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/)
7 ------------------------------------------------------------
8 The contents of this file are used with permission, subject to
9 the Mozilla Public License Version 1.1 (the "License"); you may
10 not use this file except in compliance with the License. You may
11 obtain a copy of the License at
12 http://www.mozilla.org/MPL/MPL-1.1.html
13 ------------------------------------------------------------
15 ------------------------------------------------------------
18 - The define GLB_DELPHI dosn't check versions anymore. If you say you are using delphi
19 then it's your problem if that isn't true. This prevents the unit for incompatibility
20 with newer versions of Delphi.
21 - Problems with D2009+ resolved (Thanks noeska and all i forgot)
22 - GetPixel isn't set if you are loading textures inside the constructor (Thanks Wilson)
24 - AddAlphaFromglBitmap used the custom pointer instead the imagedatapointer (Thanks Wilson)
25 - Additional Datapointer for functioninterface now has the name CustomData
27 - AssigneAlphaToBitmap overwrites his own palette (Thanks Wilson)
28 - If you load an texture from an file the property Filename will be set to the name of the file
29 - Three new properties to attach custom data to the Texture objects
30 - CustomName (free for use string)
31 - CustomNameW (free for use widestring)
32 - CustomDataPointer (free for use pointer to attach other objects or complex structures)
34 - RLE TGAs loaded much faster
36 - fixed some problem with reading RLE TGAs.
38 - function clone now only copys data if it's assigned and now it also copies the ID
39 - it seems that lazarus dont like comments in comments.
41 - It's possible to set the id of the texture
42 - define GLB_NO_NATIVE_GL deactivated by default
44 - Now supports the following libraries
48 - Linux compatibillity via free pascal compatibility (delphi sources optional)
49 - BMPs now loaded manuel
51 - Property DataPtr now has the name Data
52 - Functions are more flexible between RGB(A) and BGR(A). RGB can be saved as Bitmap and will be saved as BGR
53 - Unused Depth removed
54 - Function FreeData to freeing image data added
56 - ImageID flag of TGAs was ignored. (Thanks Zwoetzen)
58 - Function SetBorderColor implemented (only used by opengl if wrap is set to GL_CLAMP_TO_BORDER)
59 - Function AddAlphaFromValue implemented to use an fixed Value as Alphachannel
60 - Function ReadOpenGLExtension is now only intern
62 - pngimage now disabled by default like all other versions.
64 - Setting up an anisotropic filter of 0 isnt allowed by nvidia (Thanks Ogridi)
66 - Fixed some Problem with Delphi 5
67 - Now uses the newest version of pngimage. Makes saving pngs much easier.
69 - Property IsCompressed and Size removed. Not really supported by Spec (Thanks Ogridi)
71 - Internal Format ifDepth8 added
72 - function GrabScreen now supports all uncompressed formats
74 - AddAlphaFromglBitmap implemented
76 - LoadFromResource and LoadFromResourceId now needs an Instance and an ResourceType (for ID)
78 - Width, Height and Depth internal changed to TglBitmapPixelPosition.
79 property Width, Height, Depth are still existing and new property Dimension are avail
81 - Added native OpenGL Support. Breaking the dglOpenGL "barrier".
83 - Added function GrabScreen to class TglBitmap2D
85 - Added support to Save images
86 - Added function Clone to Clone Instance
88 - Functions now works with Cardinals for each channel. Up to 32 Bits per channel.
90 - Several speed optimizations
92 - Internal structure change. Loading of TGA, PNG and DDS improved.
93 Data, format and size will now set directly with SetDataPtr.
94 - AddFunc now works with all Types of Images and Formats
95 - Some Funtions moved to Baseclass TglBitmap
97 - Added Support to decompress DXT3 and DXT5 compressed Images.
98 - Added Mapping to convert data from one format into an other.
100 - Added method ConvertTo in Class TglBitmap2D. Method allows to convert every
101 supported Input format (supported by GetPixel) into any uncompresed Format
102 - Added Support to decompress DXT1 compressed Images.
103 - SwapColors replaced by ConvertTo
105 - Added Support for compressed DDSs
106 - Added new internal formats (DXT1, DXT3, DXT5)
108 - Parameter Components renamed to InternalFormat
110 - Some AllocMem replaced with GetMem (little speed change)
111 - better exception handling. Better protection from memory leaks.
113 - Added support for Direct Draw Surfaces (.DDS) (uncompressed images only)
114 - Added new internal formats (RGB8, RGBA8, RGBA4, RGB5A1, RGB10A2, R5G6B5)
116 - Added support for Grayscale textures
117 - Added internal formats (Alpha, Luminance, LuminanceAlpha, BGR8, BGRA8)
119 - Added support for GL_VERSION_2_0
120 - Added support for GL_EXT_texture_filter_anisotropic
122 - Function FillWithColor fills the Image with one Color
123 - Function LoadNormalMap added
125 - ToNormalMap allows to Create an NormalMap from the Alphachannel
126 - ToNormalMap now supports Sobel (nmSobel) function.
128 - support for RLE Compressed RGB TGAs added
130 - Class TglBitmapNormalMap added to support Normalmap generation
131 - Added function ToNormalMap in class TglBitmap2D to genereate normal maps from textures.
132 3 Filters are supported. (4 Samples, 3x3 and 5x5)
134 - Method LoadCubeMapClass removed
135 - LoadCubeMap returnvalue is now the Texture paramter. Such as LoadTextures
136 - virtual abstract method GenTexture in class TglBitmap now is protected
138 - now support DescriptionFlag in LoadTga. Allows vertical flipped images to be loaded as normal
140 - little enhancement for IsPowerOfTwo
141 - TglBitmap1D.GenTexture now tests NPOT Textures
143 - some little name changes. All properties or function with Texture in name are
144 now without texture in name. We have allways texture so we dosn't name it.
146 - GenTexture now tests if texture is NPOT and NPOT-Texture are supported or
147 TextureTarget is GL_TEXTURE_RECTANGLE. Else it raised an exception.
149 - added support for GL_ARB_texture_rectangle, GL_EXT_texture_rectangle and GL_NV_texture_rectangle
151 - Function Unbind added
152 - call of SetFilter or SetTextureWrap if TextureID exists results in setting properties to opengl texture.
154 - class TglBitmapCubeMap added (allows to Create Cubemaps)
156 - Added Support for PNG Images. (http://pngdelphi.sourceforge.net/)
157 To Enable png's use the define pngimage
159 - New Functioninterface added
160 - Function GetPixel added
162 - Property BuildMipMaps renamed to MipMap
164 - property Name removed.
165 - BuildMipMaps is now a set of 3 values. None, GluBuildMipmaps and SGIS_generate_mipmap
167 - property name added. Only used in glForms!
169 - property FreeDataAfterGenTexture is now available as default (default = true)
170 - BuildMipmaps now implemented in TglBitmap1D (i've forgotten it)
171 - function MoveMemory replaced with function Move (little speed change)
172 - several calculations stored in variables (little speed change)
174 - property BuildMipsMaps added (default = true)
175 if BuildMipMaps isn't set GenTextures uses glTexImage[12]D else it use gluBuild[12]dMipmaps
176 - property FreeDataAfterGenTexture added (default = true)
177 if FreeDataAfterGenTexture is set the texturedata were deleted after the texture was generated.
178 - parameter DisableOtherTextureUnits of Bind removed
179 - parameter FreeDataAfterGeneration of GenTextures removed
181 - TglBitmap dosn't delete data if class was destroyed (fixed)
183 - Bind now enables TextureUnits (by params)
184 - GenTextures can leave data (by param)
185 - LoadTextures now optimal
187 - Performance optimization in AddFunc
188 - procedure Bind moved to subclasses
189 - Added new Class TglBitmap1D to support real OpenGL 1D Textures
191 - Texturefilter and texturewrap now also as defaults
192 Minfilter = GL_LINEAR_MIPMAP_LINEAR
193 Magfilter = GL_LINEAR
194 Wrap(str) = GL_CLAMP_TO_EDGE
195 - Added new format tfCompressed to create a compressed texture.
196 - propertys IsCompressed, TextureSize and IsResident added
197 IsCompressed and TextureSize only contains data from level 0
199 - Added function AddFunc to add PerPixelEffects to Image
200 - LoadFromFunc now based on AddFunc
201 - Invert now based on AddFunc
202 - SwapColors now based on AddFunc
204 - Added function FlipHorz
206 - Added function LaodFromFunc to create images with function
207 - Added function FlipVert
208 - Added internal format RGB(A) if GL_EXT_bgra or OpenGL 1.2 isn't supported
210 - Added Alphafunctions to calculate alpha per function
211 - Added Alpha from ColorKey using alphafunctions
213 - First full functionally Version of glBitmap
214 - Support for 24Bit and 32Bit TGA Pictures added
216 - begin of programming
217 ***********************************************************}
220 // Please uncomment the defines below to configure the glBitmap to your preferences.
221 // If you have configured the unit you can uncomment the warning above.
222 {$MESSAGE warn 'Hey. I''m the glBitmap.pas and i need to be configured. My master tell me your preferences! ;)'}
224 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
225 // Preferences ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
226 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
227 // activate to enable build-in OpenGL support with statically linked methods
228 // use dglOpenGL.pas if not enabled
229 {.$DEFINE GLB_NATIVE_OGL_STATIC}
231 // activate to enable build-in OpenGL support with dynamically linked methods
232 // use dglOpenGL.pas if not enabled
233 {.$DEFINE GLB_NATIVE_OGL_DYNAMIC}
236 // activate to enable the support for SDL_surfaces
239 // activate to enable the support for TBitmap from Delphi (not lazarus)
240 {.$DEFINE GLB_DELPHI}
242 // activate to enable the support for TLazIntfImage from Lazarus
243 {$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(var aData: PByte; const aFormat: TglBitmapFormat;
850 const aWidth: Integer = -1; const aHeight: Integer = -1); virtual; //be careful, aData could be freed by this method
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 TglBitmap1D = class(TglBitmap)
998 procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
999 const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
1000 procedure UploadData(const aBuildWithGlu: Boolean);
1003 procedure AfterConstruction; override;
1004 function FlipHorz: Boolean; override;
1005 procedure GenTexture(const aTestTextureSize: Boolean = true); override;
1008 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1009 TglBitmap2D = class(TglBitmap)
1011 // Bildeinstellungen
1012 fLines: array of PByte;
1014 function GetScanline(const aIndex: Integer): Pointer;
1015 procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
1016 const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
1017 procedure UploadData(const aBuildWithGlu: Boolean);
1021 property Scanline[const aIndex: Integer]: Pointer read GetScanline;
1023 procedure AfterConstruction; override;
1025 procedure GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
1026 procedure GetDataFromTexture;
1027 procedure GenTexture(const aTestTextureSize: Boolean = true); override;
1029 function FlipHorz: Boolean; override;
1030 function FlipVert: Boolean; override;
1032 procedure ToNormalMap(const aFunc: TglBitmapNormalMapFunc = nm3x3;
1033 const aScale: Single = 2; const aUseAlpha: Boolean = false);
1037 TglBitmapCubeMap = class(TglBitmap2D)
1042 procedure GenTexture(TestTextureSize: Boolean = true); reintroduce;
1044 procedure AfterConstruction; override;
1046 procedure GenerateCubeMap(CubeTarget: Cardinal; TestTextureSize: Boolean = true);
1048 procedure Unbind(DisableTexCoordsGen: Boolean = true; DisableTextureUnit: Boolean = true); reintroduce; virtual;
1049 procedure Bind(EnableTexCoordsGen: Boolean = true; EnableTextureUnit: Boolean = true); reintroduce; virtual;
1053 TglBitmapNormalMap = class(TglBitmapCubeMap)
1055 procedure AfterConstruction; override;
1057 procedure GenerateNormalMap(Size: Integer = 32; TestTextureSize: Boolean = true);
1065 NULL_SIZE: TglBitmapPixelPosition = (Fields: []; X: 0; Y: 0);
1067 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
1068 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
1069 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
1070 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
1071 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
1072 procedure glBitmapSetDefaultWrap(
1073 const S: Cardinal = GL_CLAMP_TO_EDGE;
1074 const T: Cardinal = GL_CLAMP_TO_EDGE;
1075 const R: Cardinal = GL_CLAMP_TO_EDGE);
1077 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
1078 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
1079 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
1080 function glBitmapGetDefaultFormat: TglBitmapFormat;
1081 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
1082 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
1084 function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
1085 function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
1086 function glBitmapColorRecCmp(const r1, r2: TglBitmapColorRec): Boolean;
1089 glBitmapDefaultDeleteTextureOnFree: Boolean;
1090 glBitmapDefaultFreeDataAfterGenTextures: Boolean;
1091 glBitmapDefaultFormat: TglBitmapFormat;
1092 glBitmapDefaultMipmap: TglBitmapMipMap;
1093 glBitmapDefaultFilterMin: Cardinal;
1094 glBitmapDefaultFilterMag: Cardinal;
1095 glBitmapDefaultWrapS: Cardinal;
1096 glBitmapDefaultWrapT: Cardinal;
1097 glBitmapDefaultWrapR: Cardinal;
1100 function CreateGrayPalette: HPALETTE;
1106 Math, syncobjs, typinfo;
1110 QWord = System.UInt64;
1117 ////////////////////////////////////////////////////////////////////////////////////////////////////
1118 TShiftRec = packed record
1120 0: (r, g, b, a: Byte);
1121 1: (arr: array[0..3] of Byte);
1124 TFormatDescriptor = class(TObject)
1126 function GetRedMask: QWord;
1127 function GetGreenMask: QWord;
1128 function GetBlueMask: QWord;
1129 function GetAlphaMask: QWord;
1131 fFormat: TglBitmapFormat;
1132 fWithAlpha: TglBitmapFormat;
1133 fWithoutAlpha: TglBitmapFormat;
1134 fRGBInverted: TglBitmapFormat;
1135 fUncompressed: TglBitmapFormat;
1137 fIsCompressed: Boolean;
1139 fRange: TglBitmapColorRec;
1142 fglFormat: Cardinal;
1143 fglInternalFormat: Cardinal;
1144 fglDataFormat: Cardinal;
1146 function GetComponents: Integer; virtual;
1148 property Format: TglBitmapFormat read fFormat;
1149 property WithAlpha: TglBitmapFormat read fWithAlpha;
1150 property WithoutAlpha: TglBitmapFormat read fWithoutAlpha;
1151 property RGBInverted: TglBitmapFormat read fRGBInverted;
1152 property Components: Integer read GetComponents;
1153 property PixelSize: Single read fPixelSize;
1154 property IsCompressed: Boolean read fIsCompressed;
1156 property glFormat: Cardinal read fglFormat;
1157 property glInternalFormat: Cardinal read fglInternalFormat;
1158 property glDataFormat: Cardinal read fglDataFormat;
1160 property Range: TglBitmapColorRec read fRange;
1161 property Shift: TShiftRec read fShift;
1163 property RedMask: QWord read GetRedMask;
1164 property GreenMask: QWord read GetGreenMask;
1165 property BlueMask: QWord read GetBlueMask;
1166 property AlphaMask: QWord read GetAlphaMask;
1168 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); virtual; abstract;
1169 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract;
1171 function GetSize(const aSize: TglBitmapPixelPosition): Integer; overload; virtual;
1172 function GetSize(const aWidth, aHeight: Integer): Integer; overload; virtual;
1174 function CreateMappingData: Pointer; virtual;
1175 procedure FreeMappingData(var aMappingData: Pointer); virtual;
1177 function IsEmpty: Boolean; virtual;
1178 function HasAlpha: Boolean; virtual;
1179 function MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: QWord): Boolean; virtual;
1181 procedure PreparePixel(out aPixel: TglBitmapPixelData); virtual;
1183 constructor Create; virtual;
1185 class procedure Init;
1186 class function Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
1187 class function GetWithAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
1188 class procedure Clear;
1189 class procedure Finalize;
1191 TFormatDescriptorClass = class of TFormatDescriptor;
1193 TfdEmpty = class(TFormatDescriptor);
1195 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1196 TfdAlpha_UB1 = class(TFormatDescriptor) //1* unsigned byte
1197 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1198 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1199 constructor Create; override;
1202 TfdLuminance_UB1 = class(TFormatDescriptor) //1* unsigned byte
1203 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1204 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1205 constructor Create; override;
1208 TfdUniversal_UB1 = class(TFormatDescriptor) //1* unsigned byte
1209 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1210 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1211 constructor Create; override;
1214 TfdLuminanceAlpha_UB2 = class(TfdLuminance_UB1) //2* unsigned byte
1215 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1216 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1217 constructor Create; override;
1220 TfdRGB_UB3 = class(TFormatDescriptor) //3* unsigned byte
1221 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1222 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1223 constructor Create; override;
1226 TfdBGR_UB3 = class(TFormatDescriptor) //3* unsigned byte (inverse)
1227 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1228 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1229 constructor Create; override;
1232 TfdRGBA_UB4 = class(TfdRGB_UB3) //4* unsigned byte
1233 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1234 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1235 constructor Create; override;
1238 TfdBGRA_UB4 = class(TfdBGR_UB3) //4* unsigned byte (inverse)
1239 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1240 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1241 constructor Create; override;
1244 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1245 TfdAlpha_US1 = class(TFormatDescriptor) //1* unsigned short
1246 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1247 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1248 constructor Create; override;
1251 TfdLuminance_US1 = class(TFormatDescriptor) //1* unsigned short
1252 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1253 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1254 constructor Create; override;
1257 TfdUniversal_US1 = class(TFormatDescriptor) //1* unsigned short
1258 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1259 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1260 constructor Create; override;
1263 TfdDepth_US1 = class(TFormatDescriptor) //1* unsigned short
1264 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1265 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1266 constructor Create; override;
1269 TfdLuminanceAlpha_US2 = class(TfdLuminance_US1) //2* unsigned short
1270 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1271 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1272 constructor Create; override;
1275 TfdRGB_US3 = class(TFormatDescriptor) //3* unsigned short
1276 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1277 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1278 constructor Create; override;
1281 TfdBGR_US3 = class(TFormatDescriptor) //3* unsigned short (inverse)
1282 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1283 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1284 constructor Create; override;
1287 TfdRGBA_US4 = class(TfdRGB_US3) //4* unsigned short
1288 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1289 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1290 constructor Create; override;
1293 TfdBGRA_US4 = class(TfdBGR_US3) //4* unsigned short (inverse)
1294 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1295 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1296 constructor Create; override;
1299 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1300 TfdUniversal_UI1 = class(TFormatDescriptor) //1* unsigned int
1301 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1302 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1303 constructor Create; override;
1306 TfdDepth_UI1 = class(TFormatDescriptor) //1* unsigned int
1307 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1308 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1309 constructor Create; override;
1312 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1313 TfdAlpha4 = class(TfdAlpha_UB1)
1314 constructor Create; override;
1317 TfdAlpha8 = class(TfdAlpha_UB1)
1318 constructor Create; override;
1321 TfdAlpha12 = class(TfdAlpha_US1)
1322 constructor Create; override;
1325 TfdAlpha16 = class(TfdAlpha_US1)
1326 constructor Create; override;
1329 TfdLuminance4 = class(TfdLuminance_UB1)
1330 constructor Create; override;
1333 TfdLuminance8 = class(TfdLuminance_UB1)
1334 constructor Create; override;
1337 TfdLuminance12 = class(TfdLuminance_US1)
1338 constructor Create; override;
1341 TfdLuminance16 = class(TfdLuminance_US1)
1342 constructor Create; override;
1345 TfdLuminance4Alpha4 = class(TfdLuminanceAlpha_UB2)
1346 constructor Create; override;
1349 TfdLuminance6Alpha2 = class(TfdLuminanceAlpha_UB2)
1350 constructor Create; override;
1353 TfdLuminance8Alpha8 = class(TfdLuminanceAlpha_UB2)
1354 constructor Create; override;
1357 TfdLuminance12Alpha4 = class(TfdLuminanceAlpha_US2)
1358 constructor Create; override;
1361 TfdLuminance12Alpha12 = class(TfdLuminanceAlpha_US2)
1362 constructor Create; override;
1365 TfdLuminance16Alpha16 = class(TfdLuminanceAlpha_US2)
1366 constructor Create; override;
1369 TfdR3G3B2 = class(TfdUniversal_UB1)
1370 constructor Create; override;
1373 TfdRGB4 = class(TfdUniversal_US1)
1374 constructor Create; override;
1377 TfdR5G6B5 = class(TfdUniversal_US1)
1378 constructor Create; override;
1381 TfdRGB5 = class(TfdUniversal_US1)
1382 constructor Create; override;
1385 TfdRGB8 = class(TfdRGB_UB3)
1386 constructor Create; override;
1389 TfdRGB10 = class(TfdUniversal_UI1)
1390 constructor Create; override;
1393 TfdRGB12 = class(TfdRGB_US3)
1394 constructor Create; override;
1397 TfdRGB16 = class(TfdRGB_US3)
1398 constructor Create; override;
1401 TfdRGBA2 = class(TfdRGBA_UB4)
1402 constructor Create; override;
1405 TfdRGBA4 = class(TfdUniversal_US1)
1406 constructor Create; override;
1409 TfdRGB5A1 = class(TfdUniversal_US1)
1410 constructor Create; override;
1413 TfdRGBA8 = class(TfdRGBA_UB4)
1414 constructor Create; override;
1417 TfdRGB10A2 = class(TfdUniversal_UI1)
1418 constructor Create; override;
1421 TfdRGBA12 = class(TfdRGBA_US4)
1422 constructor Create; override;
1425 TfdRGBA16 = class(TfdRGBA_US4)
1426 constructor Create; override;
1429 TfdBGR4 = class(TfdUniversal_US1)
1430 constructor Create; override;
1433 TfdB5G6R5 = class(TfdUniversal_US1)
1434 constructor Create; override;
1437 TfdBGR5 = class(TfdUniversal_US1)
1438 constructor Create; override;
1441 TfdBGR8 = class(TfdBGR_UB3)
1442 constructor Create; override;
1445 TfdBGR10 = class(TfdUniversal_UI1)
1446 constructor Create; override;
1449 TfdBGR12 = class(TfdBGR_US3)
1450 constructor Create; override;
1453 TfdBGR16 = class(TfdBGR_US3)
1454 constructor Create; override;
1457 TfdBGRA2 = class(TfdBGRA_UB4)
1458 constructor Create; override;
1461 TfdBGRA4 = class(TfdUniversal_US1)
1462 constructor Create; override;
1465 TfdBGR5A1 = class(TfdUniversal_US1)
1466 constructor Create; override;
1469 TfdBGRA8 = class(TfdBGRA_UB4)
1470 constructor Create; override;
1473 TfdBGR10A2 = class(TfdUniversal_UI1)
1474 constructor Create; override;
1477 TfdBGRA12 = class(TfdBGRA_US4)
1478 constructor Create; override;
1481 TfdBGRA16 = class(TfdBGRA_US4)
1482 constructor Create; override;
1485 TfdDepth16 = class(TfdDepth_US1)
1486 constructor Create; override;
1489 TfdDepth24 = class(TfdDepth_UI1)
1490 constructor Create; override;
1493 TfdDepth32 = class(TfdDepth_UI1)
1494 constructor Create; override;
1497 TfdS3tcDtx1RGBA = class(TFormatDescriptor)
1498 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1499 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1500 constructor Create; override;
1503 TfdS3tcDtx3RGBA = class(TFormatDescriptor)
1504 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1505 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1506 constructor Create; override;
1509 TfdS3tcDtx5RGBA = class(TFormatDescriptor)
1510 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1511 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1512 constructor Create; override;
1515 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1516 TbmpBitfieldFormat = class(TFormatDescriptor)
1518 procedure SetRedMask (const aValue: QWord);
1519 procedure SetGreenMask(const aValue: QWord);
1520 procedure SetBlueMask (const aValue: QWord);
1521 procedure SetAlphaMask(const aValue: QWord);
1523 procedure Update(aMask: QWord; out aRange: Cardinal; out aShift: Byte);
1525 property RedMask: QWord read GetRedMask write SetRedMask;
1526 property GreenMask: QWord read GetGreenMask write SetGreenMask;
1527 property BlueMask: QWord read GetBlueMask write SetBlueMask;
1528 property AlphaMask: QWord read GetAlphaMask write SetAlphaMask;
1530 property PixelSize: Single read fPixelSize write fPixelSize;
1532 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1533 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1536 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1537 TbmpColorTableEnty = packed record
1540 TbmpColorTable = array of TbmpColorTableEnty;
1541 TbmpColorTableFormat = class(TFormatDescriptor)
1543 fColorTable: TbmpColorTable;
1545 property PixelSize: Single read fPixelSize write fPixelSize;
1546 property ColorTable: TbmpColorTable read fColorTable write fColorTable;
1547 property Range: TglBitmapColorRec read fRange write fRange;
1548 property Shift: TShiftRec read fShift write fShift;
1549 property Format: TglBitmapFormat read fFormat write fFormat;
1551 procedure CreateColorTable;
1553 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1554 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1555 destructor Destroy; override;
1559 LUMINANCE_WEIGHT_R = 0.30;
1560 LUMINANCE_WEIGHT_G = 0.59;
1561 LUMINANCE_WEIGHT_B = 0.11;
1563 ALPHA_WEIGHT_R = 0.30;
1564 ALPHA_WEIGHT_G = 0.59;
1565 ALPHA_WEIGHT_B = 0.11;
1567 DEPTH_WEIGHT_R = 0.333333333;
1568 DEPTH_WEIGHT_G = 0.333333333;
1569 DEPTH_WEIGHT_B = 0.333333333;
1571 UNSUPPORTED_FORMAT = 'the given format isn''t supported by this function.';
1573 FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
1586 TfdLuminance4Alpha4,
1587 TfdLuminance6Alpha2,
1588 TfdLuminance8Alpha8,
1589 TfdLuminance12Alpha4,
1590 TfdLuminance12Alpha12,
1591 TfdLuminance16Alpha16,
1636 FormatDescriptorCS: TCriticalSection;
1637 FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
1639 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1640 constructor EglBitmapUnsupportedFormat.Create(const aFormat: TglBitmapFormat);
1642 inherited Create('unsupported format: ' + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1645 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1646 constructor EglBitmapUnsupportedFormat.Create(const aMsg: String; const aFormat: TglBitmapFormat);
1648 inherited Create(aMsg + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1651 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1652 function glBitmapPosition(X, Y: Integer): TglBitmapPixelPosition;
1654 result.Fields := [];
1657 result.Fields := result.Fields + [ffX];
1659 result.Fields := result.Fields + [ffY];
1661 result.X := Max(0, X);
1662 result.Y := Max(0, Y);
1665 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1666 function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
1674 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1675 function glBitmapColorRecCmp(const r1, r2: TglBitmapColorRec): Boolean;
1680 for i := 0 to high(r1.arr) do
1681 if (r1.arr[i] <> r2.arr[i]) then
1686 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1687 function glBitmapShiftRec(const r, g, b, a: Byte): TShiftRec;
1695 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1696 function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
1705 tfR3G3B2, tfLuminance8,
1708 tfRGB4, tfRGB5, tfR5G6B5, tfRGB5A1, tfRGBA4,
1709 tfBGR4, tfBGR5, tfB5G6R5, tfBGR5A1, tfBGRA4,
1715 tfRGB10, tfRGB10A2, tfRGBA8,
1716 tfBGR10, tfBGR10A2, tfBGRA8]) then
1717 result := result + [ftBMP];
1721 tfLuminance8, tfAlpha8,
1724 tfLuminance16, tfLuminance8Alpha8,
1725 tfRGB5, tfRGB5A1, tfRGBA4,
1726 tfBGR5, tfBGR5A1, tfBGRA4,
1732 tfRGB10A2, tfRGBA8, tfBGR10A2, tfBGRA8]) then
1733 result := result + [ftTGA];
1737 tfAlpha8, tfLuminance8, tfLuminance4Alpha4, tfLuminance6Alpha2,
1738 tfR3G3B2, tfRGBA2, tfBGRA2,
1741 tfAlpha16, tfLuminance16, tfLuminance8Alpha8, tfLuminance12Alpha4,
1742 tfRGB4, tfR5G6B5, tfRGB5, tfRGBA4, tfRGB5A1,
1743 tfBGR4, tfB5G6R5, tfBGR5, tfBGRA4, tfBGR5A1,
1749 tfLuminance16Alpha16,
1754 tfS3tcDtx1RGBA, tfS3tcDtx3RGBA, tfS3tcDtx5RGBA]) then
1755 result := result + [ftDDS];
1757 {$IFDEF GLB_SUPPORT_PNG_WRITE}
1759 tfAlpha8, tfLuminance8, tfLuminance8Alpha8,
1761 tfBGR8, tfBGRA8] then
1762 result := result + [ftPNG];
1765 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
1766 if aFormat in [tfAlpha8, tfLuminance8, tfRGB8, tfBGR8] then
1767 result := result + [ftJPEG];
1771 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1772 function IsPowerOfTwo(aNumber: Integer): Boolean;
1774 while (aNumber and 1) = 0 do
1775 aNumber := aNumber shr 1;
1776 result := aNumber = 1;
1779 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1780 function GetTopMostBit(aBitSet: QWord): Integer;
1783 while aBitSet > 0 do begin
1785 aBitSet := aBitSet shr 1;
1789 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1790 function CountSetBits(aBitSet: QWord): Integer;
1793 while aBitSet > 0 do begin
1794 if (aBitSet and 1) = 1 then
1796 aBitSet := aBitSet shr 1;
1800 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1801 function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
1804 LUMINANCE_WEIGHT_R * aPixel.Data.r +
1805 LUMINANCE_WEIGHT_G * aPixel.Data.g +
1806 LUMINANCE_WEIGHT_B * aPixel.Data.b);
1809 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1810 function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
1813 DEPTH_WEIGHT_R * aPixel.Data.r +
1814 DEPTH_WEIGHT_G * aPixel.Data.g +
1815 DEPTH_WEIGHT_B * aPixel.Data.b);
1818 {$IFDEF GLB_NATIVE_OGL}
1819 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1820 //OpenGLInitialization///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1821 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1823 GL_LibHandle: Pointer = nil;
1825 function glbGetProcAddress(aProcName: PChar; aLibHandle: Pointer = nil): Pointer;
1827 if not Assigned(aLibHandle) then
1828 aLibHandle := GL_LibHandle;
1830 {$IF DEFINED(GLB_WIN)}
1831 result := GetProcAddress({%H-}HMODULE(aLibHandle), aProcName);
1832 if Assigned(result) then
1835 if Assigned(wglGetProcAddress) then
1836 result := wglGetProcAddress(aProcName);
1837 {$ELSEIF DEFINED(GLB_LINUX)}
1838 if Assigned(glXGetProcAddress) then begin
1839 result := glXGetProcAddress(aProcName);
1840 if Assigned(result) then
1844 if Assigned(glXGetProcAddressARB) then begin
1845 result := glXGetProcAddressARB(aProcName);
1846 if Assigned(result) then
1850 result := dlsym(aLibHandle, aProcName);
1852 if not Assigned(result) then
1853 raise EglBitmapException.Create('unable to load procedure form library: ' + aProcName);
1856 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
1858 GLU_LibHandle: Pointer = nil;
1859 OpenGLInitialized: Boolean;
1860 InitOpenGLCS: TCriticalSection;
1862 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1863 procedure glbInitOpenGL;
1865 ////////////////////////////////////////////////////////////////////////////////
1866 function glbLoadLibrary(const aName: PChar): Pointer;
1868 {$IF DEFINED(GLB_WIN)}
1869 result := {%H-}Pointer(LoadLibrary(aName));
1870 {$ELSEIF DEFINED(GLB_LINUX)}
1871 result := dlopen(Name, RTLD_LAZY);
1877 ////////////////////////////////////////////////////////////////////////////////
1878 function glbFreeLibrary(const aLibHandle: Pointer): Boolean;
1881 if not Assigned(aLibHandle) then
1884 {$IF DEFINED(GLB_WIN)}
1885 Result := FreeLibrary({%H-}HINST(aLibHandle));
1886 {$ELSEIF DEFINED(GLB_LINUX)}
1887 Result := dlclose(aLibHandle) = 0;
1892 if Assigned(GL_LibHandle) then
1893 glbFreeLibrary(GL_LibHandle);
1895 if Assigned(GLU_LibHandle) then
1896 glbFreeLibrary(GLU_LibHandle);
1898 GL_LibHandle := glbLoadLibrary(libopengl);
1899 if not Assigned(GL_LibHandle) then
1900 raise EglBitmapException.Create('unable to load library: ' + libopengl);
1902 GLU_LibHandle := glbLoadLibrary(libglu);
1903 if not Assigned(GLU_LibHandle) then
1904 raise EglBitmapException.Create('unable to load library: ' + libglu);
1907 {$IF DEFINED(GLB_WIN)}
1908 wglGetProcAddress := glbGetProcAddress('wglGetProcAddress');
1909 {$ELSEIF DEFINED(GLB_LINUX)}
1910 glXGetProcAddress := glbGetProcAddress('glXGetProcAddress');
1911 glXGetProcAddressARB := glbGetProcAddress('glXGetProcAddressARB');
1914 glEnable := glbGetProcAddress('glEnable');
1915 glDisable := glbGetProcAddress('glDisable');
1916 glGetString := glbGetProcAddress('glGetString');
1917 glGetIntegerv := glbGetProcAddress('glGetIntegerv');
1918 glTexParameteri := glbGetProcAddress('glTexParameteri');
1919 glTexParameterfv := glbGetProcAddress('glTexParameterfv');
1920 glGetTexParameteriv := glbGetProcAddress('glGetTexParameteriv');
1921 glGetTexParameterfv := glbGetProcAddress('glGetTexParameterfv');
1922 glGetTexLevelParameteriv := glbGetProcAddress('glGetTexLevelParameteriv');
1923 glGetTexLevelParameterfv := glbGetProcAddress('glGetTexLevelParameterfv');
1924 glGenTextures := glbGetProcAddress('glGenTextures');
1925 glBindTexture := glbGetProcAddress('glBindTexture');
1926 glDeleteTextures := glbGetProcAddress('glDeleteTextures');
1927 glAreTexturesResident := glbGetProcAddress('glAreTexturesResident');
1928 glReadPixels := glbGetProcAddress('glReadPixels');
1929 glPixelStorei := glbGetProcAddress('glPixelStorei');
1930 glTexImage1D := glbGetProcAddress('glTexImage1D');
1931 glTexImage2D := glbGetProcAddress('glTexImage2D');
1932 glGetTexImage := glbGetProcAddress('glGetTexImage');
1934 gluBuild1DMipmaps := glbGetProcAddress('gluBuild1DMipmaps', GLU_LibHandle);
1935 gluBuild2DMipmaps := glbGetProcAddress('gluBuild2DMipmaps', GLU_LibHandle);
1937 glbFreeLibrary(GL_LibHandle);
1938 glbFreeLibrary(GLU_LibHandle);
1943 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1944 procedure glbReadOpenGLExtensions;
1947 MajorVersion, MinorVersion: Integer;
1949 ///////////////////////////////////////////////////////////////////////////////////////////
1950 procedure TrimVersionString(aBuffer: AnsiString; out aMajor, aMinor: Integer);
1957 Separator := Pos(AnsiString('.'), aBuffer);
1958 if (Separator > 1) and (Separator < Length(aBuffer)) and
1959 (aBuffer[Separator - 1] in ['0'..'9']) and
1960 (aBuffer[Separator + 1] in ['0'..'9']) then begin
1963 while (Separator > 0) and (aBuffer[Separator] in ['0'..'9']) do
1966 Delete(aBuffer, 1, Separator);
1967 Separator := Pos(AnsiString('.'), aBuffer) + 1;
1969 while (Separator <= Length(aBuffer)) and (AnsiChar(aBuffer[Separator]) in ['0'..'9']) do
1972 Delete(aBuffer, Separator, 255);
1973 Separator := Pos(AnsiString('.'), aBuffer);
1975 aMajor := StrToInt(Copy(String(aBuffer), 1, Separator - 1));
1976 aMinor := StrToInt(Copy(String(aBuffer), Separator + 1, 1));
1980 ///////////////////////////////////////////////////////////////////////////////////////////
1981 function CheckExtension(const Extension: AnsiString): Boolean;
1985 ExtPos := Pos(Extension, Buffer);
1986 result := ExtPos > 0;
1988 result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
1992 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
1995 if not OpenGLInitialized then begin
1997 OpenGLInitialized := true;
2005 Buffer := glGetString(GL_VERSION);
2006 TrimVersionString(Buffer, MajorVersion, MinorVersion);
2008 GL_VERSION_1_2 := false;
2009 GL_VERSION_1_3 := false;
2010 GL_VERSION_1_4 := false;
2011 GL_VERSION_2_0 := false;
2012 if MajorVersion = 1 then begin
2013 if MinorVersion >= 2 then
2014 GL_VERSION_1_2 := true;
2016 if MinorVersion >= 3 then
2017 GL_VERSION_1_3 := true;
2019 if MinorVersion >= 4 then
2020 GL_VERSION_1_4 := true;
2021 end else if MajorVersion >= 2 then begin
2022 GL_VERSION_1_2 := true;
2023 GL_VERSION_1_3 := true;
2024 GL_VERSION_1_4 := true;
2025 GL_VERSION_2_0 := true;
2029 Buffer := glGetString(GL_EXTENSIONS);
2030 GL_ARB_texture_border_clamp := CheckExtension('GL_ARB_texture_border_clamp');
2031 GL_ARB_texture_non_power_of_two := CheckExtension('GL_ARB_texture_non_power_of_two');
2032 GL_ARB_texture_rectangle := CheckExtension('GL_ARB_texture_rectangle');
2033 GL_ARB_texture_mirrored_repeat := CheckExtension('GL_ARB_texture_mirrored_repeat');
2034 GL_EXT_texture_edge_clamp := CheckExtension('GL_EXT_texture_edge_clamp');
2035 GL_EXT_texture_filter_anisotropic := CheckExtension('GL_EXT_texture_filter_anisotropic');
2036 GL_EXT_texture_rectangle := CheckExtension('GL_EXT_texture_rectangle');
2037 GL_NV_texture_rectangle := CheckExtension('GL_NV_texture_rectangle');
2038 GL_IBM_texture_mirrored_repeat := CheckExtension('GL_IBM_texture_mirrored_repeat');
2039 GL_SGIS_generate_mipmap := CheckExtension('GL_SGIS_generate_mipmap');
2041 if GL_VERSION_1_3 then begin
2042 glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1D');
2043 glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2D');
2044 glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImage');
2046 glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1DARB');
2047 glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2DARB');
2048 glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImageARB');
2053 {$IFDEF GLB_SDL_IMAGE}
2054 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2055 // SDL Image Helper /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2056 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2057 function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
2059 result := TStream(context^.unknown.data1).Seek(offset, whence);
2062 function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
2064 result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
2067 function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
2069 result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
2072 function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
2077 function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
2079 result := SDL_AllocRW;
2081 if result = nil then
2082 raise EglBitmapException.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
2084 result^.seek := glBitmapRWseek;
2085 result^.read := glBitmapRWread;
2086 result^.write := glBitmapRWwrite;
2087 result^.close := glBitmapRWclose;
2088 result^.unknown.data1 := Stream;
2092 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2093 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
2095 glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
2098 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2099 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
2101 glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
2104 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2105 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
2107 glBitmapDefaultMipmap := aValue;
2110 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2111 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
2113 glBitmapDefaultFormat := aFormat;
2116 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2117 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
2119 glBitmapDefaultFilterMin := aMin;
2120 glBitmapDefaultFilterMag := aMag;
2123 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2124 procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
2126 glBitmapDefaultWrapS := S;
2127 glBitmapDefaultWrapT := T;
2128 glBitmapDefaultWrapR := R;
2131 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2132 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
2134 result := glBitmapDefaultDeleteTextureOnFree;
2137 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2138 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
2140 result := glBitmapDefaultFreeDataAfterGenTextures;
2143 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2144 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
2146 result := glBitmapDefaultMipmap;
2149 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2150 function glBitmapGetDefaultFormat: TglBitmapFormat;
2152 result := glBitmapDefaultFormat;
2155 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2156 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
2158 aMin := glBitmapDefaultFilterMin;
2159 aMag := glBitmapDefaultFilterMag;
2162 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2163 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
2165 S := glBitmapDefaultWrapS;
2166 T := glBitmapDefaultWrapT;
2167 R := glBitmapDefaultWrapR;
2170 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2171 //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2172 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2173 function TFormatDescriptor.GetRedMask: QWord;
2175 result := fRange.r shl fShift.r;
2178 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2179 function TFormatDescriptor.GetGreenMask: QWord;
2181 result := fRange.g shl fShift.g;
2184 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2185 function TFormatDescriptor.GetBlueMask: QWord;
2187 result := fRange.b shl fShift.b;
2190 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2191 function TFormatDescriptor.GetAlphaMask: QWord;
2193 result := fRange.a shl fShift.a;
2196 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2197 function TFormatDescriptor.GetComponents: Integer;
2203 if (fRange.arr[i] > 0) then
2207 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2208 function TFormatDescriptor.GetSize(const aSize: TglBitmapPixelPosition): Integer;
2212 if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
2213 w := Max(1, aSize.X);
2214 h := Max(1, aSize.Y);
2215 result := GetSize(w, h);
2220 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2221 function TFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer;
2224 if (aWidth <= 0) or (aHeight <= 0) then
2226 result := Ceil(aWidth * aHeight * fPixelSize);
2229 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2230 function TFormatDescriptor.CreateMappingData: Pointer;
2235 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2236 procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
2241 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2242 function TFormatDescriptor.IsEmpty: Boolean;
2244 result := (fFormat = tfEmpty);
2247 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2248 function TFormatDescriptor.HasAlpha: Boolean;
2250 result := (fRange.a > 0);
2253 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2254 function TFormatDescriptor.MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: QWord): Boolean;
2257 if (aRedMask = 0) and (aGreenMask = 0) and (aBlueMask = 0) and (aAlphaMask = 0) then
2258 raise EglBitmapException.Create('FormatCheckFormat - All Masks are 0');
2259 if (aRedMask <> RedMask) then
2261 if (aGreenMask <> GreenMask) then
2263 if (aBlueMask <> BlueMask) then
2265 if (aAlphaMask <> AlphaMask) then
2270 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2271 procedure TFormatDescriptor.PreparePixel(out aPixel: TglBitmapPixelData);
2273 FillChar(aPixel{%H-}, SizeOf(aPixel), 0);
2274 aPixel.Data := fRange;
2275 aPixel.Range := fRange;
2276 aPixel.Format := fFormat;
2279 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2280 constructor TFormatDescriptor.Create;
2285 fWithAlpha := tfEmpty;
2286 fWithoutAlpha := tfEmpty;
2287 fRGBInverted := tfEmpty;
2288 fUncompressed := tfEmpty;
2290 fIsCompressed := false;
2293 fglInternalFormat := 0;
2296 FillChar(fRange, 0, SizeOf(fRange));
2297 FillChar(fShift, 0, SizeOf(fShift));
2300 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2301 //TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2302 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2303 procedure TfdAlpha_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2305 aData^ := aPixel.Data.a;
2309 procedure TfdAlpha_UB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2314 aPixel.Data.a := aData^;
2318 constructor TfdAlpha_UB1.Create;
2323 fglFormat := GL_ALPHA;
2324 fglDataFormat := GL_UNSIGNED_BYTE;
2327 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2328 //TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2329 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2330 procedure TfdLuminance_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2332 aData^ := LuminanceWeight(aPixel);
2336 procedure TfdLuminance_UB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2338 aPixel.Data.r := aData^;
2339 aPixel.Data.g := aData^;
2340 aPixel.Data.b := aData^;
2345 constructor TfdLuminance_UB1.Create;
2352 fglFormat := GL_LUMINANCE;
2353 fglDataFormat := GL_UNSIGNED_BYTE;
2356 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2357 //TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2358 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2359 procedure TfdUniversal_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2365 if (fRange.arr[i] > 0) then
2366 aData^ := aData^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2370 procedure TfdUniversal_UB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2375 aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and fRange.arr[i];
2379 constructor TfdUniversal_UB1.Create;
2385 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2386 //TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2387 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2388 procedure TfdLuminanceAlpha_UB2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2390 inherited Map(aPixel, aData, aMapData);
2391 aData^ := aPixel.Data.a;
2395 procedure TfdLuminanceAlpha_UB2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2397 inherited Unmap(aData, aPixel, aMapData);
2398 aPixel.Data.a := aData^;
2402 constructor TfdLuminanceAlpha_UB2.Create;
2408 fglFormat := GL_LUMINANCE_ALPHA;
2409 fglDataFormat := GL_UNSIGNED_BYTE;
2412 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2413 //TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2414 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2415 procedure TfdRGB_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2417 aData^ := aPixel.Data.r;
2419 aData^ := aPixel.Data.g;
2421 aData^ := aPixel.Data.b;
2425 procedure TfdRGB_UB3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2427 aPixel.Data.r := aData^;
2429 aPixel.Data.g := aData^;
2431 aPixel.Data.b := aData^;
2436 constructor TfdRGB_UB3.Create;
2446 fglFormat := GL_RGB;
2447 fglDataFormat := GL_UNSIGNED_BYTE;
2450 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2451 //TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2452 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2453 procedure TfdBGR_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2455 aData^ := aPixel.Data.b;
2457 aData^ := aPixel.Data.g;
2459 aData^ := aPixel.Data.r;
2463 procedure TfdBGR_UB3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2465 aPixel.Data.b := aData^;
2467 aPixel.Data.g := aData^;
2469 aPixel.Data.r := aData^;
2474 constructor TfdBGR_UB3.Create;
2483 fglFormat := GL_BGR;
2484 fglDataFormat := GL_UNSIGNED_BYTE;
2487 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2488 //TdfRGBA_UB4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2489 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2490 procedure TfdRGBA_UB4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2492 inherited Map(aPixel, aData, aMapData);
2493 aData^ := aPixel.Data.a;
2497 procedure TfdRGBA_UB4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2499 inherited Unmap(aData, aPixel, aMapData);
2500 aPixel.Data.a := aData^;
2504 constructor TfdRGBA_UB4.Create;
2510 fglFormat := GL_RGBA;
2511 fglDataFormat := GL_UNSIGNED_BYTE;
2514 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2515 //TfdBGRA_UB4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2516 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2517 procedure TfdBGRA_UB4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2519 inherited Map(aPixel, aData, aMapData);
2520 aData^ := aPixel.Data.a;
2524 procedure TfdBGRA_UB4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2526 inherited Unmap(aData, aPixel, aMapData);
2527 aPixel.Data.a := aData^;
2531 constructor TfdBGRA_UB4.Create;
2537 fglFormat := GL_BGRA;
2538 fglDataFormat := GL_UNSIGNED_BYTE;
2541 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2542 //TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2543 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2544 procedure TfdAlpha_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2546 PWord(aData)^ := aPixel.Data.a;
2550 procedure TfdAlpha_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2555 aPixel.Data.a := PWord(aData)^;
2559 constructor TfdAlpha_US1.Create;
2564 fglFormat := GL_ALPHA;
2565 fglDataFormat := GL_UNSIGNED_SHORT;
2568 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2569 //TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2570 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2571 procedure TfdLuminance_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2573 PWord(aData)^ := LuminanceWeight(aPixel);
2577 procedure TfdLuminance_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2579 aPixel.Data.r := PWord(aData)^;
2580 aPixel.Data.g := PWord(aData)^;
2581 aPixel.Data.b := PWord(aData)^;
2586 constructor TfdLuminance_US1.Create;
2593 fglFormat := GL_LUMINANCE;
2594 fglDataFormat := GL_UNSIGNED_SHORT;
2597 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2598 //TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2599 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2600 procedure TfdUniversal_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2606 if (fRange.arr[i] > 0) then
2607 PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2611 procedure TfdUniversal_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2616 aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and fRange.arr[i];
2620 constructor TfdUniversal_US1.Create;
2626 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2627 //TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2628 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2629 procedure TfdDepth_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2631 PWord(aData)^ := DepthWeight(aPixel);
2635 procedure TfdDepth_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2637 aPixel.Data.r := PWord(aData)^;
2638 aPixel.Data.g := PWord(aData)^;
2639 aPixel.Data.b := PWord(aData)^;
2644 constructor TfdDepth_US1.Create;
2651 fglFormat := GL_DEPTH_COMPONENT;
2652 fglDataFormat := GL_UNSIGNED_SHORT;
2655 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2656 //TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2657 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2658 procedure TfdLuminanceAlpha_US2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2660 inherited Map(aPixel, aData, aMapData);
2661 PWord(aData)^ := aPixel.Data.a;
2665 procedure TfdLuminanceAlpha_US2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2667 inherited Unmap(aData, aPixel, aMapData);
2668 aPixel.Data.a := PWord(aData)^;
2672 constructor TfdLuminanceAlpha_US2.Create;
2678 fglFormat := GL_LUMINANCE_ALPHA;
2679 fglDataFormat := GL_UNSIGNED_SHORT;
2682 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2683 //TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2684 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2685 procedure TfdRGB_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2687 PWord(aData)^ := aPixel.Data.r;
2689 PWord(aData)^ := aPixel.Data.g;
2691 PWord(aData)^ := aPixel.Data.b;
2695 procedure TfdRGB_US3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2697 aPixel.Data.r := PWord(aData)^;
2699 aPixel.Data.g := PWord(aData)^;
2701 aPixel.Data.b := PWord(aData)^;
2706 constructor TfdRGB_US3.Create;
2716 fglFormat := GL_RGB;
2717 fglDataFormat := GL_UNSIGNED_SHORT;
2720 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2721 //TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2722 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2723 procedure TfdBGR_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2725 PWord(aData)^ := aPixel.Data.b;
2727 PWord(aData)^ := aPixel.Data.g;
2729 PWord(aData)^ := aPixel.Data.r;
2733 procedure TfdBGR_US3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2735 aPixel.Data.b := PWord(aData)^;
2737 aPixel.Data.g := PWord(aData)^;
2739 aPixel.Data.r := PWord(aData)^;
2744 constructor TfdBGR_US3.Create;
2754 fglFormat := GL_BGR;
2755 fglDataFormat := GL_UNSIGNED_SHORT;
2758 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2759 //TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2760 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2761 procedure TfdRGBA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2763 inherited Map(aPixel, aData, aMapData);
2764 PWord(aData)^ := aPixel.Data.a;
2768 procedure TfdRGBA_US4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2770 inherited Unmap(aData, aPixel, aMapData);
2771 aPixel.Data.a := PWord(aData)^;
2775 constructor TfdRGBA_US4.Create;
2781 fglFormat := GL_RGBA;
2782 fglDataFormat := GL_UNSIGNED_SHORT;
2785 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2786 //TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2787 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2788 procedure TfdBGRA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2790 inherited Map(aPixel, aData, aMapData);
2791 PWord(aData)^ := aPixel.Data.a;
2795 procedure TfdBGRA_US4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2797 inherited Unmap(aData, aPixel, aMapData);
2798 aPixel.Data.a := PWord(aData)^;
2802 constructor TfdBGRA_US4.Create;
2808 fglFormat := GL_BGRA;
2809 fglDataFormat := GL_UNSIGNED_SHORT;
2812 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2813 //TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2814 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2815 procedure TfdUniversal_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2819 PCardinal(aData)^ := 0;
2821 if (fRange.arr[i] > 0) then
2822 PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2826 procedure TfdUniversal_UI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2831 aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and fRange.arr[i];
2835 constructor TfdUniversal_UI1.Create;
2841 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2842 //TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2843 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2844 procedure TfdDepth_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2846 PCardinal(aData)^ := DepthWeight(aPixel);
2850 procedure TfdDepth_UI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2852 aPixel.Data.r := PCardinal(aData)^;
2853 aPixel.Data.g := PCardinal(aData)^;
2854 aPixel.Data.b := PCardinal(aData)^;
2859 constructor TfdDepth_UI1.Create;
2863 fRange.r := $FFFFFFFF;
2864 fRange.g := $FFFFFFFF;
2865 fRange.b := $FFFFFFFF;
2866 fglFormat := GL_DEPTH_COMPONENT;
2867 fglDataFormat := GL_UNSIGNED_INT;
2870 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2871 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2872 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2873 constructor TfdAlpha4.Create;
2876 fFormat := tfAlpha4;
2877 fWithAlpha := tfAlpha4;
2878 fglInternalFormat := GL_ALPHA4;
2881 constructor TfdAlpha8.Create;
2884 fFormat := tfAlpha8;
2885 fWithAlpha := tfAlpha8;
2886 fglInternalFormat := GL_ALPHA8;
2889 constructor TfdAlpha12.Create;
2892 fFormat := tfAlpha12;
2893 fWithAlpha := tfAlpha12;
2894 fglInternalFormat := GL_ALPHA12;
2897 constructor TfdAlpha16.Create;
2900 fFormat := tfAlpha16;
2901 fWithAlpha := tfAlpha16;
2902 fglInternalFormat := GL_ALPHA16;
2905 constructor TfdLuminance4.Create;
2908 fFormat := tfLuminance4;
2909 fWithAlpha := tfLuminance4Alpha4;
2910 fWithoutAlpha := tfLuminance4;
2911 fglInternalFormat := GL_LUMINANCE4;
2914 constructor TfdLuminance8.Create;
2917 fFormat := tfLuminance8;
2918 fWithAlpha := tfLuminance8Alpha8;
2919 fWithoutAlpha := tfLuminance8;
2920 fglInternalFormat := GL_LUMINANCE8;
2923 constructor TfdLuminance12.Create;
2926 fFormat := tfLuminance12;
2927 fWithAlpha := tfLuminance12Alpha12;
2928 fWithoutAlpha := tfLuminance12;
2929 fglInternalFormat := GL_LUMINANCE12;
2932 constructor TfdLuminance16.Create;
2935 fFormat := tfLuminance16;
2936 fWithAlpha := tfLuminance16Alpha16;
2937 fWithoutAlpha := tfLuminance16;
2938 fglInternalFormat := GL_LUMINANCE16;
2941 constructor TfdLuminance4Alpha4.Create;
2944 fFormat := tfLuminance4Alpha4;
2945 fWithAlpha := tfLuminance4Alpha4;
2946 fWithoutAlpha := tfLuminance4;
2947 fglInternalFormat := GL_LUMINANCE4_ALPHA4;
2950 constructor TfdLuminance6Alpha2.Create;
2953 fFormat := tfLuminance6Alpha2;
2954 fWithAlpha := tfLuminance6Alpha2;
2955 fWithoutAlpha := tfLuminance8;
2956 fglInternalFormat := GL_LUMINANCE6_ALPHA2;
2959 constructor TfdLuminance8Alpha8.Create;
2962 fFormat := tfLuminance8Alpha8;
2963 fWithAlpha := tfLuminance8Alpha8;
2964 fWithoutAlpha := tfLuminance8;
2965 fglInternalFormat := GL_LUMINANCE8_ALPHA8;
2968 constructor TfdLuminance12Alpha4.Create;
2971 fFormat := tfLuminance12Alpha4;
2972 fWithAlpha := tfLuminance12Alpha4;
2973 fWithoutAlpha := tfLuminance12;
2974 fglInternalFormat := GL_LUMINANCE12_ALPHA4;
2977 constructor TfdLuminance12Alpha12.Create;
2980 fFormat := tfLuminance12Alpha12;
2981 fWithAlpha := tfLuminance12Alpha12;
2982 fWithoutAlpha := tfLuminance12;
2983 fglInternalFormat := GL_LUMINANCE12_ALPHA12;
2986 constructor TfdLuminance16Alpha16.Create;
2989 fFormat := tfLuminance16Alpha16;
2990 fWithAlpha := tfLuminance16Alpha16;
2991 fWithoutAlpha := tfLuminance16;
2992 fglInternalFormat := GL_LUMINANCE16_ALPHA16;
2995 constructor TfdR3G3B2.Create;
2998 fFormat := tfR3G3B2;
2999 fWithAlpha := tfRGBA2;
3000 fWithoutAlpha := tfR3G3B2;
3007 fglFormat := GL_RGB;
3008 fglInternalFormat := GL_R3_G3_B2;
3009 fglDataFormat := GL_UNSIGNED_BYTE_2_3_3_REV;
3012 constructor TfdRGB4.Create;
3016 fWithAlpha := tfRGBA4;
3017 fWithoutAlpha := tfRGB4;
3018 fRGBInverted := tfBGR4;
3025 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3026 fglInternalFormat := GL_RGB4;
3027 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3030 constructor TfdR5G6B5.Create;
3033 fFormat := tfR5G6B5;
3034 fWithAlpha := tfRGBA4;
3035 fWithoutAlpha := tfR5G6B5;
3036 fRGBInverted := tfB5G6R5;
3043 fglFormat := GL_RGB;
3044 fglInternalFormat := GL_RGB565;
3045 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5_REV;
3048 constructor TfdRGB5.Create;
3052 fWithAlpha := tfRGB5A1;
3053 fWithoutAlpha := tfRGB5;
3054 fRGBInverted := tfBGR5;
3061 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3062 fglInternalFormat := GL_RGB5;
3063 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3066 constructor TfdRGB8.Create;
3070 fWithAlpha := tfRGBA8;
3071 fWithoutAlpha := tfRGB8;
3072 fRGBInverted := tfBGR8;
3073 fglInternalFormat := GL_RGB8;
3076 constructor TfdRGB10.Create;
3080 fWithAlpha := tfRGB10A2;
3081 fWithoutAlpha := tfRGB10;
3082 fRGBInverted := tfBGR10;
3089 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3090 fglInternalFormat := GL_RGB10;
3091 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3094 constructor TfdRGB12.Create;
3098 fWithAlpha := tfRGBA12;
3099 fWithoutAlpha := tfRGB12;
3100 fRGBInverted := tfBGR12;
3101 fglInternalFormat := GL_RGB12;
3104 constructor TfdRGB16.Create;
3108 fWithAlpha := tfRGBA16;
3109 fWithoutAlpha := tfRGB16;
3110 fRGBInverted := tfBGR16;
3111 fglInternalFormat := GL_RGB16;
3114 constructor TfdRGBA2.Create;
3118 fWithAlpha := tfRGBA2;
3119 fWithoutAlpha := tfR3G3B2;
3120 fRGBInverted := tfBGRA2;
3121 fglInternalFormat := GL_RGBA2;
3124 constructor TfdRGBA4.Create;
3128 fWithAlpha := tfRGBA4;
3129 fWithoutAlpha := tfRGB4;
3130 fRGBInverted := tfBGRA4;
3139 fglFormat := GL_RGBA;
3140 fglInternalFormat := GL_RGBA4;
3141 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3144 constructor TfdRGB5A1.Create;
3147 fFormat := tfRGB5A1;
3148 fWithAlpha := tfRGB5A1;
3149 fWithoutAlpha := tfRGB5;
3150 fRGBInverted := tfBGR5A1;
3159 fglFormat := GL_RGBA;
3160 fglInternalFormat := GL_RGB5_A1;
3161 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3164 constructor TfdRGBA8.Create;
3168 fWithAlpha := tfRGBA8;
3169 fWithoutAlpha := tfRGB8;
3170 fRGBInverted := tfBGRA8;
3171 fglInternalFormat := GL_RGBA8;
3174 constructor TfdRGB10A2.Create;
3177 fFormat := tfRGB10A2;
3178 fWithAlpha := tfRGB10A2;
3179 fWithoutAlpha := tfRGB10;
3180 fRGBInverted := tfBGR10A2;
3189 fglFormat := GL_RGBA;
3190 fglInternalFormat := GL_RGB10_A2;
3191 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3194 constructor TfdRGBA12.Create;
3197 fFormat := tfRGBA12;
3198 fWithAlpha := tfRGBA12;
3199 fWithoutAlpha := tfRGB12;
3200 fRGBInverted := tfBGRA12;
3201 fglInternalFormat := GL_RGBA12;
3204 constructor TfdRGBA16.Create;
3207 fFormat := tfRGBA16;
3208 fWithAlpha := tfRGBA16;
3209 fWithoutAlpha := tfRGB16;
3210 fRGBInverted := tfBGRA16;
3211 fglInternalFormat := GL_RGBA16;
3214 constructor TfdBGR4.Create;
3219 fWithAlpha := tfBGRA4;
3220 fWithoutAlpha := tfBGR4;
3221 fRGBInverted := tfRGB4;
3230 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3231 fglInternalFormat := GL_RGB4;
3232 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3235 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3236 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3237 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3238 constructor TfdB5G6R5.Create;
3241 fFormat := tfB5G6R5;
3242 fWithAlpha := tfBGRA4;
3243 fWithoutAlpha := tfB5G6R5;
3244 fRGBInverted := tfR5G6B5;
3251 fglFormat := GL_RGB; //B5G6R5 is only possible as R5G6B5 -> use reverted dataformat
3252 fglInternalFormat := GL_RGB8;
3253 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5;
3256 constructor TfdBGR5.Create;
3261 fWithAlpha := tfBGR5A1;
3262 fWithoutAlpha := tfBGR5;
3263 fRGBInverted := tfRGB5;
3272 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3273 fglInternalFormat := GL_RGB5;
3274 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3277 constructor TfdBGR8.Create;
3281 fWithAlpha := tfBGRA8;
3282 fWithoutAlpha := tfBGR8;
3283 fRGBInverted := tfRGB8;
3284 fglInternalFormat := GL_RGB8;
3287 constructor TfdBGR10.Create;
3291 fWithAlpha := tfBGR10A2;
3292 fWithoutAlpha := tfBGR10;
3293 fRGBInverted := tfRGB10;
3302 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3303 fglInternalFormat := GL_RGB10;
3304 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3307 constructor TfdBGR12.Create;
3311 fWithAlpha := tfBGRA12;
3312 fWithoutAlpha := tfBGR12;
3313 fRGBInverted := tfRGB12;
3314 fglInternalFormat := GL_RGB12;
3317 constructor TfdBGR16.Create;
3321 fWithAlpha := tfBGRA16;
3322 fWithoutAlpha := tfBGR16;
3323 fRGBInverted := tfRGB16;
3324 fglInternalFormat := GL_RGB16;
3327 constructor TfdBGRA2.Create;
3331 fWithAlpha := tfBGRA4;
3332 fWithoutAlpha := tfBGR4;
3333 fRGBInverted := tfRGBA2;
3334 fglInternalFormat := GL_RGBA2;
3337 constructor TfdBGRA4.Create;
3341 fWithAlpha := tfBGRA4;
3342 fWithoutAlpha := tfBGR4;
3343 fRGBInverted := tfRGBA4;
3352 fglFormat := GL_BGRA;
3353 fglInternalFormat := GL_RGBA4;
3354 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3357 constructor TfdBGR5A1.Create;
3360 fFormat := tfBGR5A1;
3361 fWithAlpha := tfBGR5A1;
3362 fWithoutAlpha := tfBGR5;
3363 fRGBInverted := tfRGB5A1;
3372 fglFormat := GL_BGRA;
3373 fglInternalFormat := GL_RGB5_A1;
3374 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3377 constructor TfdBGRA8.Create;
3381 fWithAlpha := tfBGRA8;
3382 fWithoutAlpha := tfBGR8;
3383 fRGBInverted := tfRGBA8;
3384 fglInternalFormat := GL_RGBA8;
3387 constructor TfdBGR10A2.Create;
3390 fFormat := tfBGR10A2;
3391 fWithAlpha := tfBGR10A2;
3392 fWithoutAlpha := tfBGR10;
3393 fRGBInverted := tfRGB10A2;
3402 fglFormat := GL_BGRA;
3403 fglInternalFormat := GL_RGB10_A2;
3404 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3407 constructor TfdBGRA12.Create;
3410 fFormat := tfBGRA12;
3411 fWithAlpha := tfBGRA12;
3412 fWithoutAlpha := tfBGR12;
3413 fRGBInverted := tfRGBA12;
3414 fglInternalFormat := GL_RGBA12;
3417 constructor TfdBGRA16.Create;
3420 fFormat := tfBGRA16;
3421 fWithAlpha := tfBGRA16;
3422 fWithoutAlpha := tfBGR16;
3423 fRGBInverted := tfRGBA16;
3424 fglInternalFormat := GL_RGBA16;
3427 constructor TfdDepth16.Create;
3430 fFormat := tfDepth16;
3431 fWithAlpha := tfEmpty;
3432 fWithoutAlpha := tfDepth16;
3433 fglInternalFormat := GL_DEPTH_COMPONENT16;
3436 constructor TfdDepth24.Create;
3439 fFormat := tfDepth24;
3440 fWithAlpha := tfEmpty;
3441 fWithoutAlpha := tfDepth24;
3442 fglInternalFormat := GL_DEPTH_COMPONENT24;
3445 constructor TfdDepth32.Create;
3448 fFormat := tfDepth32;
3449 fWithAlpha := tfEmpty;
3450 fWithoutAlpha := tfDepth32;
3451 fglInternalFormat := GL_DEPTH_COMPONENT32;
3454 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3455 //TfdS3tcDtx1RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3456 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3457 procedure TfdS3tcDtx1RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3459 raise EglBitmapException.Create('mapping for compressed formats is not supported');
3462 procedure TfdS3tcDtx1RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3464 raise EglBitmapException.Create('mapping for compressed formats is not supported');
3467 constructor TfdS3tcDtx1RGBA.Create;
3470 fFormat := tfS3tcDtx1RGBA;
3471 fWithAlpha := tfS3tcDtx1RGBA;
3472 fUncompressed := tfRGB5A1;
3474 fIsCompressed := true;
3475 fglFormat := GL_COMPRESSED_RGBA;
3476 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
3477 fglDataFormat := GL_UNSIGNED_BYTE;
3480 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3481 //TfdS3tcDtx3RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3482 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3483 procedure TfdS3tcDtx3RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3485 raise EglBitmapException.Create('mapping for compressed formats is not supported');
3488 procedure TfdS3tcDtx3RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3490 raise EglBitmapException.Create('mapping for compressed formats is not supported');
3493 constructor TfdS3tcDtx3RGBA.Create;
3496 fFormat := tfS3tcDtx3RGBA;
3497 fWithAlpha := tfS3tcDtx3RGBA;
3498 fUncompressed := tfRGBA8;
3500 fIsCompressed := true;
3501 fglFormat := GL_COMPRESSED_RGBA;
3502 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
3503 fglDataFormat := GL_UNSIGNED_BYTE;
3506 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3507 //TfdS3tcDtx5RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3508 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3509 procedure TfdS3tcDtx5RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3511 raise EglBitmapException.Create('mapping for compressed formats is not supported');
3514 procedure TfdS3tcDtx5RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3516 raise EglBitmapException.Create('mapping for compressed formats is not supported');
3519 constructor TfdS3tcDtx5RGBA.Create;
3522 fFormat := tfS3tcDtx3RGBA;
3523 fWithAlpha := tfS3tcDtx3RGBA;
3524 fUncompressed := tfRGBA8;
3526 fIsCompressed := true;
3527 fglFormat := GL_COMPRESSED_RGBA;
3528 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
3529 fglDataFormat := GL_UNSIGNED_BYTE;
3532 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3533 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3534 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3535 class procedure TFormatDescriptor.Init;
3537 if not Assigned(FormatDescriptorCS) then
3538 FormatDescriptorCS := TCriticalSection.Create;
3541 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3542 class function TFormatDescriptor.Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
3544 FormatDescriptorCS.Enter;
3546 result := FormatDescriptors[aFormat];
3547 if not Assigned(result) then begin
3548 result := FORMAT_DESCRIPTOR_CLASSES[aFormat].Create;
3549 FormatDescriptors[aFormat] := result;
3552 FormatDescriptorCS.Leave;
3556 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3557 class function TFormatDescriptor.GetWithAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
3559 result := Get(Get(aFormat).WithAlpha);
3562 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3563 class procedure TFormatDescriptor.Clear;
3567 FormatDescriptorCS.Enter;
3569 for f := low(FormatDescriptors) to high(FormatDescriptors) do
3570 FreeAndNil(FormatDescriptors[f]);
3572 FormatDescriptorCS.Leave;
3576 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3577 class procedure TFormatDescriptor.Finalize;
3580 FreeAndNil(FormatDescriptorCS);
3583 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3584 //TBitfieldFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3585 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3586 procedure TbmpBitfieldFormat.SetRedMask(const aValue: QWord);
3588 Update(aValue, fRange.r, fShift.r);
3591 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3592 procedure TbmpBitfieldFormat.SetGreenMask(const aValue: QWord);
3594 Update(aValue, fRange.g, fShift.g);
3597 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3598 procedure TbmpBitfieldFormat.SetBlueMask(const aValue: QWord);
3600 Update(aValue, fRange.b, fShift.b);
3603 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3604 procedure TbmpBitfieldFormat.SetAlphaMask(const aValue: QWord);
3606 Update(aValue, fRange.a, fShift.a);
3609 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3610 procedure TbmpBitfieldFormat.Update(aMask: QWord; out aRange: Cardinal; out
3617 while (aMask > 0) and ((aMask and 1) = 0) do begin
3619 aMask := aMask shr 1;
3622 while (aMask > 0) do begin
3623 aRange := aRange shl 1;
3624 aMask := aMask shr 1;
3628 fPixelSize := Round(GetTopMostBit(RedMask or GreenMask or BlueMask or AlphaMask) / 8);
3631 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3632 procedure TbmpBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3638 ((aPixel.Data.r and fRange.r) shl fShift.r) or
3639 ((aPixel.Data.g and fRange.g) shl fShift.g) or
3640 ((aPixel.Data.b and fRange.b) shl fShift.b) or
3641 ((aPixel.Data.a and fRange.a) shl fShift.a);
3642 s := Round(fPixelSize);
3645 2: PWord(aData)^ := data;
3646 4: PCardinal(aData)^ := data;
3647 8: PQWord(aData)^ := data;
3649 raise EglBitmapException.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
3654 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3655 procedure TbmpBitfieldFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3660 s := Round(fPixelSize);
3663 2: data := PWord(aData)^;
3664 4: data := PCardinal(aData)^;
3665 8: data := PQWord(aData)^;
3667 raise EglBitmapException.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
3670 aPixel.Data.arr[i] := (data shr fShift.arr[i]) and fRange.arr[i];
3674 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3675 //TColorTableFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3676 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3677 procedure TbmpColorTableFormat.CreateColorTable;
3681 if not (Format in [tfLuminance4, tfLuminance8, tfR3G3B2]) then
3682 raise EglBitmapException.Create(UNSUPPORTED_FORMAT);
3684 if (Format = tfLuminance4) then
3685 SetLength(fColorTable, 16)
3687 SetLength(fColorTable, 256);
3691 for i := 0 to High(fColorTable) do begin
3692 fColorTable[i].r := 16 * i;
3693 fColorTable[i].g := 16 * i;
3694 fColorTable[i].b := 16 * i;
3695 fColorTable[i].a := 0;
3700 for i := 0 to High(fColorTable) do begin
3701 fColorTable[i].r := i;
3702 fColorTable[i].g := i;
3703 fColorTable[i].b := i;
3704 fColorTable[i].a := 0;
3709 for i := 0 to High(fColorTable) do begin
3710 fColorTable[i].r := Round(((i shr Shift.r) and Range.r) / Range.r * 255);
3711 fColorTable[i].g := Round(((i shr Shift.g) and Range.g) / Range.g * 255);
3712 fColorTable[i].b := Round(((i shr Shift.b) and Range.b) / Range.b * 255);
3713 fColorTable[i].a := 0;
3719 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3720 procedure TbmpColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3724 if not (Format in [tfLuminance4, tfLuminance8, tfR3G3B2]) then
3725 raise EglBitmapException.Create(UNSUPPORTED_FORMAT);
3729 if (aMapData = nil) then
3731 d := LuminanceWeight(aPixel) and Range.r;
3732 aData^ := aData^ or (d shl (4 - {%H-}PtrUInt(aMapData)));
3733 inc(PByte(aMapData), 4);
3734 if ({%H-}PtrUInt(aMapData) >= 8) then begin
3741 aData^ := LuminanceWeight(aPixel) and Range.r;
3747 ((aPixel.Data.r and Range.r) shl Shift.r) or
3748 ((aPixel.Data.g and Range.g) shl Shift.g) or
3749 ((aPixel.Data.b and Range.b) shl Shift.b));
3755 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3756 procedure TbmpColorTableFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3763 s := Trunc(fPixelSize);
3764 f := fPixelSize - s;
3765 bits := Round(8 * f);
3767 0: idx := (aData^ shr (8 - bits - {%H-}PtrInt(aMapData))) and ((1 shl bits) - 1);
3769 2: idx := PWord(aData)^;
3770 4: idx := PCardinal(aData)^;
3771 8: idx := PQWord(aData)^;
3773 raise EglBitmapException.CreateFmt('invalid pixel size: %.3f', [fPixelSize]);
3775 if (idx >= Length(fColorTable)) then
3776 raise EglBitmapException.CreateFmt('invalid color index: %d', [idx]);
3777 with fColorTable[idx] do begin
3783 inc(PByte(aMapData), bits);
3784 if ({%H-}PtrUInt(aMapData) >= 8) then begin
3786 dec(PByte(aMapData), 8);
3791 destructor TbmpColorTableFormat.Destroy;
3793 SetLength(fColorTable, 0);
3797 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3798 //TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3799 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3800 procedure glBitmapConvertPixel(var aPixel: TglBitmapPixelData; const aSourceFD, aDestFD: TFormatDescriptor);
3804 for i := 0 to 3 do begin
3805 if (aSourceFD.Range.arr[i] <> aDestFD.Range.arr[i]) then begin
3806 if (aSourceFD.Range.arr[i] > 0) then
3807 aPixel.Data.arr[i] := Round(aPixel.Data.arr[i] / aSourceFD.Range.arr[i] * aDestFD.Range.arr[i])
3809 aPixel.Data.arr[i] := aDestFD.Range.arr[i];
3814 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3815 procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
3817 with aFuncRec do begin
3818 if (Source.Range.r > 0) then
3819 Dest.Data.r := Source.Data.r;
3820 if (Source.Range.g > 0) then
3821 Dest.Data.g := Source.Data.g;
3822 if (Source.Range.b > 0) then
3823 Dest.Data.b := Source.Data.b;
3824 if (Source.Range.a > 0) then
3825 Dest.Data.a := Source.Data.a;
3829 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3830 procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
3834 with aFuncRec do begin
3836 if (Source.Range.arr[i] > 0) then
3837 Dest.Data.arr[i] := Round(Dest.Range.arr[i] * Source.Data.arr[i] / Source.Range.arr[i]);
3842 TShiftData = packed record
3844 0: (r, g, b, a: SmallInt);
3845 1: (arr: array[0..3] of SmallInt);
3847 PShiftData = ^TShiftData;
3849 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3850 procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
3856 if (Source.Range.arr[i] > 0) then
3857 Dest.Data.arr[i] := Source.Data.arr[i] shr PShiftData(Args)^.arr[i];
3860 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3861 procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
3863 with aFuncRec do begin
3864 Dest.Data := Source.Data;
3865 if ({%H-}PtrUInt(Args) and $1 > 0) then begin
3866 Dest.Data.r := Dest.Data.r xor Dest.Range.r;
3867 Dest.Data.g := Dest.Data.g xor Dest.Range.g;
3868 Dest.Data.b := Dest.Data.b xor Dest.Range.b;
3870 if ({%H-}PtrUInt(Args) and $2 > 0) then begin
3871 Dest.Data.a := Dest.Data.a xor Dest.Range.a;
3876 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3877 procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
3881 with aFuncRec do begin
3883 Dest.Data.arr[i] := PglBitmapPixelData(Args)^.Data.arr[i];
3887 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3888 procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
3892 with FuncRec do begin
3893 if (FuncRec.Args = nil) then begin //source has no alpha
3895 Source.Data.r / Source.Range.r * ALPHA_WEIGHT_R +
3896 Source.Data.g / Source.Range.g * ALPHA_WEIGHT_G +
3897 Source.Data.b / Source.Range.b * ALPHA_WEIGHT_B;
3898 Dest.Data.a := Round(Dest.Range.a * Temp);
3900 Dest.Data.a := Round(Source.Data.a / Source.Range.a * Dest.Range.a);
3904 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3905 procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
3907 PglBitmapPixelData = ^TglBitmapPixelData;
3909 with FuncRec do begin
3910 Dest.Data.r := Source.Data.r;
3911 Dest.Data.g := Source.Data.g;
3912 Dest.Data.b := Source.Data.b;
3914 with PglBitmapPixelData(Args)^ do
3915 if ((Dest.Data.r <= Data.r) and (Dest.Data.r >= Range.r) and
3916 (Dest.Data.g <= Data.g) and (Dest.Data.g >= Range.g) and
3917 (Dest.Data.b <= Data.b) and (Dest.Data.b >= Range.b)) then
3920 Dest.Data.a := Dest.Range.a;
3924 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3925 procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
3927 with FuncRec do begin
3928 Dest.Data.r := Source.Data.r;
3929 Dest.Data.g := Source.Data.g;
3930 Dest.Data.b := Source.Data.b;
3931 Dest.Data.a := PCardinal(Args)^;
3935 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3936 procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
3939 TRGBPix = array [0..2] of byte;
3943 while aWidth > 0 do begin
3944 Temp := PRGBPix(aData)^[0];
3945 PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
3946 PRGBPix(aData)^[2] := Temp;
3956 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3957 //TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3958 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3959 function TglBitmap.GetWidth: Integer;
3961 if (ffX in fDimension.Fields) then
3962 result := fDimension.X
3967 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3968 function TglBitmap.GetHeight: Integer;
3970 if (ffY in fDimension.Fields) then
3971 result := fDimension.Y
3976 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3977 function TglBitmap.GetFileWidth: Integer;
3979 result := Max(1, Width);
3982 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3983 function TglBitmap.GetFileHeight: Integer;
3985 result := Max(1, Height);
3988 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3989 procedure TglBitmap.SetCustomData(const aValue: Pointer);
3991 if fCustomData = aValue then
3993 fCustomData := aValue;
3996 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3997 procedure TglBitmap.SetCustomName(const aValue: String);
3999 if fCustomName = aValue then
4001 fCustomName := aValue;
4004 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4005 procedure TglBitmap.SetCustomNameW(const aValue: WideString);
4007 if fCustomNameW = aValue then
4009 fCustomNameW := aValue;
4012 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4013 procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
4015 if fDeleteTextureOnFree = aValue then
4017 fDeleteTextureOnFree := aValue;
4020 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4021 procedure TglBitmap.SetFormat(const aValue: TglBitmapFormat);
4023 if fFormat = aValue then
4025 if TFormatDescriptor.Get(Format).PixelSize <> TFormatDescriptor.Get(aValue).PixelSize then
4026 raise EglBitmapUnsupportedFormat.Create(Format);
4027 SetDataPointer(fData, aValue, Width, Height); //be careful, Data could be freed by this method
4030 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4031 procedure TglBitmap.SetFreeDataAfterGenTexture(const aValue: Boolean);
4033 if fFreeDataAfterGenTexture = aValue then
4035 fFreeDataAfterGenTexture := aValue;
4038 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4039 procedure TglBitmap.SetID(const aValue: Cardinal);
4041 if fID = aValue then
4046 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4047 procedure TglBitmap.SetMipMap(const aValue: TglBitmapMipMap);
4049 if fMipMap = aValue then
4054 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4055 procedure TglBitmap.SetTarget(const aValue: Cardinal);
4057 if fTarget = aValue then
4062 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4063 procedure TglBitmap.SetAnisotropic(const aValue: Integer);
4065 MaxAnisotropic: Integer;
4067 fAnisotropic := aValue;
4068 if (ID > 0) then begin
4069 if GL_EXT_texture_filter_anisotropic then begin
4070 if fAnisotropic > 0 then begin
4072 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
4073 if aValue > MaxAnisotropic then
4074 fAnisotropic := MaxAnisotropic;
4075 glTexParameteri(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, fAnisotropic);
4083 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4084 procedure TglBitmap.CreateID;
4087 glDeleteTextures(1, @fID);
4088 glGenTextures(1, @fID);
4092 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4093 procedure TglBitmap.SetupParameters(out aBuildWithGlu: Boolean);
4095 // Set Up Parameters
4096 SetWrap(fWrapS, fWrapT, fWrapR);
4097 SetFilter(fFilterMin, fFilterMag);
4098 SetAnisotropic(fAnisotropic);
4099 SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
4101 // Mip Maps Generation Mode
4102 aBuildWithGlu := false;
4103 if (MipMap = mmMipmap) then begin
4104 if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
4105 glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
4107 aBuildWithGlu := true;
4108 end else if (MipMap = mmMipmapGlu) then
4109 aBuildWithGlu := true;
4112 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4113 procedure TglBitmap.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
4114 const aWidth: Integer; const aHeight: Integer);
4118 if (Data <> aData) then begin
4119 if (Assigned(Data)) then
4124 FillChar(fDimension, SizeOf(fDimension), 0);
4125 if not Assigned(fData) then begin
4130 if aWidth <> -1 then begin
4131 fDimension.Fields := fDimension.Fields + [ffX];
4132 fDimension.X := aWidth;
4135 if aHeight <> -1 then begin
4136 fDimension.Fields := fDimension.Fields + [ffY];
4137 fDimension.Y := aHeight;
4140 s := TFormatDescriptor.Get(aFormat).PixelSize;
4142 fPixelSize := Ceil(s);
4143 fRowSize := Ceil(s * aWidth);
4147 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4148 function TglBitmap.FlipHorz: Boolean;
4153 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4154 function TglBitmap.FlipVert: Boolean;
4159 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4160 //TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4161 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4162 procedure TglBitmap.AfterConstruction;
4164 inherited AfterConstruction;
4168 fIsResident := false;
4170 fFormat := glBitmapGetDefaultFormat;
4171 fMipMap := glBitmapDefaultMipmap;
4172 fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
4173 fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
4175 glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
4176 glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
4179 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4180 procedure TglBitmap.BeforeDestruction;
4185 SetDataPointer(NewData, tfEmpty); //be careful, Data could be freed by this method
4186 if (fID > 0) and fDeleteTextureOnFree then
4187 glDeleteTextures(1, @fID);
4188 inherited BeforeDestruction;
4191 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4192 procedure TglBitmap.PrepareResType(var aResource: String; var aResType: PChar);
4196 if not Assigned(aResType) then begin
4197 TempPos := Pos('.', aResource);
4198 aResType := PChar(UpperCase(Copy(aResource, TempPos + 1, Length(aResource) - TempPos)));
4199 aResource := UpperCase(Copy(aResource, 0, TempPos -1));
4203 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4204 procedure TglBitmap.LoadFromFile(const aFilename: String);
4208 if not FileExists(aFilename) then
4209 raise EglBitmapException.Create('file does not exist: ' + aFilename);
4210 fFilename := aFilename;
4211 fs := TFileStream.Create(fFilename, fmOpenRead);
4220 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4221 procedure TglBitmap.LoadFromStream(const aStream: TStream);
4223 {$IFDEF GLB_SUPPORT_PNG_READ}
4224 if not LoadPNG(aStream) then
4226 {$IFDEF GLB_SUPPORT_JPEG_READ}
4227 if not LoadJPEG(aStream) then
4229 if not LoadDDS(aStream) then
4230 if not LoadTGA(aStream) then
4231 if not LoadBMP(aStream) then
4232 raise EglBitmapException.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
4235 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4236 procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
4237 const aFormat: TglBitmapFormat; const aArgs: Pointer);
4242 size := TFormatDescriptor.Get(aFormat).GetSize(aSize);
4243 GetMem(tmpData, size);
4245 FillChar(tmpData^, size, #$FF);
4246 SetDataPointer(tmpData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
4248 if Assigned(tmpData) then
4252 AddFunc(Self, aFunc, false, Format, aArgs);
4255 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4256 procedure TglBitmap.LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar);
4258 rs: TResourceStream;
4260 PrepareResType(aResource, aResType);
4261 rs := TResourceStream.Create(aInstance, aResource, aResType);
4269 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4270 procedure TglBitmap.LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
4272 rs: TResourceStream;
4274 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
4282 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4283 procedure TglBitmap.SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
4287 fs := TFileStream.Create(aFileName, fmCreate);
4290 SaveToStream(fs, aFileType);
4296 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4297 procedure TglBitmap.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
4300 {$IFDEF GLB_SUPPORT_PNG_WRITE}
4301 ftPNG: SavePNG(aStream);
4303 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
4304 ftJPEG: SaveJPEG(aStream);
4306 ftDDS: SaveDDS(aStream);
4307 ftTGA: SaveTGA(aStream);
4308 ftBMP: SaveBMP(aStream);
4312 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4313 function TglBitmap.AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer): Boolean;
4315 result := AddFunc(Self, aFunc, aCreateTemp, Format, aArgs);
4318 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4319 function TglBitmap.AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
4320 const aFormat: TglBitmapFormat; const aArgs: Pointer): Boolean;
4322 DestData, TmpData, SourceData: pByte;
4323 TempHeight, TempWidth: Integer;
4324 SourceFD, DestFD: TFormatDescriptor;
4325 SourceMD, DestMD: Pointer;
4327 FuncRec: TglBitmapFunctionRec;
4329 Assert(Assigned(Data));
4330 Assert(Assigned(aSource));
4331 Assert(Assigned(aSource.Data));
4334 if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
4335 SourceFD := TFormatDescriptor.Get(aSource.Format);
4336 DestFD := TFormatDescriptor.Get(aFormat);
4338 if (SourceFD.IsCompressed) then
4339 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', SourceFD.Format);
4340 if (DestFD.IsCompressed) then
4341 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', DestFD.Format);
4343 // inkompatible Formats so CreateTemp
4344 if (SourceFD.PixelSize <> DestFD.PixelSize) then
4345 aCreateTemp := true;
4348 TempHeight := Max(1, aSource.Height);
4349 TempWidth := Max(1, aSource.Width);
4351 FuncRec.Sender := Self;
4352 FuncRec.Args := aArgs;
4355 if aCreateTemp then begin
4356 GetMem(TmpData, DestFD.GetSize(TempWidth, TempHeight));
4357 DestData := TmpData;
4362 SourceFD.PreparePixel(FuncRec.Source);
4363 DestFD.PreparePixel (FuncRec.Dest);
4365 SourceMD := SourceFD.CreateMappingData;
4366 DestMD := DestFD.CreateMappingData;
4368 FuncRec.Size := aSource.Dimension;
4369 FuncRec.Position.Fields := FuncRec.Size.Fields;
4372 SourceData := aSource.Data;
4373 FuncRec.Position.Y := 0;
4374 while FuncRec.Position.Y < TempHeight do begin
4375 FuncRec.Position.X := 0;
4376 while FuncRec.Position.X < TempWidth do begin
4377 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
4379 DestFD.Map(FuncRec.Dest, DestData, DestMD);
4380 inc(FuncRec.Position.X);
4382 inc(FuncRec.Position.Y);
4385 // Updating Image or InternalFormat
4387 SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height) //be careful, Data could be freed by this method
4388 else if (aFormat <> fFormat) then
4393 SourceFD.FreeMappingData(SourceMD);
4394 DestFD.FreeMappingData(DestMD);
4397 if aCreateTemp and Assigned(TmpData) then
4405 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4406 function TglBitmap.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
4408 Row, RowSize: Integer;
4409 SourceData, TmpData: PByte;
4411 FormatDesc: TFormatDescriptor;
4413 function GetRowPointer(Row: Integer): pByte;
4415 result := aSurface.pixels;
4416 Inc(result, Row * RowSize);
4422 FormatDesc := TFormatDescriptor.Get(Format);
4423 if FormatDesc.IsCompressed then
4424 raise EglBitmapUnsupportedFormat.Create(Format);
4426 if Assigned(Data) then begin
4427 case Trunc(FormatDesc.PixelSize) of
4433 raise EglBitmapUnsupportedFormat.Create(Format);
4436 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
4437 FormatDesc.RedMask, FormatDesc.GreenMask, FormatDesc.BlueMask, FormatDesc.AlphaMask);
4439 RowSize := FormatDesc.GetSize(FileWidth, 1);
4441 for Row := 0 to FileHeight-1 do begin
4442 TmpData := GetRowPointer(Row);
4443 if Assigned(TmpData) then begin
4444 Move(SourceData^, TmpData^, RowSize);
4445 inc(SourceData, RowSize);
4452 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4453 function TglBitmap.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
4455 pSource, pData, pTempData: PByte;
4456 Row, RowSize, TempWidth, TempHeight: Integer;
4457 IntFormat: TglBitmapFormat;
4458 FormatDesc: TFormatDescriptor;
4460 function GetRowPointer(Row: Integer): pByte;
4462 result := aSurface^.pixels;
4463 Inc(result, Row * RowSize);
4468 if (Assigned(aSurface)) then begin
4469 with aSurface^.format^ do begin
4470 for IntFormat := High(TglBitmapFormat) to Low(TglBitmapFormat) do begin
4471 FormatDesc := TFormatDescriptor.Get(IntFormat);
4472 if (FormatDesc.MaskMatch(RMask, GMask, BMask, AMask)) then
4475 if (IntFormat = tfEmpty) then
4476 raise EglBitmapException.Create('AssignFromSurface - Invalid Pixelformat.');
4479 TempWidth := aSurface^.w;
4480 TempHeight := aSurface^.h;
4481 RowSize := FormatDesc.GetSize(TempWidth, 1);
4482 GetMem(pData, TempHeight * RowSize);
4485 for Row := 0 to TempHeight -1 do begin
4486 pSource := GetRowPointer(Row);
4487 if (Assigned(pSource)) then begin
4488 Move(pSource^, pTempData^, RowSize);
4489 Inc(pTempData, RowSize);
4492 SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
4495 if Assigned(pData) then
4502 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4503 function TglBitmap.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
4505 Row, Col, AlphaInterleave: Integer;
4506 pSource, pDest: PByte;
4508 function GetRowPointer(Row: Integer): pByte;
4510 result := aSurface.pixels;
4511 Inc(result, Row * Width);
4516 if Assigned(Data) then begin
4517 if Format in [tfAlpha8, tfLuminance8Alpha8, tfBGRA8, tfRGBA8] then begin
4518 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
4520 AlphaInterleave := 0;
4523 AlphaInterleave := 1;
4525 AlphaInterleave := 3;
4529 for Row := 0 to Height -1 do begin
4530 pDest := GetRowPointer(Row);
4531 if Assigned(pDest) then begin
4532 for Col := 0 to Width -1 do begin
4533 Inc(pSource, AlphaInterleave);
4545 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4546 function TglBitmap.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
4550 bmp := TglBitmap2D.Create;
4552 bmp.AssignFromSurface(aSurface);
4553 result := AddAlphaFromGlBitmap(bmp, aFunc, aArgs);
4561 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4562 function CreateGrayPalette: HPALETTE;
4567 GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
4569 Pal.palVersion := $300;
4570 Pal.palNumEntries := 256;
4572 for Idx := 0 to Pal.palNumEntries - 1 do begin
4573 Pal.palPalEntry[Idx].peRed := Idx;
4574 Pal.palPalEntry[Idx].peGreen := Idx;
4575 Pal.palPalEntry[Idx].peBlue := Idx;
4576 Pal.palPalEntry[Idx].peFlags := 0;
4578 Result := CreatePalette(Pal^);
4582 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4583 function TglBitmap.AssignToBitmap(const aBitmap: TBitmap): Boolean;
4586 pSource, pData: PByte;
4589 if Assigned(Data) then begin
4590 if Assigned(aBitmap) then begin
4591 aBitmap.Width := Width;
4592 aBitmap.Height := Height;
4595 tfAlpha8, tfLuminance8: begin
4596 aBitmap.PixelFormat := pf8bit;
4597 aBitmap.Palette := CreateGrayPalette;
4600 aBitmap.PixelFormat := pf15bit;
4602 aBitmap.PixelFormat := pf16bit;
4604 aBitmap.PixelFormat := pf24bit;
4606 aBitmap.PixelFormat := pf32bit;
4608 raise EglBitmapException.Create('AssignToBitmap - Invalid Pixelformat.');
4612 for Row := 0 to FileHeight -1 do begin
4613 pData := aBitmap.Scanline[Row];
4614 Move(pSource^, pData^, fRowSize);
4615 Inc(pSource, fRowSize);
4616 if (Format in [tfRGB8, tfRGBA8]) then // swap RGB(A) to BGR(A)
4617 SwapRGB(pData, FileWidth, Format = tfRGBA8);
4624 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4625 function TglBitmap.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
4627 pSource, pData, pTempData: PByte;
4628 Row, RowSize, TempWidth, TempHeight: Integer;
4629 IntFormat: TglBitmapFormat;
4633 if (Assigned(aBitmap)) then begin
4634 case aBitmap.PixelFormat of
4636 IntFormat := tfLuminance8;
4638 IntFormat := tfRGB5A1;
4640 IntFormat := tfR5G6B5;
4642 IntFormat := tfBGR8;
4644 IntFormat := tfBGRA8;
4646 raise EglBitmapException.Create('AssignFromBitmap - Invalid Pixelformat.');
4649 TempWidth := aBitmap.Width;
4650 TempHeight := aBitmap.Height;
4651 RowSize := TFormatDescriptor.Get(IntFormat).GetSize(TempWidth, 1);
4652 GetMem(pData, TempHeight * RowSize);
4655 for Row := 0 to TempHeight -1 do begin
4656 pSource := aBitmap.Scanline[Row];
4657 if (Assigned(pSource)) then begin
4658 Move(pSource^, pTempData^, RowSize);
4659 Inc(pTempData, RowSize);
4662 SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
4665 if Assigned(pData) then
4672 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4673 function TglBitmap.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
4675 Row, Col, AlphaInterleave: Integer;
4676 pSource, pDest: PByte;
4680 if Assigned(Data) then begin
4681 if (Format in [tfAlpha8, tfLuminance8Alpha8, tfRGBA8, tfBGRA8]) then begin
4682 if Assigned(aBitmap) then begin
4683 aBitmap.PixelFormat := pf8bit;
4684 aBitmap.Palette := CreateGrayPalette;
4685 aBitmap.Width := Width;
4686 aBitmap.Height := Height;
4690 AlphaInterleave := 1;
4692 AlphaInterleave := 3;
4694 AlphaInterleave := 0;
4700 for Row := 0 to Height -1 do begin
4701 pDest := aBitmap.Scanline[Row];
4702 if Assigned(pDest) then begin
4703 for Col := 0 to Width -1 do begin
4704 Inc(pSource, AlphaInterleave);
4717 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4718 function TglBitmap.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
4722 tex := TglBitmap2D.Create;
4724 tex.AssignFromBitmap(ABitmap);
4725 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
4732 {$IFDEF GLB_LAZARUS}
4733 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4734 function TglBitmap.AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
4736 rid: TRawImageDescription;
4737 FormatDesc: TFormatDescriptor;
4740 if not Assigned(aImage) or (Format = tfEmpty) then
4742 FormatDesc := TFormatDescriptor.Get(Format);
4743 if FormatDesc.IsCompressed then
4746 FillChar(rid{%H-}, SizeOf(rid), 0);
4748 tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16,
4749 tfLuminance4, tfLuminance8, tfLuminance12, tfLuminance16,
4750 tfLuminance4Alpha4, tfLuminance8Alpha8, tfLuminance12Alpha4, tfLuminance12Alpha12, tfLuminance16Alpha16]) then
4751 rid.Format := ricfGray
4753 rid.Format := ricfRGBA;
4756 rid.Height := Height;
4757 rid.Depth := CountSetBits(FormatDesc.Range.r or FormatDesc.Range.g or FormatDesc.Range.b or FormatDesc.Range.a);
4758 rid.BitOrder := riboBitsInOrder;
4759 rid.ByteOrder := riboLSBFirst;
4760 rid.LineOrder := riloTopToBottom;
4761 rid.LineEnd := rileTight;
4762 rid.BitsPerPixel := Round(8 * FormatDesc.PixelSize);
4763 rid.RedPrec := CountSetBits(FormatDesc.Range.r);
4764 rid.GreenPrec := CountSetBits(FormatDesc.Range.g);
4765 rid.BluePrec := CountSetBits(FormatDesc.Range.b);
4766 rid.AlphaPrec := CountSetBits(FormatDesc.Range.a);
4767 rid.RedShift := FormatDesc.Shift.r;
4768 rid.GreenShift := FormatDesc.Shift.g;
4769 rid.BlueShift := FormatDesc.Shift.b;
4770 rid.AlphaShift := FormatDesc.Shift.a;
4772 rid.MaskBitsPerPixel := 0;
4773 rid.PaletteColorCount := 0;
4775 aImage.DataDescription := rid;
4778 Move(Data^, aImage.PixelData^, FormatDesc.GetSize(Dimension));
4783 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4784 function TglBitmap.AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
4787 FormatDesc: TFormatDescriptor;
4792 if not Assigned(aImage) then
4794 for f := High(f) downto Low(f) do begin
4795 FormatDesc := TFormatDescriptor.Get(f);
4796 with aImage.DataDescription do
4797 if FormatDesc.MaskMatch(
4798 (QWord(1 shl RedPrec )-1) shl RedShift,
4799 (QWord(1 shl GreenPrec)-1) shl GreenShift,
4800 (QWord(1 shl BluePrec )-1) shl BlueShift,
4801 (QWord(1 shl AlphaPrec)-1) shl AlphaShift) then
4805 if (f = tfEmpty) then
4808 ImageSize := FormatDesc.GetSize(aImage.Width, aImage.Height);
4809 ImageData := GetMem(ImageSize);
4811 Move(aImage.PixelData^, ImageData^, (aImage.Width * aImage.Height * aImage.DataDescription.BitsPerPixel) shr 3);
4812 SetDataPointer(ImageData, f, aImage.Width, aImage.Height); //be careful, Data could be freed by this method
4814 if Assigned(ImageData) then
4822 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4823 function TglBitmap.AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
4825 rid: TRawImageDescription;
4826 FormatDesc: TFormatDescriptor;
4827 Pixel: TglBitmapPixelData;
4833 if not Assigned(aImage) or (Format = tfEmpty) then
4835 FormatDesc := TFormatDescriptor.Get(Format);
4836 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
4839 FillChar(rid{%H-}, SizeOf(rid), 0);
4840 rid.Format := ricfGray;
4842 rid.Height := Height;
4843 rid.Depth := CountSetBits(FormatDesc.Range.a);
4844 rid.BitOrder := riboBitsInOrder;
4845 rid.ByteOrder := riboLSBFirst;
4846 rid.LineOrder := riloTopToBottom;
4847 rid.LineEnd := rileTight;
4848 rid.BitsPerPixel := 8 * Ceil(rid.Depth / 8);
4849 rid.RedPrec := CountSetBits(FormatDesc.Range.a);
4854 rid.GreenShift := 0;
4856 rid.AlphaShift := 0;
4858 rid.MaskBitsPerPixel := 0;
4859 rid.PaletteColorCount := 0;
4861 aImage.DataDescription := rid;
4864 srcMD := FormatDesc.CreateMappingData;
4866 FormatDesc.PreparePixel(Pixel);
4868 dst := aImage.PixelData;
4869 for y := 0 to Height-1 do
4870 for x := 0 to Width-1 do begin
4871 FormatDesc.Unmap(src, Pixel, srcMD);
4872 case rid.BitsPerPixel of
4874 dst^ := Pixel.Data.a;
4878 PWord(dst)^ := Pixel.Data.a;
4882 PByteArray(dst)^[0] := PByteArray(@Pixel.Data.a)^[0];
4883 PByteArray(dst)^[1] := PByteArray(@Pixel.Data.a)^[1];
4884 PByteArray(dst)^[2] := PByteArray(@Pixel.Data.a)^[2];
4888 PCardinal(dst)^ := Pixel.Data.a;
4892 raise EglBitmapUnsupportedFormat.Create(Format);
4896 FormatDesc.FreeMappingData(srcMD);
4901 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4902 function TglBitmap.AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
4906 tex := TglBitmap2D.Create;
4908 tex.AssignFromLazIntfImage(aImage);
4909 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
4916 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4917 function TglBitmap.AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar;
4918 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
4920 rs: TResourceStream;
4922 PrepareResType(aResource, aResType);
4923 rs := TResourceStream.Create(aInstance, aResource, aResType);
4925 result := AddAlphaFromStream(rs, aFunc, aArgs);
4931 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4932 function TglBitmap.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
4933 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
4935 rs: TResourceStream;
4937 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
4939 result := AddAlphaFromStream(rs, aFunc, aArgs);
4945 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4946 function TglBitmap.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
4948 if TFormatDescriptor.Get(Format).IsCompressed then
4949 raise EglBitmapUnsupportedFormat.Create(Format);
4950 result := AddFunc(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs);
4953 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4954 function TglBitmap.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
4958 FS := TFileStream.Create(FileName, fmOpenRead);
4960 result := AddAlphaFromStream(FS, aFunc, aArgs);
4966 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4967 function TglBitmap.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
4971 tex := TglBitmap2D.Create(aStream);
4973 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
4979 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4980 function TglBitmap.AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
4982 DestData, DestData2, SourceData: pByte;
4983 TempHeight, TempWidth: Integer;
4984 SourceFD, DestFD: TFormatDescriptor;
4985 SourceMD, DestMD, DestMD2: Pointer;
4987 FuncRec: TglBitmapFunctionRec;
4991 Assert(Assigned(Data));
4992 Assert(Assigned(aBitmap));
4993 Assert(Assigned(aBitmap.Data));
4995 if ((aBitmap.Width = Width) and (aBitmap.Height = Height)) then begin
4996 result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
4998 SourceFD := TFormatDescriptor.Get(aBitmap.Format);
4999 DestFD := TFormatDescriptor.Get(Format);
5001 if not Assigned(aFunc) then begin
5002 aFunc := glBitmapAlphaFunc;
5003 FuncRec.Args := {%H-}Pointer(SourceFD.HasAlpha);
5005 FuncRec.Args := aArgs;
5008 TempHeight := aBitmap.FileHeight;
5009 TempWidth := aBitmap.FileWidth;
5011 FuncRec.Sender := Self;
5012 FuncRec.Size := Dimension;
5013 FuncRec.Position.Fields := FuncRec.Size.Fields;
5017 SourceData := aBitmap.Data;
5020 SourceFD.PreparePixel(FuncRec.Source);
5021 DestFD.PreparePixel (FuncRec.Dest);
5023 SourceMD := SourceFD.CreateMappingData;
5024 DestMD := DestFD.CreateMappingData;
5025 DestMD2 := DestFD.CreateMappingData;
5027 FuncRec.Position.Y := 0;
5028 while FuncRec.Position.Y < TempHeight do begin
5029 FuncRec.Position.X := 0;
5030 while FuncRec.Position.X < TempWidth do begin
5031 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
5032 DestFD.Unmap (DestData, FuncRec.Dest, DestMD);
5034 DestFD.Map(FuncRec.Dest, DestData2, DestMD2);
5035 inc(FuncRec.Position.X);
5037 inc(FuncRec.Position.Y);
5040 SourceFD.FreeMappingData(SourceMD);
5041 DestFD.FreeMappingData(DestMD);
5042 DestFD.FreeMappingData(DestMD2);
5047 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5048 function TglBitmap.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
5050 result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
5053 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5054 function TglBitmap.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
5056 PixelData: TglBitmapPixelData;
5058 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
5059 result := AddAlphaFromColorKeyFloat(
5060 aRed / PixelData.Range.r,
5061 aGreen / PixelData.Range.g,
5062 aBlue / PixelData.Range.b,
5063 aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b)));
5066 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5067 function TglBitmap.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
5069 values: array[0..2] of Single;
5072 PixelData: TglBitmapPixelData;
5074 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
5075 with PixelData do begin
5077 values[1] := aGreen;
5080 for i := 0 to 2 do begin
5081 tmp := Trunc(Range.arr[i] * aDeviation);
5082 Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp));
5083 Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp));
5088 result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, @PixelData);
5091 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5092 function TglBitmap.AddAlphaFromValue(const aAlpha: Byte): Boolean;
5094 result := AddAlphaFromValueFloat(aAlpha / $FF);
5097 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5098 function TglBitmap.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
5100 PixelData: TglBitmapPixelData;
5102 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
5103 result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
5106 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5107 function TglBitmap.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
5109 PixelData: TglBitmapPixelData;
5111 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
5113 Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
5114 result := AddAlphaFromFunc(glBitmapValueAlphaFunc, @PixelData.Data.a);
5117 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5118 function TglBitmap.RemoveAlpha: Boolean;
5120 FormatDesc: TFormatDescriptor;
5123 FormatDesc := TFormatDescriptor.Get(Format);
5124 if Assigned(Data) then begin
5125 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
5126 raise EglBitmapUnsupportedFormat.Create(Format);
5127 result := ConvertTo(FormatDesc.WithoutAlpha);
5131 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5132 function TglBitmap.Clone: TglBitmap;
5139 Temp := (ClassType.Create as TglBitmap);
5141 // copy texture data if assigned
5142 if Assigned(Data) then begin
5143 Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
5144 GetMem(TempPtr, Size);
5146 Move(Data^, TempPtr^, Size);
5147 Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
5149 if Assigned(TempPtr) then
5155 Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
5160 Temp.fTarget := Target;
5161 Temp.fFormat := Format;
5162 Temp.fMipMap := MipMap;
5163 Temp.fAnisotropic := Anisotropic;
5164 Temp.fBorderColor := fBorderColor;
5165 Temp.fDeleteTextureOnFree := DeleteTextureOnFree;
5166 Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
5167 Temp.fFilterMin := fFilterMin;
5168 Temp.fFilterMag := fFilterMag;
5169 Temp.fWrapS := fWrapS;
5170 Temp.fWrapT := fWrapT;
5171 Temp.fWrapR := fWrapR;
5172 Temp.fFilename := fFilename;
5173 Temp.fCustomName := fCustomName;
5174 Temp.fCustomNameW := fCustomNameW;
5175 Temp.fCustomData := fCustomData;
5184 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5185 function TglBitmap.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
5187 SourceFD, DestFD: TFormatDescriptor;
5188 SourcePD, DestPD: TglBitmapPixelData;
5189 ShiftData: TShiftData;
5191 function CanCopyDirect: Boolean;
5194 ((SourcePD.Range.r = DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
5195 ((SourcePD.Range.g = DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
5196 ((SourcePD.Range.b = DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
5197 ((SourcePD.Range.a = DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
5200 function CanShift: Boolean;
5203 ((SourcePD.Range.r >= DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
5204 ((SourcePD.Range.g >= DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
5205 ((SourcePD.Range.b >= DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
5206 ((SourcePD.Range.a >= DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
5209 function GetShift(aSource, aDest: Cardinal) : ShortInt;
5212 while (aSource > aDest) and (aSource > 0) do begin
5214 aSource := aSource shr 1;
5219 if (aFormat <> fFormat) and (aFormat <> tfEmpty) then begin
5220 SourceFD := TFormatDescriptor.Get(Format);
5221 DestFD := TFormatDescriptor.Get(aFormat);
5223 SourceFD.PreparePixel(SourcePD);
5224 DestFD.PreparePixel (DestPD);
5226 if CanCopyDirect then
5227 result := AddFunc(Self, glBitmapConvertCopyFunc, false, aFormat)
5228 else if CanShift then begin
5229 ShiftData.r := GetShift(SourcePD.Range.r, DestPD.Range.r);
5230 ShiftData.g := GetShift(SourcePD.Range.g, DestPD.Range.g);
5231 ShiftData.b := GetShift(SourcePD.Range.b, DestPD.Range.b);
5232 ShiftData.a := GetShift(SourcePD.Range.a, DestPD.Range.a);
5233 result := AddFunc(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, @ShiftData);
5235 result := AddFunc(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
5240 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5241 procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
5243 if aUseRGB or aUseAlpha then
5244 AddFunc(glBitmapInvertFunc, false, {%H-}Pointer(
5245 ((PtrInt(aUseAlpha) and 1) shl 1) or
5246 (PtrInt(aUseRGB) and 1) ));
5249 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5250 procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
5252 fBorderColor[0] := aRed;
5253 fBorderColor[1] := aGreen;
5254 fBorderColor[2] := aBlue;
5255 fBorderColor[3] := aAlpha;
5256 if (ID > 0) then begin
5258 glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
5262 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5263 procedure TglBitmap.FreeData;
5268 SetDataPointer(TempPtr, tfEmpty); //be careful, Data could be freed by this method
5271 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5272 procedure TglBitmap.FillWithColor(const aRed, aGreen, aBlue: Byte;
5273 const aAlpha: Byte);
5275 FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
5278 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5279 procedure TglBitmap.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
5281 PixelData: TglBitmapPixelData;
5283 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
5285 aRed / PixelData.Range.r,
5286 aGreen / PixelData.Range.g,
5287 aBlue / PixelData.Range.b,
5288 aAlpha / PixelData.Range.a);
5291 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5292 procedure TglBitmap.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
5294 PixelData: TglBitmapPixelData;
5296 TFormatDescriptor.Get(Format).PreparePixel(PixelData);
5297 with PixelData do begin
5298 Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed)));
5299 Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen)));
5300 Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue)));
5301 Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha)));
5303 AddFunc(glBitmapFillWithColorFunc, false, @PixelData);
5306 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5307 procedure TglBitmap.SetFilter(const aMin, aMag: Cardinal);
5312 fFilterMin := GL_NEAREST;
5314 fFilterMin := GL_LINEAR;
5315 GL_NEAREST_MIPMAP_NEAREST:
5316 fFilterMin := GL_NEAREST_MIPMAP_NEAREST;
5317 GL_LINEAR_MIPMAP_NEAREST:
5318 fFilterMin := GL_LINEAR_MIPMAP_NEAREST;
5319 GL_NEAREST_MIPMAP_LINEAR:
5320 fFilterMin := GL_NEAREST_MIPMAP_LINEAR;
5321 GL_LINEAR_MIPMAP_LINEAR:
5322 fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
5324 raise EglBitmapException.Create('SetFilter - Unknow MIN filter.');
5330 fFilterMag := GL_NEAREST;
5332 fFilterMag := GL_LINEAR;
5334 raise EglBitmapException.Create('SetFilter - Unknow MAG filter.');
5338 if (ID > 0) then begin
5340 glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
5342 if (MipMap = mmNone) or (Target = GL_TEXTURE_RECTANGLE) then begin
5344 GL_NEAREST, GL_LINEAR:
5345 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
5346 GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR:
5347 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5348 GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR:
5349 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5352 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
5356 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5357 procedure TglBitmap.SetWrap(const S: Cardinal; const T: Cardinal; const R: Cardinal);
5359 procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
5363 aTarget := GL_CLAMP;
5366 aTarget := GL_REPEAT;
5368 GL_CLAMP_TO_EDGE: begin
5369 if GL_VERSION_1_2 or GL_EXT_texture_edge_clamp then
5370 aTarget := GL_CLAMP_TO_EDGE
5372 aTarget := GL_CLAMP;
5375 GL_CLAMP_TO_BORDER: begin
5376 if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
5377 aTarget := GL_CLAMP_TO_BORDER
5379 aTarget := GL_CLAMP;
5382 GL_MIRRORED_REPEAT: begin
5383 if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
5384 aTarget := GL_MIRRORED_REPEAT
5386 raise EglBitmapException.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
5389 raise EglBitmapException.Create('SetWrap - Unknow Texturewrap (S).');
5394 CheckAndSetWrap(S, fWrapS);
5395 CheckAndSetWrap(T, fWrapT);
5396 CheckAndSetWrap(R, fWrapR);
5398 if (ID > 0) then begin
5400 glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
5401 glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
5402 glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
5406 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5407 procedure TglBitmap.Bind(const aEnableTextureUnit: Boolean);
5409 if aEnableTextureUnit then
5412 glBindTexture(Target, ID);
5415 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5416 procedure TglBitmap.Unbind(const aDisableTextureUnit: Boolean);
5418 if aDisableTextureUnit then
5420 glBindTexture(Target, 0);
5423 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5424 constructor TglBitmap.Create;
5426 if (ClassType = TglBitmap) then
5427 raise EglBitmapException.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
5428 {$IFDEF GLB_NATIVE_OGL}
5429 glbReadOpenGLExtensions;
5434 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5435 constructor TglBitmap.Create(const aFileName: String);
5438 LoadFromFile(FileName);
5441 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5442 constructor TglBitmap.Create(const aStream: TStream);
5445 LoadFromStream(aStream);
5448 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5449 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat);
5455 ImageSize := TFormatDescriptor.Get(aFormat).GetSize(aSize);
5456 GetMem(Image, ImageSize);
5458 FillChar(Image^, ImageSize, #$FF);
5459 SetDataPointer(Image, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
5461 if Assigned(Image) then
5467 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5468 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat;
5469 const aFunc: TglBitmapFunction; const aArgs: Pointer);
5472 LoadFromFunc(aSize, aFunc, aFormat, aArgs);
5475 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5476 constructor TglBitmap.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
5479 LoadFromResource(aInstance, aResource, aResType);
5482 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5483 constructor TglBitmap.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
5486 LoadFromResourceID(aInstance, aResourceID, aResType);
5489 {$IFDEF GLB_SUPPORT_PNG_READ}
5490 {$IF DEFINED(GLB_SDL_IMAGE)}
5491 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5492 //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5493 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5494 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
5496 Surface: PSDL_Surface;
5500 RWops := glBitmapCreateRWops(aStream);
5502 if IMG_isPNG(RWops) > 0 then begin
5503 Surface := IMG_LoadPNG_RW(RWops);
5505 AssignFromSurface(Surface);
5508 SDL_FreeSurface(Surface);
5516 {$ELSEIF DEFINED(GLB_LIB_PNG)}
5517 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5518 procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
5520 TStream(png_get_io_ptr(png)).Read(buffer^, size);
5523 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5524 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
5527 signature: array [0..7] of byte;
5529 png_info: png_infop;
5531 TempHeight, TempWidth: Integer;
5532 Format: TglBitmapFormat;
5535 png_rows: array of pByte;
5536 Row, LineSize: Integer;
5540 if not init_libPNG then
5541 raise Exception.Create('LoadPNG - unable to initialize libPNG.');
5545 StreamPos := aStream.Position;
5546 aStream.Read(signature{%H-}, 8);
5547 aStream.Position := StreamPos;
5549 if png_check_sig(@signature, 8) <> 0 then begin
5551 png := png_create_read_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
5553 raise EglBitmapException.Create('LoadPng - couldn''t create read struct.');
5556 png_info := png_create_info_struct(png);
5557 if png_info = nil then begin
5558 png_destroy_read_struct(@png, nil, nil);
5559 raise EglBitmapException.Create('LoadPng - couldn''t create info struct.');
5562 // set read callback
5563 png_set_read_fn(png, aStream, glBitmap_libPNG_read_func);
5565 // read informations
5566 png_read_info(png, png_info);
5569 TempHeight := png_get_image_height(png, png_info);
5570 TempWidth := png_get_image_width(png, png_info);
5573 case png_get_color_type(png, png_info) of
5574 PNG_COLOR_TYPE_GRAY:
5575 Format := tfLuminance8;
5576 PNG_COLOR_TYPE_GRAY_ALPHA:
5577 Format := tfLuminance8Alpha8;
5580 PNG_COLOR_TYPE_RGB_ALPHA:
5583 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
5586 // cut upper 8 bit from 16 bit formats
5587 if png_get_bit_depth(png, png_info) > 8 then
5588 png_set_strip_16(png);
5590 // expand bitdepth smaller than 8
5591 if png_get_bit_depth(png, png_info) < 8 then
5592 png_set_expand(png);
5594 // allocating mem for scanlines
5595 LineSize := png_get_rowbytes(png, png_info);
5596 GetMem(png_data, TempHeight * LineSize);
5598 SetLength(png_rows, TempHeight);
5599 for Row := Low(png_rows) to High(png_rows) do begin
5600 png_rows[Row] := png_data;
5601 Inc(png_rows[Row], Row * LineSize);
5604 // read complete image into scanlines
5605 png_read_image(png, @png_rows[0]);
5608 png_read_end(png, png_info);
5610 // destroy read struct
5611 png_destroy_read_struct(@png, @png_info, nil);
5613 SetLength(png_rows, 0);
5616 SetDataPointer(png_data, Format, TempWidth, TempHeight); //be careful, Data could be freed by this method
5620 if Assigned(png_data) then
5630 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
5631 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5632 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
5637 Row, Col, PixSize, LineSize: Integer;
5638 NewImage, pSource, pDest, pAlpha: pByte;
5639 PngFormat: TglBitmapFormat;
5640 FormatDesc: TFormatDescriptor;
5643 PngHeader: String[8] = #137#80#78#71#13#10#26#10;
5648 StreamPos := aStream.Position;
5649 aStream.Read(Header[0], SizeOf(Header));
5650 aStream.Position := StreamPos;
5652 {Test if the header matches}
5653 if Header = PngHeader then begin
5654 Png := TPNGObject.Create;
5656 Png.LoadFromStream(aStream);
5658 case Png.Header.ColorType of
5660 PngFormat := tfLuminance8;
5661 COLOR_GRAYSCALEALPHA:
5662 PngFormat := tfLuminance8Alpha8;
5664 PngFormat := tfBGR8;
5666 PngFormat := tfBGRA8;
5668 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
5671 FormatDesc := TFormatDescriptor.Get(PngFormat);
5672 PixSize := Round(FormatDesc.PixelSize);
5673 LineSize := FormatDesc.GetSize(Png.Header.Width, 1);
5675 GetMem(NewImage, LineSize * Integer(Png.Header.Height));
5679 case Png.Header.ColorType of
5680 COLOR_RGB, COLOR_GRAYSCALE:
5682 for Row := 0 to Png.Height -1 do begin
5683 Move (Png.Scanline[Row]^, pDest^, LineSize);
5684 Inc(pDest, LineSize);
5687 COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA:
5689 PixSize := PixSize -1;
5691 for Row := 0 to Png.Height -1 do begin
5692 pSource := Png.Scanline[Row];
5693 pAlpha := pByte(Png.AlphaScanline[Row]);
5695 for Col := 0 to Png.Width -1 do begin
5696 Move (pSource^, pDest^, PixSize);
5697 Inc(pSource, PixSize);
5698 Inc(pDest, PixSize);
5707 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
5710 SetDataPointer(NewImage, PngFormat, Png.Header.Width, Png.Header.Height); //be careful, Data could be freed by this method
5714 if Assigned(NewImage) then
5726 {$IFDEF GLB_SUPPORT_PNG_WRITE}
5727 {$IFDEF GLB_LIB_PNG}
5728 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5729 procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
5731 TStream(png_get_io_ptr(png)).Write(buffer^, size);
5735 {$IF DEFINED(GLB_LIB_PNG)}
5736 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5737 procedure TglBitmap.SavePNG(const aStream: TStream);
5740 png_info: png_infop;
5741 png_rows: array of pByte;
5745 FormatDesc: TFormatDescriptor;
5747 if not (ftPNG in FormatGetSupportedFiles(Format)) then
5748 raise EglBitmapUnsupportedFormat.Create(Format);
5750 if not init_libPNG then
5751 raise Exception.Create('unable to initialize libPNG.');
5755 tfAlpha8, tfLuminance8:
5756 ColorType := PNG_COLOR_TYPE_GRAY;
5758 ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
5760 ColorType := PNG_COLOR_TYPE_RGB;
5762 ColorType := PNG_COLOR_TYPE_RGBA;
5764 raise EglBitmapUnsupportedFormat.Create(Format);
5767 FormatDesc := TFormatDescriptor.Get(Format);
5768 LineSize := FormatDesc.GetSize(Width, 1);
5770 // creating array for scanline
5771 SetLength(png_rows, Height);
5773 for Row := 0 to Height - 1 do begin
5774 png_rows[Row] := Data;
5775 Inc(png_rows[Row], Row * LineSize)
5779 png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
5781 raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
5784 png_info := png_create_info_struct(png);
5785 if png_info = nil then begin
5786 png_destroy_write_struct(@png, nil);
5787 raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
5790 // set read callback
5791 png_set_write_fn(png, aStream, glBitmap_libPNG_write_func, nil);
5794 png_set_compression_level(png, 6);
5796 if Format in [tfBGR8, tfBGRA8] then
5799 png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
5800 png_write_info(png, png_info);
5801 png_write_image(png, @png_rows[0]);
5802 png_write_end(png, png_info);
5803 png_destroy_write_struct(@png, @png_info);
5805 SetLength(png_rows, 0);
5812 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
5813 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5814 procedure TglBitmap.SavePNG(const aStream: TStream);
5818 pSource, pDest: pByte;
5819 X, Y, PixSize: Integer;
5820 ColorType: Cardinal;
5826 if not (ftPNG in FormatGetSupportedFiles (Format)) then
5827 raise EglBitmapUnsupportedFormat.Create(Format);
5830 tfAlpha8, tfLuminance8: begin
5831 ColorType := COLOR_GRAYSCALE;
5835 tfLuminance8Alpha8: begin
5836 ColorType := COLOR_GRAYSCALEALPHA;
5840 tfBGR8, tfRGB8: begin
5841 ColorType := COLOR_RGB;
5845 tfBGRA8, tfRGBA8: begin
5846 ColorType := COLOR_RGBALPHA;
5851 raise EglBitmapUnsupportedFormat.Create(Format);
5854 Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
5858 for Y := 0 to Height -1 do begin
5859 pDest := png.ScanLine[Y];
5860 for X := 0 to Width -1 do begin
5861 Move(pSource^, pDest^, PixSize);
5862 Inc(pDest, PixSize);
5863 Inc(pSource, PixSize);
5865 png.AlphaScanline[Y]^[X] := pSource^;
5870 // convert RGB line to BGR
5871 if Format in [tfRGB8, tfRGBA8] then begin
5872 pTemp := png.ScanLine[Y];
5873 for X := 0 to Width -1 do begin
5874 Temp := pByteArray(pTemp)^[0];
5875 pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
5876 pByteArray(pTemp)^[2] := Temp;
5883 Png.CompressionLevel := 6;
5884 Png.SaveToStream(aStream);
5892 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5893 //JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5894 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5895 {$IFDEF GLB_LIB_JPEG}
5897 glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
5898 glBitmap_libJPEG_source_mgr = record
5899 pub: jpeg_source_mgr;
5902 SrcBuffer: array [1..4096] of byte;
5905 glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
5906 glBitmap_libJPEG_dest_mgr = record
5907 pub: jpeg_destination_mgr;
5909 DestStream: TStream;
5910 DestBuffer: array [1..4096] of byte;
5913 procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
5919 procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
5925 procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
5930 procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
5936 procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
5942 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5943 function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
5945 src: glBitmap_libJPEG_source_mgr_ptr;
5948 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
5950 bytes := src^.SrcStream.Read(src^.SrcBuffer[1], 4096);
5951 if (bytes <= 0) then begin
5952 src^.SrcBuffer[1] := $FF;
5953 src^.SrcBuffer[2] := JPEG_EOI;
5957 src^.pub.next_input_byte := @(src^.SrcBuffer[1]);
5958 src^.pub.bytes_in_buffer := bytes;
5963 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5964 procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
5966 src: glBitmap_libJPEG_source_mgr_ptr;
5968 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
5970 if num_bytes > 0 then begin
5971 // wanted byte isn't in buffer so set stream position and read buffer
5972 if num_bytes > src^.pub.bytes_in_buffer then begin
5973 src^.SrcStream.Position := src^.SrcStream.Position + num_bytes - src^.pub.bytes_in_buffer;
5974 src^.pub.fill_input_buffer(cinfo);
5976 // wanted byte is in buffer so only skip
5977 inc(src^.pub.next_input_byte, num_bytes);
5978 dec(src^.pub.bytes_in_buffer, num_bytes);
5983 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5984 function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
5986 dest: glBitmap_libJPEG_dest_mgr_ptr;
5988 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
5990 if dest^.pub.free_in_buffer < Cardinal(Length(dest^.DestBuffer)) then begin
5991 // write complete buffer
5992 dest^.DestStream.Write(dest^.DestBuffer[1], SizeOf(dest^.DestBuffer));
5995 dest^.pub.next_output_byte := @dest^.DestBuffer[1];
5996 dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
6002 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6003 procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
6006 dest: glBitmap_libJPEG_dest_mgr_ptr;
6008 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
6010 for Idx := Low(dest^.DestBuffer) to High(dest^.DestBuffer) do begin
6011 // check for endblock
6012 if (Idx < High(dest^.DestBuffer)) and (dest^.DestBuffer[Idx] = $FF) and (dest^.DestBuffer[Idx +1] = JPEG_EOI) then begin
6014 dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
6019 dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
6024 {$IFDEF GLB_SUPPORT_JPEG_READ}
6025 {$IF DEFINED(GLB_SDL_IMAGE)}
6026 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6027 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6029 Surface: PSDL_Surface;
6034 RWops := glBitmapCreateRWops(aStream);
6036 if IMG_isJPG(RWops) > 0 then begin
6037 Surface := IMG_LoadJPG_RW(RWops);
6039 AssignFromSurface(Surface);
6042 SDL_FreeSurface(Surface);
6050 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
6051 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6052 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6055 Temp: array[0..1]of Byte;
6057 jpeg: jpeg_decompress_struct;
6058 jpeg_err: jpeg_error_mgr;
6060 IntFormat: TglBitmapFormat;
6062 TempHeight, TempWidth: Integer;
6067 FormatDesc: TFormatDescriptor;
6071 if not init_libJPEG then
6072 raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
6075 // reading first two bytes to test file and set cursor back to begin
6076 StreamPos := aStream.Position;
6077 aStream.Read({%H-}Temp[0], 2);
6078 aStream.Position := StreamPos;
6080 // if Bitmap then read file.
6081 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
6082 FillChar(jpeg{%H-}, SizeOf(jpeg_decompress_struct), $00);
6083 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
6086 jpeg.err := jpeg_std_error(@jpeg_err);
6087 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
6088 jpeg_err.output_message := glBitmap_libJPEG_output_message;
6090 // decompression struct
6091 jpeg_create_decompress(@jpeg);
6093 // allocation space for streaming methods
6094 jpeg.src := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_source_mgr));
6096 // seeting up custom functions
6097 with glBitmap_libJPEG_source_mgr_ptr(jpeg.src)^ do begin
6098 pub.init_source := glBitmap_libJPEG_init_source;
6099 pub.fill_input_buffer := glBitmap_libJPEG_fill_input_buffer;
6100 pub.skip_input_data := glBitmap_libJPEG_skip_input_data;
6101 pub.resync_to_restart := jpeg_resync_to_restart; // use default method
6102 pub.term_source := glBitmap_libJPEG_term_source;
6104 pub.bytes_in_buffer := 0; // forces fill_input_buffer on first read
6105 pub.next_input_byte := nil; // until buffer loaded
6107 SrcStream := aStream;
6110 // set global decoding state
6111 jpeg.global_state := DSTATE_START;
6113 // read header of jpeg
6114 jpeg_read_header(@jpeg, false);
6116 // setting output parameter
6117 case jpeg.jpeg_color_space of
6120 jpeg.out_color_space := JCS_GRAYSCALE;
6121 IntFormat := tfLuminance8;
6124 jpeg.out_color_space := JCS_RGB;
6125 IntFormat := tfRGB8;
6129 jpeg_start_decompress(@jpeg);
6131 TempHeight := jpeg.output_height;
6132 TempWidth := jpeg.output_width;
6134 FormatDesc := TFormatDescriptor.Get(IntFormat);
6136 // creating new image
6137 GetMem(pImage, FormatDesc.GetSize(TempWidth, TempHeight));
6141 for Row := 0 to TempHeight -1 do begin
6142 jpeg_read_scanlines(@jpeg, @pTemp, 1);
6143 Inc(pTemp, FormatDesc.GetSize(TempWidth, 1));
6146 // finish decompression
6147 jpeg_finish_decompress(@jpeg);
6149 // destroy decompression
6150 jpeg_destroy_decompress(@jpeg);
6152 SetDataPointer(pImage, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
6156 if Assigned(pImage) then
6166 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
6167 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6168 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6173 Temp: array[0..1]of Byte;
6177 // reading first two bytes to test file and set cursor back to begin
6178 StreamPos := aStream.Position;
6179 aStream.Read(Temp[0], 2);
6180 aStream.Position := StreamPos;
6182 // if Bitmap then read file.
6183 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
6184 bmp := TBitmap.Create;
6186 jpg := TJPEGImage.Create;
6188 jpg.LoadFromStream(aStream);
6190 result := AssignFromBitmap(bmp);
6202 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
6203 {$IF DEFINED(GLB_LIB_JPEG)}
6204 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6205 procedure TglBitmap.SaveJPEG(const aStream: TStream);
6207 jpeg: jpeg_compress_struct;
6208 jpeg_err: jpeg_error_mgr;
6210 pTemp, pTemp2: pByte;
6212 procedure CopyRow(pDest, pSource: pByte);
6216 for X := 0 to Width - 1 do begin
6217 pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
6218 pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
6219 pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
6226 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
6227 raise EglBitmapUnsupportedFormat.Create(Format);
6229 if not init_libJPEG then
6230 raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
6233 FillChar(jpeg{%H-}, SizeOf(jpeg_compress_struct), $00);
6234 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
6237 jpeg.err := jpeg_std_error(@jpeg_err);
6238 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
6239 jpeg_err.output_message := glBitmap_libJPEG_output_message;
6241 // compression struct
6242 jpeg_create_compress(@jpeg);
6244 // allocation space for streaming methods
6245 jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
6247 // seeting up custom functions
6248 with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
6249 pub.init_destination := glBitmap_libJPEG_init_destination;
6250 pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
6251 pub.term_destination := glBitmap_libJPEG_term_destination;
6253 pub.next_output_byte := @DestBuffer[1];
6254 pub.free_in_buffer := Length(DestBuffer);
6256 DestStream := aStream;
6259 // very important state
6260 jpeg.global_state := CSTATE_START;
6261 jpeg.image_width := Width;
6262 jpeg.image_height := Height;
6264 tfAlpha8, tfLuminance8: begin
6265 jpeg.input_components := 1;
6266 jpeg.in_color_space := JCS_GRAYSCALE;
6268 tfRGB8, tfBGR8: begin
6269 jpeg.input_components := 3;
6270 jpeg.in_color_space := JCS_RGB;
6274 jpeg_set_defaults(@jpeg);
6275 jpeg_set_quality(@jpeg, 95, true);
6276 jpeg_start_compress(@jpeg, true);
6279 if Format = tfBGR8 then
6280 GetMem(pTemp2, fRowSize)
6285 for Row := 0 to jpeg.image_height -1 do begin
6287 if Format = tfBGR8 then
6288 CopyRow(pTemp2, pTemp)
6293 jpeg_write_scanlines(@jpeg, @pTemp2, 1);
6294 inc(pTemp, fRowSize);
6298 if Format = tfBGR8 then
6301 jpeg_finish_compress(@jpeg);
6302 jpeg_destroy_compress(@jpeg);
6308 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
6309 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6310 procedure TglBitmap.SaveJPEG(const aStream: TStream);
6315 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
6316 raise EglBitmapUnsupportedFormat.Create(Format);
6318 Bmp := TBitmap.Create;
6320 Jpg := TJPEGImage.Create;
6322 AssignToBitmap(Bmp);
6323 if (Format in [tfAlpha8, tfLuminance8]) then begin
6324 Jpg.Grayscale := true;
6325 Jpg.PixelFormat := jf8Bit;
6328 Jpg.SaveToStream(aStream);
6339 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6340 //BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6341 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6348 BMP_COMP_BITFIELDS = 3;
6351 TBMPHeader = packed record
6356 bfOffBits: Cardinal;
6359 TBMPInfo = packed record
6365 biCompression: Cardinal;
6366 biSizeImage: Cardinal;
6367 biXPelsPerMeter: Longint;
6368 biYPelsPerMeter: Longint;
6369 biClrUsed: Cardinal;
6370 biClrImportant: Cardinal;
6373 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6374 function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
6376 //////////////////////////////////////////////////////////////////////////////////////////////////
6377 function ReadInfo(out aInfo: TBMPInfo; out aMask: TglBitmapColorRec): TglBitmapFormat;
6380 aStream.Read(aInfo{%H-}, SizeOf(aInfo));
6381 FillChar(aMask{%H-}, SizeOf(aMask), 0);
6384 case aInfo.biCompression of
6386 BMP_COMP_RLE8: begin
6387 raise EglBitmapException.Create('RLE compression is not supported');
6389 BMP_COMP_BITFIELDS: begin
6390 if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
6391 aStream.Read(aMask.r, SizeOf(aMask.r));
6392 aStream.Read(aMask.g, SizeOf(aMask.g));
6393 aStream.Read(aMask.b, SizeOf(aMask.b));
6394 aStream.Read(aMask.a, SizeOf(aMask.a));
6396 raise EglBitmapException.Create('Bitfields are only supported for 16bit and 32bit formats');
6400 //get suitable format
6401 case aInfo.biBitCount of
6402 8: result := tfLuminance8;
6403 16: result := tfBGR5;
6404 24: result := tfBGR8;
6405 32: result := tfBGRA8;
6409 function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TbmpColorTableFormat;
6412 ColorTable: TbmpColorTable;
6415 if (aInfo.biBitCount >= 16) then
6417 aFormat := tfLuminance8;
6418 c := aInfo.biClrUsed;
6420 c := 1 shl aInfo.biBitCount;
6421 SetLength(ColorTable, c);
6422 for i := 0 to c-1 do begin
6423 aStream.Read(ColorTable[i], SizeOf(TbmpColorTableEnty));
6424 if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then
6428 result := TbmpColorTableFormat.Create;
6429 result.PixelSize := aInfo.biBitCount / 8;
6430 result.ColorTable := ColorTable;
6431 result.Range := glBitmapColorRec($FF, $FF, $FF, $00);
6434 //////////////////////////////////////////////////////////////////////////////////////////////////
6435 function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapColorRec;
6436 const aInfo: TBMPInfo): TbmpBitfieldFormat;
6438 TmpFormat: TglBitmapFormat;
6439 FormatDesc: TFormatDescriptor;
6442 if (aMask.r <> 0) or (aMask.g <> 0) or (aMask.b <> 0) or (aMask.a <> 0) then begin
6443 for TmpFormat := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
6444 FormatDesc := TFormatDescriptor.Get(TmpFormat);
6445 if FormatDesc.MaskMatch(aMask.r, aMask.g, aMask.b, aMask.a) then begin
6446 aFormat := FormatDesc.Format;
6451 if (aMask.a = 0) and TFormatDescriptor.Get(aFormat).HasAlpha then
6452 aFormat := TFormatDescriptor.Get(aFormat).WithoutAlpha;
6453 if (aMask.a <> 0) and not TFormatDescriptor.Get(aFormat).HasAlpha then
6454 aFormat := TFormatDescriptor.Get(aFormat).WithAlpha;
6456 result := TbmpBitfieldFormat.Create;
6457 result.PixelSize := aInfo.biBitCount / 8;
6458 result.RedMask := aMask.r;
6459 result.GreenMask := aMask.g;
6460 result.BlueMask := aMask.b;
6461 result.AlphaMask := aMask.a;
6468 ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
6469 PaddingBuff: Cardinal;
6470 LineBuf, ImageData, TmpData: PByte;
6471 SourceMD, DestMD: Pointer;
6472 BmpFormat: TglBitmapFormat;
6475 Mask: TglBitmapColorRec;
6480 SpecialFormat: TFormatDescriptor;
6481 FormatDesc: TFormatDescriptor;
6483 //////////////////////////////////////////////////////////////////////////////////////////////////
6484 procedure SpecialFormatReadLine(aData: PByte; aLineBuf: PByte);
6487 Pixel: TglBitmapPixelData;
6489 aStream.Read(aLineBuf^, rbLineSize);
6490 SpecialFormat.PreparePixel(Pixel);
6491 for i := 0 to Info.biWidth-1 do begin
6492 SpecialFormat.Unmap(aLineBuf, Pixel, SourceMD);
6493 glBitmapConvertPixel(Pixel, SpecialFormat, FormatDesc);
6494 FormatDesc.Map(Pixel, aData, DestMD);
6500 BmpFormat := tfEmpty;
6501 SpecialFormat := nil;
6507 StartPos := aStream.Position;
6508 aStream.Read(Header{%H-}, SizeOf(Header));
6510 if Header.bfType = BMP_MAGIC then begin
6512 BmpFormat := ReadInfo(Info, Mask);
6513 SpecialFormat := ReadColorTable(BmpFormat, Info);
6514 if not Assigned(SpecialFormat) then
6515 SpecialFormat := CheckBitfields(BmpFormat, Mask, Info);
6516 aStream.Position := StartPos + Header.bfOffBits;
6518 if (BmpFormat <> tfEmpty) then begin
6519 FormatDesc := TFormatDescriptor.Get(BmpFormat);
6520 rbLineSize := Round(Info.biWidth * Info.biBitCount / 8); //ReadBuffer LineSize
6521 wbLineSize := Trunc(Info.biWidth * FormatDesc.PixelSize);
6522 Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
6525 DestMD := FormatDesc.CreateMappingData;
6526 ImageSize := FormatDesc.GetSize(Info.biWidth, abs(Info.biHeight));
6527 GetMem(ImageData, ImageSize);
6528 if Assigned(SpecialFormat) then begin
6529 GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
6530 SourceMD := SpecialFormat.CreateMappingData;
6535 FillChar(ImageData^, ImageSize, $FF);
6536 TmpData := ImageData;
6537 if (Info.biHeight > 0) then
6538 Inc(TmpData, wbLineSize * (Info.biHeight-1));
6539 for i := 0 to Abs(Info.biHeight)-1 do begin
6540 if Assigned(SpecialFormat) then
6541 SpecialFormatReadLine(TmpData, LineBuf) //if is special format read and convert data
6543 aStream.Read(TmpData^, wbLineSize); //else only read data
6544 if (Info.biHeight > 0) then
6545 dec(TmpData, wbLineSize)
6547 inc(TmpData, wbLineSize);
6548 aStream.Read(PaddingBuff{%H-}, Padding);
6550 SetDataPointer(ImageData, BmpFormat, Info.biWidth, abs(Info.biHeight)); //be careful, Data could be freed by this method
6553 if Assigned(LineBuf) then
6555 if Assigned(SourceMD) then
6556 SpecialFormat.FreeMappingData(SourceMD);
6557 FormatDesc.FreeMappingData(DestMD);
6560 if Assigned(ImageData) then
6565 raise EglBitmapException.Create('LoadBMP - No suitable format found');
6567 aStream.Position := StartPos;
6571 FreeAndNil(SpecialFormat);
6574 else aStream.Position := StartPos;
6577 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6578 procedure TglBitmap.SaveBMP(const aStream: TStream);
6582 Converter: TbmpColorTableFormat;
6583 FormatDesc: TFormatDescriptor;
6584 SourceFD, DestFD: Pointer;
6585 pData, srcData, dstData, ConvertBuffer: pByte;
6587 Pixel: TglBitmapPixelData;
6588 ImageSize, wbLineSize, rbLineSize, Padding, LineIdx, PixelIdx: Integer;
6589 RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
6591 PaddingBuff: Cardinal;
6593 function GetLineWidth : Integer;
6595 result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
6599 if not (ftBMP in FormatGetSupportedFiles(Format)) then
6600 raise EglBitmapUnsupportedFormat.Create(Format);
6603 FormatDesc := TFormatDescriptor.Get(Format);
6604 ImageSize := FormatDesc.GetSize(Dimension);
6606 FillChar(Header{%H-}, SizeOf(Header), 0);
6607 Header.bfType := BMP_MAGIC;
6608 Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
6609 Header.bfReserved1 := 0;
6610 Header.bfReserved2 := 0;
6611 Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
6613 FillChar(Info{%H-}, SizeOf(Info), 0);
6614 Info.biSize := SizeOf(Info);
6615 Info.biWidth := Width;
6616 Info.biHeight := Height;
6618 Info.biCompression := BMP_COMP_RGB;
6619 Info.biSizeImage := ImageSize;
6624 Info.biBitCount := 4;
6625 Header.bfSize := Header.bfSize + 16 * SizeOf(Cardinal);
6626 Header.bfOffBits := Header.bfOffBits + 16 * SizeOf(Cardinal); //16 ColorTable entries
6627 Converter := TbmpColorTableFormat.Create;
6628 Converter.PixelSize := 0.5;
6629 Converter.Format := Format;
6630 Converter.Range := glBitmapColorRec($F, $F, $F, $0);
6631 Converter.CreateColorTable;
6634 tfR3G3B2, tfLuminance8: begin
6635 Info.biBitCount := 8;
6636 Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
6637 Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal); //256 ColorTable entries
6638 Converter := TbmpColorTableFormat.Create;
6639 Converter.PixelSize := 1;
6640 Converter.Format := Format;
6641 if (Format = tfR3G3B2) then begin
6642 Converter.Range := glBitmapColorRec($7, $7, $3, $0);
6643 Converter.Shift := glBitmapShiftRec(0, 3, 6, 0);
6645 Converter.Range := glBitmapColorRec($FF, $FF, $FF, $0);
6646 Converter.CreateColorTable;
6649 tfRGB4, tfRGB5, tfR5G6B5, tfRGB5A1, tfRGBA4,
6650 tfBGR4, tfBGR5, tfB5G6R5, tfBGR5A1, tfBGRA4: begin
6651 Info.biBitCount := 16;
6652 Info.biCompression := BMP_COMP_BITFIELDS;
6655 tfBGR8, tfRGB8: begin
6656 Info.biBitCount := 24;
6659 tfRGB10, tfRGB10A2, tfRGBA8,
6660 tfBGR10, tfBGR10A2, tfBGRA8: begin
6661 Info.biBitCount := 32;
6662 Info.biCompression := BMP_COMP_BITFIELDS;
6665 raise EglBitmapUnsupportedFormat.Create(Format);
6667 Info.biXPelsPerMeter := 2835;
6668 Info.biYPelsPerMeter := 2835;
6671 if Info.biCompression = BMP_COMP_BITFIELDS then begin
6672 Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
6673 Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
6675 RedMask := FormatDesc.RedMask;
6676 GreenMask := FormatDesc.GreenMask;
6677 BlueMask := FormatDesc.BlueMask;
6678 AlphaMask := FormatDesc.AlphaMask;
6682 aStream.Write(Header, SizeOf(Header));
6683 aStream.Write(Info, SizeOf(Info));
6686 if Assigned(Converter) then
6687 aStream.Write(Converter.ColorTable[0].b,
6688 SizeOf(TbmpColorTableEnty) * Length(Converter.ColorTable));
6691 if Info.biCompression = BMP_COMP_BITFIELDS then begin
6692 aStream.Write(RedMask, SizeOf(Cardinal));
6693 aStream.Write(GreenMask, SizeOf(Cardinal));
6694 aStream.Write(BlueMask, SizeOf(Cardinal));
6695 aStream.Write(AlphaMask, SizeOf(Cardinal));
6699 rbLineSize := Round(Info.biWidth * FormatDesc.PixelSize);
6700 wbLineSize := Round(Info.biWidth * Info.biBitCount / 8);
6701 Padding := GetLineWidth - wbLineSize;
6705 inc(pData, (Height-1) * rbLineSize);
6707 // prepare row buffer. But only for RGB because RGBA supports color masks
6708 // so it's possible to change color within the image.
6709 if Assigned(Converter) then begin
6710 FormatDesc.PreparePixel(Pixel);
6711 GetMem(ConvertBuffer, wbLineSize);
6712 SourceFD := FormatDesc.CreateMappingData;
6713 DestFD := Converter.CreateMappingData;
6715 ConvertBuffer := nil;
6718 for LineIdx := 0 to Height - 1 do begin
6720 if Assigned(Converter) then begin
6722 dstData := ConvertBuffer;
6723 for PixelIdx := 0 to Info.biWidth-1 do begin
6724 FormatDesc.Unmap(srcData, Pixel, SourceFD);
6725 glBitmapConvertPixel(Pixel, FormatDesc, Converter);
6726 Converter.Map(Pixel, dstData, DestFD);
6728 aStream.Write(ConvertBuffer^, wbLineSize);
6730 aStream.Write(pData^, rbLineSize);
6732 dec(pData, rbLineSize);
6733 if (Padding > 0) then
6734 aStream.Write(PaddingBuff, Padding);
6737 // destroy row buffer
6738 if Assigned(ConvertBuffer) then begin
6739 FormatDesc.FreeMappingData(SourceFD);
6740 Converter.FreeMappingData(DestFD);
6741 FreeMem(ConvertBuffer);
6745 if Assigned(Converter) then
6750 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6751 //TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6752 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6754 TTGAHeader = packed record
6758 //ColorMapSpec: Array[0..4] of Byte;
6759 ColorMapStart: Word;
6760 ColorMapLength: Word;
6761 ColorMapEntrySize: Byte;
6771 TGA_UNCOMPRESSED_RGB = 2;
6772 TGA_UNCOMPRESSED_GRAY = 3;
6773 TGA_COMPRESSED_RGB = 10;
6774 TGA_COMPRESSED_GRAY = 11;
6776 TGA_NONE_COLOR_TABLE = 0;
6778 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6779 function TglBitmap.LoadTGA(const aStream: TStream): Boolean;
6782 ImageData: System.PByte;
6783 StartPosition: Int64;
6784 PixelSize, LineSize: Integer;
6785 tgaFormat: TglBitmapFormat;
6786 FormatDesc: TFormatDescriptor;
6787 Counter: packed record
6789 low, high, dir: Integer;
6796 ////////////////////////////////////////////////////////////////////////////////////////
6797 procedure ReadUncompressed;
6800 buf, tmp1, tmp2: System.PByte;
6803 if (Counter.X.dir < 0) then
6804 GetMem(buf, LineSize);
6806 while (Counter.Y.low <> Counter.Y.high + counter.Y.dir) do begin
6808 inc(tmp1, (Counter.Y.low * LineSize)); //pointer to LineStart
6809 if (Counter.X.dir < 0) then begin //flip X
6810 aStream.Read(buf^, LineSize);
6812 inc(tmp2, LineSize - PixelSize); //pointer to last pixel in line
6813 for i := 0 to Header.Width-1 do begin //for all pixels in line
6814 for j := 0 to PixelSize-1 do begin //for all bytes in pixel
6819 dec(tmp2, 2*PixelSize); //move 2 backwards, because j-loop moved 1 forward
6822 aStream.Read(tmp1^, LineSize);
6823 inc(Counter.Y.low, Counter.Y.dir); //move to next line index
6826 if Assigned(buf) then
6831 ////////////////////////////////////////////////////////////////////////////////////////
6832 procedure ReadCompressed;
6834 /////////////////////////////////////////////////////////////////
6836 TmpData: System.PByte;
6837 LinePixelsRead: Integer;
6838 procedure CheckLine;
6840 if (LinePixelsRead >= Header.Width) then begin
6841 LinePixelsRead := 0;
6842 inc(Counter.Y.low, Counter.Y.dir); //next line index
6843 TmpData := ImageData;
6844 inc(TmpData, Counter.Y.low * LineSize); //set line
6845 if (Counter.X.dir < 0) then //if x flipped then
6846 inc(TmpData, LineSize - PixelSize); //set last pixel
6850 /////////////////////////////////////////////////////////////////
6853 CacheSize, CachePos: Integer;
6854 procedure CachedRead(out Buffer; Count: Integer);
6858 if (CachePos + Count > CacheSize) then begin
6859 //if buffer overflow save non read bytes
6861 if (CacheSize - CachePos > 0) then begin
6862 BytesRead := CacheSize - CachePos;
6863 Move(PByteArray(Cache)^[CachePos], Buffer{%H-}, BytesRead);
6864 inc(CachePos, BytesRead);
6867 //load cache from file
6868 CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
6869 aStream.Read(Cache^, CacheSize);
6872 //read rest of requested bytes
6873 if (Count - BytesRead > 0) then begin
6874 Move(PByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
6875 inc(CachePos, Count - BytesRead);
6878 //if no buffer overflow just read the data
6879 Move(PByteArray(Cache)^[CachePos], Buffer, Count);
6880 inc(CachePos, Count);
6884 procedure PixelToBuffer(const aData: PByte; var aBuffer: PByte);
6889 inc(aBuffer, Counter.X.dir);
6892 PWord(aBuffer)^ := PWord(aData)^;
6893 inc(aBuffer, 2 * Counter.X.dir);
6896 PByteArray(aBuffer)^[0] := PByteArray(aData)^[0];
6897 PByteArray(aBuffer)^[1] := PByteArray(aData)^[1];
6898 PByteArray(aBuffer)^[2] := PByteArray(aData)^[2];
6899 inc(aBuffer, 3 * Counter.X.dir);
6902 PCardinal(aBuffer)^ := PCardinal(aData)^;
6903 inc(aBuffer, 4 * Counter.X.dir);
6909 TotalPixelsToRead, TotalPixelsRead: Integer;
6911 buf: array [0..3] of Byte; //1 pixel is max 32bit long
6912 PixelRepeat: Boolean;
6913 PixelsToRead, PixelCount: Integer;
6918 TotalPixelsToRead := Header.Width * Header.Height;
6919 TotalPixelsRead := 0;
6920 LinePixelsRead := 0;
6922 GetMem(Cache, CACHE_SIZE);
6924 TmpData := ImageData;
6925 inc(TmpData, Counter.Y.low * LineSize); //set line
6926 if (Counter.X.dir < 0) then //if x flipped then
6927 inc(TmpData, LineSize - PixelSize); //set last pixel
6931 CachedRead(Temp, 1);
6932 PixelRepeat := (Temp and $80) > 0;
6933 PixelsToRead := (Temp and $7F) + 1;
6934 inc(TotalPixelsRead, PixelsToRead);
6937 CachedRead(buf[0], PixelSize);
6938 while (PixelsToRead > 0) do begin
6940 PixelCount := Min(Header.Width - LinePixelsRead, PixelsToRead); //max read to EOL or EOF
6941 while (PixelCount > 0) do begin
6942 if not PixelRepeat then
6943 CachedRead(buf[0], PixelSize);
6944 PixelToBuffer(@buf[0], TmpData);
6945 inc(LinePixelsRead);
6950 until (TotalPixelsRead >= TotalPixelsToRead);
6956 function IsGrayFormat: Boolean;
6958 result := Header.ImageType in [TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_GRAY];
6964 // reading header to test file and set cursor back to begin
6965 StartPosition := aStream.Position;
6966 aStream.Read(Header{%H-}, SizeOf(Header));
6968 // no colormapped files
6969 if (Header.ColorMapType = TGA_NONE_COLOR_TABLE) and (Header.ImageType in [
6970 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY]) then
6973 if Header.ImageID <> 0 then // skip image ID
6974 aStream.Position := aStream.Position + Header.ImageID;
6976 tgaFormat := tfEmpty;
6978 8: if IsGrayFormat then case (Header.ImageDesc and $F) of
6979 0: tgaFormat := tfLuminance8;
6980 8: tgaFormat := tfAlpha8;
6983 16: if IsGrayFormat then case (Header.ImageDesc and $F) of
6984 0: tgaFormat := tfLuminance16;
6985 8: tgaFormat := tfLuminance8Alpha8;
6986 end else case (Header.ImageDesc and $F) of
6987 0: tgaFormat := tfBGR5;
6988 1: tgaFormat := tfBGR5A1;
6989 4: tgaFormat := tfBGRA4;
6992 24: if not IsGrayFormat then case (Header.ImageDesc and $F) of
6993 0: tgaFormat := tfBGR8;
6996 32: if not IsGrayFormat then case (Header.ImageDesc and $F) of
6997 2: tgaFormat := tfBGR10A2;
6998 8: tgaFormat := tfBGRA8;
7002 if (tgaFormat = tfEmpty) then
7003 raise EglBitmapException.Create('LoadTga - unsupported format');
7005 FormatDesc := TFormatDescriptor.Get(tgaFormat);
7006 PixelSize := FormatDesc.GetSize(1, 1);
7007 LineSize := FormatDesc.GetSize(Header.Width, 1);
7009 GetMem(ImageData, LineSize * Header.Height);
7012 if ((Header.ImageDesc and (1 shl 4)) > 0) then begin
7013 Counter.X.low := Header.Height-1;;
7014 Counter.X.high := 0;
7015 Counter.X.dir := -1;
7018 Counter.X.high := Header.Height-1;
7023 if ((Header.ImageDesc and (1 shl 5)) > 0) then begin
7025 Counter.Y.high := Header.Height-1;
7028 Counter.Y.low := Header.Height-1;;
7029 Counter.Y.high := 0;
7030 Counter.Y.dir := -1;
7034 case Header.ImageType of
7035 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY:
7037 TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY:
7041 SetDataPointer(ImageData, tgaFormat, Header.Width, Header.Height); //be careful, Data could be freed by this method
7044 if Assigned(ImageData) then
7049 aStream.Position := StartPosition;
7052 else aStream.Position := StartPosition;
7055 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7056 procedure TglBitmap.SaveTGA(const aStream: TStream);
7059 LineSize, Size, x, y: Integer;
7060 Pixel: TglBitmapPixelData;
7061 LineBuf, SourceData, DestData: PByte;
7062 SourceMD, DestMD: Pointer;
7063 FormatDesc: TFormatDescriptor;
7064 Converter: TFormatDescriptor;
7066 if not (ftTGA in FormatGetSupportedFiles(Format)) then
7067 raise EglBitmapUnsupportedFormat.Create(Format);
7070 FillChar(Header{%H-}, SizeOf(Header), 0);
7073 if (Format in [tfLuminance8, tfLuminance6Alpha2, tfLuminance4Alpha4, tfAlpha8,
7074 tfLuminance16, tfLuminance12Alpha4, tfLuminance8Alpha8]) then
7075 Header.ImageType := TGA_UNCOMPRESSED_GRAY
7077 Header.ImageType := TGA_UNCOMPRESSED_RGB;
7080 if (Format in [tfLuminance8, tfLuminance6Alpha2, tfLuminance4Alpha4, tfAlpha8]) then
7082 else if (Format in [tfLuminance16, tfLuminance12Alpha4, tfLuminance8Alpha8,
7083 tfRGB5, tfBGR5, tfRGB5A1, tfBGR5A1, tfRGBA4, tfBGRA4]) then
7085 else if (Format in [tfBGR8, tfRGB8]) then
7093 Header.ImageDesc := 1 and $F;
7094 tfRGB10A2, tfBGR10A2:
7095 Header.ImageDesc := 2 and $F;
7097 Header.ImageDesc := 4 and $F;
7098 tfAlpha8, tfLuminance8Alpha8, tfRGBA8, tfBGRA8:
7099 Header.ImageDesc := 8 and $F;
7102 Header.Width := Width;
7103 Header.Height := Height;
7104 Header.ImageDesc := Header.ImageDesc or $20; //flip y
7105 aStream.Write(Header, SizeOf(Header));
7107 // convert RGB(A) to BGR(A)
7109 FormatDesc := TFormatDescriptor.Get(Format);
7110 Size := FormatDesc.GetSize(Dimension);
7111 if Format in [tfRGB5, tfRGB5A1, tfRGBA4, tfRGB8, tfRGB10A2, tfRGBA8] then begin
7112 if (FormatDesc.RGBInverted = tfEmpty) then
7113 raise EglBitmapException.Create('inverted RGB format is empty');
7114 Converter := TFormatDescriptor.Get(FormatDesc.RGBInverted);
7115 if not glBitmapColorRecCmp(Converter.Range, FormatDesc.Range) or
7116 (Converter.PixelSize <> FormatDesc.PixelSize) then
7117 raise EglBitmapException.Create('invalid inverted RGB format');
7120 if Assigned(Converter) then begin
7121 LineSize := FormatDesc.GetSize(Width, 1);
7122 GetMem(LineBuf, LineSize);
7123 SourceMD := FormatDesc.CreateMappingData;
7124 DestMD := Converter.CreateMappingData;
7127 for y := 0 to Height-1 do begin
7128 DestData := LineBuf;
7129 for x := 0 to Width-1 do begin
7130 FormatDesc.Unmap(SourceData, Pixel, SourceMD);
7131 Converter.Map(Pixel, DestData, DestMD);
7133 aStream.Write(LineBuf^, LineSize);
7137 FormatDesc.FreeMappingData(SourceMD);
7138 FormatDesc.FreeMappingData(DestMD);
7141 aStream.Write(Data^, Size);
7144 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7145 //DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7146 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7148 DDS_MAGIC: Cardinal = $20534444;
7150 // DDS_header.dwFlags
7151 DDSD_CAPS = $00000001;
7152 DDSD_HEIGHT = $00000002;
7153 DDSD_WIDTH = $00000004;
7154 DDSD_PIXELFORMAT = $00001000;
7156 // DDS_header.sPixelFormat.dwFlags
7157 DDPF_ALPHAPIXELS = $00000001;
7158 DDPF_ALPHA = $00000002;
7159 DDPF_FOURCC = $00000004;
7160 DDPF_RGB = $00000040;
7161 DDPF_LUMINANCE = $00020000;
7163 // DDS_header.sCaps.dwCaps1
7164 DDSCAPS_TEXTURE = $00001000;
7166 // DDS_header.sCaps.dwCaps2
7167 DDSCAPS2_CUBEMAP = $00000200;
7169 D3DFMT_DXT1 = $31545844;
7170 D3DFMT_DXT3 = $33545844;
7171 D3DFMT_DXT5 = $35545844;
7174 TDDSPixelFormat = packed record
7178 dwRGBBitCount: Cardinal;
7179 dwRBitMask: Cardinal;
7180 dwGBitMask: Cardinal;
7181 dwBBitMask: Cardinal;
7182 dwABitMask: Cardinal;
7185 TDDSCaps = packed record
7189 dwReserved: Cardinal;
7192 TDDSHeader = packed record
7197 dwPitchOrLinearSize: Cardinal;
7199 dwMipMapCount: Cardinal;
7200 dwReserved: array[0..10] of Cardinal;
7201 PixelFormat: TDDSPixelFormat;
7203 dwReserved2: Cardinal;
7206 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7207 function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
7210 Converter: TbmpBitfieldFormat;
7212 function GetDDSFormat: TglBitmapFormat;
7214 fd: TFormatDescriptor;
7216 Range: TglBitmapColorRec;
7220 with Header.PixelFormat do begin
7222 if ((dwFlags and DDPF_FOURCC) > 0) then begin
7223 case Header.PixelFormat.dwFourCC of
7224 D3DFMT_DXT1: result := tfS3tcDtx1RGBA;
7225 D3DFMT_DXT3: result := tfS3tcDtx3RGBA;
7226 D3DFMT_DXT5: result := tfS3tcDtx5RGBA;
7228 end else if ((Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0) then begin
7230 //find matching format
7231 for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
7232 fd := TFormatDescriptor.Get(result);
7233 if fd.MaskMatch(dwRBitMask, dwGBitMask, dwBBitMask, dwABitMask) and
7234 (8 * fd.PixelSize = dwRGBBitCount) then
7238 //find format with same Range
7239 Range.r := dwRBitMask;
7240 Range.g := dwGBitMask;
7241 Range.b := dwBBitMask;
7242 Range.a := dwABitMask;
7243 for i := 0 to 3 do begin
7244 while ((Range.arr[i] and 1) = 0) and (Range.arr[i] > 0) do
7245 Range.arr[i] := Range.arr[i] shr 1;
7247 for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
7248 fd := TFormatDescriptor.Get(result);
7251 if (fd.Range.arr[i] <> Range.arr[i]) then begin
7259 //no format with same range found -> use default
7260 if (result = tfEmpty) then begin
7261 if (dwABitMask > 0) then
7267 Converter := TbmpBitfieldFormat.Create;
7268 Converter.RedMask := dwRBitMask;
7269 Converter.GreenMask := dwGBitMask;
7270 Converter.BlueMask := dwBBitMask;
7271 Converter.AlphaMask := dwABitMask;
7272 Converter.PixelSize := dwRGBBitCount / 8;
7279 x, y, LineSize, RowSize, Magic: Cardinal;
7280 NewImage, TmpData, RowData, SrcData: System.PByte;
7281 SourceMD, DestMD: Pointer;
7282 Pixel: TglBitmapPixelData;
7283 ddsFormat: TglBitmapFormat;
7284 FormatDesc: TFormatDescriptor;
7289 StreamPos := aStream.Position;
7292 aStream.Read(Magic{%H-}, sizeof(Magic));
7293 if (Magic <> DDS_MAGIC) then begin
7294 aStream.Position := StreamPos;
7299 aStream.Read(Header{%H-}, sizeof(Header));
7300 if (Header.dwSize <> SizeOf(Header)) or
7301 ((Header.dwFlags and (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) <>
7302 (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) then
7304 aStream.Position := StreamPos;
7308 if ((Header.Caps.dwCaps1 and DDSCAPS2_CUBEMAP) > 0) then
7309 raise EglBitmapException.Create('LoadDDS - CubeMaps are not supported');
7311 ddsFormat := GetDDSFormat;
7313 if (ddsFormat = tfEmpty) then
7314 raise EglBitmapException.Create('LoadDDS - unsupported Pixelformat found.');
7316 FormatDesc := TFormatDescriptor.Get(ddsFormat);
7317 LineSize := Trunc(Header.dwWidth * FormatDesc.PixelSize);
7318 GetMem(NewImage, Header.dwHeight * LineSize);
7320 TmpData := NewImage;
7323 if Assigned(Converter) then begin
7324 RowSize := Round(Header.dwWidth * Header.PixelFormat.dwRGBBitCount / 8);
7325 GetMem(RowData, RowSize);
7326 SourceMD := Converter.CreateMappingData;
7327 DestMD := FormatDesc.CreateMappingData;
7329 for y := 0 to Header.dwHeight-1 do begin
7330 TmpData := NewImage;
7331 inc(TmpData, y * LineSize);
7333 aStream.Read(SrcData^, RowSize);
7334 for x := 0 to Header.dwWidth-1 do begin
7335 Converter.Unmap(SrcData, Pixel, SourceMD);
7336 glBitmapConvertPixel(Pixel, Converter, FormatDesc);
7337 FormatDesc.Map(Pixel, TmpData, DestMD);
7341 Converter.FreeMappingData(SourceMD);
7342 FormatDesc.FreeMappingData(DestMD);
7348 if ((Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0) then begin
7349 RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
7350 for Y := 0 to Header.dwHeight-1 do begin
7351 aStream.Read(TmpData^, RowSize);
7352 Inc(TmpData, LineSize);
7357 if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0 then begin
7358 RowSize := (Header.PixelFormat.dwRGBBitCount * Header.dwWidth) shr 3;
7359 for Y := 0 to Header.dwHeight-1 do begin
7360 aStream.Read(TmpData^, RowSize);
7361 Inc(TmpData, LineSize);
7364 raise EglBitmapException.Create('LoadDDS - unsupported Pixelformat found.');
7366 SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight); //be careful, Data could be freed by this method
7369 if Assigned(NewImage) then
7374 FreeAndNil(Converter);
7378 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7379 procedure TglBitmap.SaveDDS(const aStream: TStream);
7382 FormatDesc: TFormatDescriptor;
7384 if not (ftDDS in FormatGetSupportedFiles(Format)) then
7385 raise EglBitmapUnsupportedFormat.Create(Format);
7387 FormatDesc := TFormatDescriptor.Get(Format);
7390 FillChar(Header{%H-}, SizeOf(Header), 0);
7391 Header.dwSize := SizeOf(Header);
7392 Header.dwFlags := DDSD_WIDTH or DDSD_HEIGHT or DDSD_CAPS or DDSD_PIXELFORMAT;
7394 Header.dwWidth := Max(1, Width);
7395 Header.dwHeight := Max(1, Height);
7398 Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
7401 Header.PixelFormat.dwSize := sizeof(Header);
7402 if (FormatDesc.IsCompressed) then begin
7403 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_FOURCC;
7405 tfS3tcDtx1RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT1;
7406 tfS3tcDtx3RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT3;
7407 tfS3tcDtx5RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT5;
7409 end else if (Format in [tfAlpha8, tfAlpha16]) then begin
7410 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHA;
7411 Header.PixelFormat.dwRGBBitCount := Round(FormatDesc.PixelSize * 8);
7412 Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
7413 end else if (FormatDesc.RedMask = FormatDesc.GreenMask) and (FormatDesc.GreenMask = FormatDesc.BlueMask) then begin
7414 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_LUMINANCE;
7415 Header.PixelFormat.dwRGBBitCount := Round(FormatDesc.PixelSize * 8);
7416 Header.PixelFormat.dwRBitMask := FormatDesc.RedMask;
7417 Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
7419 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_RGB;
7420 Header.PixelFormat.dwRGBBitCount := Round(FormatDesc.PixelSize * 8);
7421 Header.PixelFormat.dwRBitMask := FormatDesc.RedMask;
7422 Header.PixelFormat.dwGBitMask := FormatDesc.GreenMask;
7423 Header.PixelFormat.dwBBitMask := FormatDesc.BlueMask;
7424 Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
7427 if (FormatDesc.HasAlpha) then
7428 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
7430 aStream.Write(DDS_MAGIC, sizeof(DDS_MAGIC));
7431 aStream.Write(Header, SizeOf(Header));
7432 aStream.Write(Data^, FormatDesc.GetSize(Dimension));
7435 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7436 //TglBitmap1D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7437 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7438 procedure TglBitmap1D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
7439 const aWidth: Integer; const aHeight: Integer);
7444 if (aHeight > 1) then begin
7445 Size := TFormatDescriptor.Get(aFormat).GetSize(aWidth, 1);
7446 GetMem(pTemp, Size);
7448 Move(aData^, pTemp^, Size);
7457 inherited SetDataPointer(pTemp, aFormat, aWidth);
7460 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7461 function TglBitmap1D.FlipHorz: Boolean;
7464 pTempDest, pDest, pSource: PByte;
7466 result := inherited FlipHorz;
7467 if Assigned(Data) and not TFormatDescriptor.Get(Format).IsCompressed then begin
7469 GetMem(pDest, fRowSize);
7472 Inc(pTempDest, fRowSize);
7473 for Col := 0 to Width-1 do begin
7474 dec(pTempDest, fPixelSize); //dec before, because ptr is behind last byte of data
7475 Move(pSource^, pTempDest^, fPixelSize);
7476 Inc(pSource, fPixelSize);
7478 SetDataPointer(pDest, Format, Width); //be careful, Data could be freed by this method
7481 if Assigned(pDest) then
7488 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7489 procedure TglBitmap1D.UploadData(const aBuildWithGlu: Boolean);
7491 FormatDesc: TFormatDescriptor;
7494 FormatDesc := TFormatDescriptor.Get(Format);
7495 if FormatDesc.IsCompressed then
7496 glCompressedTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.GetSize(Width, 1), Data)
7497 else if aBuildWithGlu then
7498 gluBuild1DMipmaps(Target, FormatDesc.glInternalFormat, Width, FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
7500 glTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
7503 if (FreeDataAfterGenTexture) then
7507 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7508 procedure TglBitmap1D.GenTexture(const aTestTextureSize: Boolean);
7510 BuildWithGlu, TexRec: Boolean;
7513 if Assigned(Data) then begin
7514 // Check Texture Size
7515 if (aTestTextureSize) then begin
7516 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
7518 if (Width > TexSize) then
7519 raise EglBitmapSizeToLargeException.Create('TglBitmap1D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
7521 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
7522 (Target = GL_TEXTURE_RECTANGLE_ARB);
7523 if not (IsPowerOfTwo(Width) or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
7524 raise EglBitmapNonPowerOfTwoException.Create('TglBitmap1D.GenTexture - Rendercontex dosn''t support non power of two texture.');
7528 SetupParameters(BuildWithGlu);
7529 UploadData(BuildWithGlu);
7530 glAreTexturesResident(1, @fID, @fIsResident);
7534 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7535 procedure TglBitmap1D.AfterConstruction;
7538 Target := GL_TEXTURE_1D;
7541 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7542 //TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7543 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7544 function TglBitmap2D.GetScanline(const aIndex: Integer): Pointer;
7546 if (aIndex >= Low(fLines)) and (aIndex <= High(fLines)) then
7547 result := fLines[aIndex]
7552 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7553 procedure TglBitmap2D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
7554 const aWidth: Integer; const aHeight: Integer);
7556 Idx, LineWidth: Integer;
7558 inherited SetDataPointer(aData, aFormat, aWidth, aHeight);
7560 if not TFormatDescriptor.Get(aFormat).IsCompressed then begin
7562 if Assigned(Data) then begin
7563 SetLength(fLines, GetHeight);
7564 LineWidth := Trunc(GetWidth * TFormatDescriptor.Get(Format).PixelSize);
7566 for Idx := 0 to GetHeight-1 do begin
7567 fLines[Idx] := Data;
7568 Inc(fLines[Idx], Idx * LineWidth);
7571 else SetLength(fLines, 0);
7573 SetLength(fLines, 0);
7577 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7578 procedure TglBitmap2D.UploadData(const aBuildWithGlu: Boolean);
7580 FormatDesc: TFormatDescriptor;
7582 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
7584 FormatDesc := TFormatDescriptor.Get(Format);
7585 if FormatDesc.IsCompressed then begin
7586 glCompressedTexImage2D(Target, 0, FormatDesc.glInternalFormat, Width, Height, 0, FormatDesc.GetSize(fDimension), Data)
7587 end else if aBuildWithGlu then begin
7588 gluBuild2DMipmaps(Target, FormatDesc.Components, Width, Height,
7589 FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
7591 glTexImage2D(Target, 0, FormatDesc.glInternalFormat, Width, Height, 0,
7592 FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
7596 if (FreeDataAfterGenTexture) then
7600 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7601 procedure TglBitmap2D.AfterConstruction;
7604 Target := GL_TEXTURE_2D;
7607 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7608 procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
7611 Size, w, h: Integer;
7612 FormatDesc: TFormatDescriptor;
7614 FormatDesc := TFormatDescriptor.Get(Format);
7615 if FormatDesc.IsCompressed then
7616 raise EglBitmapUnsupportedFormat.Create(Format);
7618 w := aRight - aLeft;
7619 h := aBottom - aTop;
7620 Size := FormatDesc.GetSize(w, h);
7623 glPixelStorei(GL_PACK_ALIGNMENT, 1);
7624 glReadPixels(aLeft, aTop, w, h, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
7625 SetDataPointer(Temp, Format, w, h); //be careful, Data could be freed by this method
7628 if Assigned(Temp) then
7634 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7635 procedure TglBitmap2D.GetDataFromTexture;
7638 TempWidth, TempHeight: Integer;
7639 TempIntFormat: Cardinal;
7640 IntFormat, f: TglBitmapFormat;
7641 FormatDesc: TFormatDescriptor;
7646 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
7647 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
7648 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
7650 IntFormat := tfEmpty;
7651 for f := Low(TglBitmapFormat) to High(TglBitmapFormat) do begin
7652 FormatDesc := TFormatDescriptor.Get(f);
7653 if (FormatDesc.glInternalFormat = TempIntFormat) then begin
7654 IntFormat := FormatDesc.Format;
7659 // Getting data from OpenGL
7660 FormatDesc := TFormatDescriptor.Get(IntFormat);
7661 GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
7663 if FormatDesc.IsCompressed then
7664 glGetCompressedTexImage(Target, 0, Temp)
7666 glGetTexImage(Target, 0, FormatDesc.glInternalFormat, FormatDesc.glDataFormat, Temp);
7667 SetDataPointer(Temp, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
7669 if Assigned(Temp) then
7675 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7676 procedure TglBitmap2D.GenTexture(const aTestTextureSize: Boolean);
7678 BuildWithGlu, PotTex, TexRec: Boolean;
7681 if Assigned(Data) then begin
7682 // Check Texture Size
7683 if (aTestTextureSize) then begin
7684 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
7686 if ((Height > TexSize) or (Width > TexSize)) then
7687 raise EglBitmapSizeToLargeException.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
7689 PotTex := IsPowerOfTwo(Height) and IsPowerOfTwo(Width);
7690 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE);
7691 if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
7692 raise EglBitmapNonPowerOfTwoException.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
7696 SetupParameters(BuildWithGlu);
7697 UploadData(BuildWithGlu);
7698 glAreTexturesResident(1, @fID, @fIsResident);
7702 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7703 function TglBitmap2D.FlipHorz: Boolean;
7706 TempDestData, DestData, SourceData: PByte;
7709 result := inherited FlipHorz;
7710 if Assigned(Data) then begin
7712 ImgSize := Height * fRowSize;
7713 GetMem(DestData, ImgSize);
7715 TempDestData := DestData;
7716 Dec(TempDestData, fRowSize + fPixelSize);
7717 for Row := 0 to Height -1 do begin
7718 Inc(TempDestData, fRowSize * 2);
7719 for Col := 0 to Width -1 do begin
7720 Move(SourceData^, TempDestData^, fPixelSize);
7721 Inc(SourceData, fPixelSize);
7722 Dec(TempDestData, fPixelSize);
7725 SetDataPointer(DestData, Format); //be careful, Data could be freed by this method
7728 if Assigned(DestData) then
7735 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7736 function TglBitmap2D.FlipVert: Boolean;
7739 TempDestData, DestData, SourceData: PByte;
7741 result := inherited FlipVert;
7742 if Assigned(Data) then begin
7744 GetMem(DestData, Height * fRowSize);
7746 TempDestData := DestData;
7747 Inc(TempDestData, Width * (Height -1) * fPixelSize);
7748 for Row := 0 to Height -1 do begin
7749 Move(SourceData^, TempDestData^, fRowSize);
7750 Dec(TempDestData, fRowSize);
7751 Inc(SourceData, fRowSize);
7753 SetDataPointer(DestData, Format); //be careful, Data could be freed by this method
7756 if Assigned(DestData) then
7763 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7764 //TglBitmap2D - ToNormalMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7765 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7767 TMatrixItem = record
7772 PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
7773 TglBitmapToNormalMapRec = Record
7775 Heights: array of Single;
7776 MatrixU : array of TMatrixItem;
7777 MatrixV : array of TMatrixItem;
7781 ONE_OVER_255 = 1 / 255;
7783 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7784 procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
7788 with FuncRec do begin
7790 Source.Data.r * LUMINANCE_WEIGHT_R +
7791 Source.Data.g * LUMINANCE_WEIGHT_G +
7792 Source.Data.b * LUMINANCE_WEIGHT_B;
7793 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255;
7797 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7798 procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
7801 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
7804 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7805 procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
7807 TVec = Array[0..2] of Single;
7814 function GetHeight(X, Y: Integer): Single;
7816 with FuncRec do begin
7817 X := Max(0, Min(Size.X -1, X));
7818 Y := Max(0, Min(Size.Y -1, Y));
7819 result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
7824 with FuncRec do begin
7825 with PglBitmapToNormalMapRec(Args)^ do begin
7827 for Idx := Low(MatrixU) to High(MatrixU) do
7828 du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
7831 for Idx := Low(MatrixU) to High(MatrixU) do
7832 dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
7834 Vec[0] := -du * Scale;
7835 Vec[1] := -dv * Scale;
7840 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
7841 if Len <> 0 then begin
7842 Vec[0] := Vec[0] * Len;
7843 Vec[1] := Vec[1] * Len;
7844 Vec[2] := Vec[2] * Len;
7848 Dest.Data.r := Trunc((Vec[0] + 1) * 127.5);
7849 Dest.Data.g := Trunc((Vec[1] + 1) * 127.5);
7850 Dest.Data.b := Trunc((Vec[2] + 1) * 127.5);
7854 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7855 procedure TglBitmap2D.ToNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
7857 Rec: TglBitmapToNormalMapRec;
7859 procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
7861 if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
7862 Matrix[Index].X := X;
7863 Matrix[Index].Y := Y;
7864 Matrix[Index].W := W;
7869 if TFormatDescriptor.Get(Format).IsCompressed then
7870 raise EglBitmapUnsupportedFormat.Create(Format);
7872 if aScale > 100 then
7874 else if aScale < -100 then
7877 Rec.Scale := aScale;
7879 SetLength(Rec.Heights, Width * Height);
7883 SetLength(Rec.MatrixU, 2);
7884 SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
7885 SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
7887 SetLength(Rec.MatrixV, 2);
7888 SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
7889 SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
7893 SetLength(Rec.MatrixU, 6);
7894 SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
7895 SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
7896 SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
7897 SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
7898 SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
7899 SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
7901 SetLength(Rec.MatrixV, 6);
7902 SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
7903 SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
7904 SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
7905 SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
7906 SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
7907 SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
7911 SetLength(Rec.MatrixU, 6);
7912 SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
7913 SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
7914 SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
7915 SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
7916 SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
7917 SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
7919 SetLength(Rec.MatrixV, 6);
7920 SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
7921 SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
7922 SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
7923 SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
7924 SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
7925 SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
7929 SetLength(Rec.MatrixU, 20);
7930 SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
7931 SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
7932 SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
7933 SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
7934 SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
7935 SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
7936 SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
7937 SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
7938 SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
7939 SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
7940 SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
7941 SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
7942 SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
7943 SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
7944 SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
7945 SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
7946 SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
7947 SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
7948 SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
7949 SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
7951 SetLength(Rec.MatrixV, 20);
7952 SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
7953 SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
7954 SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
7955 SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
7956 SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
7957 SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
7958 SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
7959 SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
7960 SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
7961 SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
7962 SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
7963 SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
7964 SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
7965 SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
7966 SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
7967 SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
7968 SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
7969 SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
7970 SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
7971 SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
7976 if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
7977 AddFunc(glBitmapToNormalMapPrepareAlphaFunc, false, @Rec)
7979 AddFunc(glBitmapToNormalMapPrepareFunc, false, @Rec);
7980 AddFunc(glBitmapToNormalMapFunc, false, @Rec);
7982 SetLength(Rec.Heights, 0);
7998 { TglBitmapCubeMap }
8000 procedure TglBitmapCubeMap.AfterConstruction;
8004 if not (GL_VERSION_1_3 or GL_ARB_texture_cube_map or GL_EXT_texture_cube_map) then
8005 raise EglBitmapException.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
8007 SetWrap; // set all to GL_CLAMP_TO_EDGE
8008 Target := GL_TEXTURE_CUBE_MAP;
8009 fGenMode := GL_REFLECTION_MAP;
8013 procedure TglBitmapCubeMap.Bind(EnableTexCoordsGen, EnableTextureUnit: Boolean);
8015 inherited Bind (EnableTextureUnit);
8017 if EnableTexCoordsGen then begin
8018 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, fGenMode);
8019 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, fGenMode);
8020 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, fGenMode);
8021 glEnable(GL_TEXTURE_GEN_S);
8022 glEnable(GL_TEXTURE_GEN_T);
8023 glEnable(GL_TEXTURE_GEN_R);
8028 procedure TglBitmapCubeMap.GenerateCubeMap(CubeTarget: Cardinal; TestTextureSize: Boolean);
8030 glFormat, glInternalFormat, glType: Cardinal;
8031 BuildWithGlu: Boolean;
8034 // Check Texture Size
8035 if (TestTextureSize) then begin
8036 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @TexSize);
8038 if ((Height > TexSize) or (Width > TexSize)) then
8039 raise EglBitmapSizeToLargeException.Create('TglBitmapCubeMap.GenTexture - The size for the Cubemap is to large. It''s may be not conform with the Hardware.');
8041 if not ((IsPowerOfTwo (Height) and IsPowerOfTwo (Width)) or GL_VERSION_2_0 or GL_ARB_texture_non_power_of_two) then
8042 raise EglBitmapNonPowerOfTwoException.Create('TglBitmapCubeMap.GenTexture - Cubemaps dosn''t support non power of two texture.');
8046 if ID = 0 then begin
8048 SetupParameters(BuildWithGlu);
8051 SelectFormat(InternalFormat, glFormat, glInternalFormat, glType);
8053 UploadData (CubeTarget, glFormat, glInternalFormat, glType, BuildWithGlu);
8057 procedure TglBitmapCubeMap.GenTexture(TestTextureSize: Boolean);
8059 Assert(false, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
8063 procedure TglBitmapCubeMap.Unbind(DisableTexCoordsGen,
8064 DisableTextureUnit: Boolean);
8066 inherited Unbind (DisableTextureUnit);
8068 if DisableTexCoordsGen then begin
8069 glDisable(GL_TEXTURE_GEN_S);
8070 glDisable(GL_TEXTURE_GEN_T);
8071 glDisable(GL_TEXTURE_GEN_R);
8076 { TglBitmapNormalMap }
8079 TVec = Array[0..2] of Single;
8080 TglBitmapNormalMapGetVectorFunc = procedure (var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
8082 PglBitmapNormalMapRec = ^TglBitmapNormalMapRec;
8083 TglBitmapNormalMapRec = record
8085 Func: TglBitmapNormalMapGetVectorFunc;
8089 procedure glBitmapNormalMapPosX(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
8092 Vec[1] := - (Position.Y + 0.5 - HalfSize);
8093 Vec[2] := - (Position.X + 0.5 - HalfSize);
8097 procedure glBitmapNormalMapNegX(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
8099 Vec[0] := - HalfSize;
8100 Vec[1] := - (Position.Y + 0.5 - HalfSize);
8101 Vec[2] := Position.X + 0.5 - HalfSize;
8105 procedure glBitmapNormalMapPosY(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
8107 Vec[0] := Position.X + 0.5 - HalfSize;
8109 Vec[2] := Position.Y + 0.5 - HalfSize;
8113 procedure glBitmapNormalMapNegY(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
8115 Vec[0] := Position.X + 0.5 - HalfSize;
8116 Vec[1] := - HalfSize;
8117 Vec[2] := - (Position.Y + 0.5 - HalfSize);
8121 procedure glBitmapNormalMapPosZ(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
8123 Vec[0] := Position.X + 0.5 - HalfSize;
8124 Vec[1] := - (Position.Y + 0.5 - HalfSize);
8129 procedure glBitmapNormalMapNegZ(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
8131 Vec[0] := - (Position.X + 0.5 - HalfSize);
8132 Vec[1] := - (Position.Y + 0.5 - HalfSize);
8133 Vec[2] := - HalfSize;
8137 procedure glBitmapNormalMapFunc(var FuncRec: TglBitmapFunctionRec);
8142 with FuncRec do begin
8143 with PglBitmapNormalMapRec (CustomData)^ do begin
8144 Func(Vec, Position, HalfSize);
8147 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
8148 if Len <> 0 then begin
8149 Vec[0] := Vec[0] * Len;
8150 Vec[1] := Vec[1] * Len;
8151 Vec[2] := Vec[2] * Len;
8154 // Scale Vector and AddVectro
8155 Vec[0] := Vec[0] * 0.5 + 0.5;
8156 Vec[1] := Vec[1] * 0.5 + 0.5;
8157 Vec[2] := Vec[2] * 0.5 + 0.5;
8161 Dest.Red := Round(Vec[0] * 255);
8162 Dest.Green := Round(Vec[1] * 255);
8163 Dest.Blue := Round(Vec[2] * 255);
8168 procedure TglBitmapNormalMap.AfterConstruction;
8172 fGenMode := GL_NORMAL_MAP;
8176 procedure TglBitmapNormalMap.GenerateNormalMap(Size: Integer;
8177 TestTextureSize: Boolean);
8179 Rec: TglBitmapNormalMapRec;
8180 SizeRec: TglBitmapPixelPosition;
8182 Rec.HalfSize := Size div 2;
8184 FreeDataAfterGenTexture := false;
8186 SizeRec.Fields := [ffX, ffY];
8191 Rec.Func := glBitmapNormalMapPosX;
8192 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
8193 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X, TestTextureSize);
8196 Rec.Func := glBitmapNormalMapNegX;
8197 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
8198 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, TestTextureSize);
8201 Rec.Func := glBitmapNormalMapPosY;
8202 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
8203 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, TestTextureSize);
8206 Rec.Func := glBitmapNormalMapNegY;
8207 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
8208 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, TestTextureSize);
8211 Rec.Func := glBitmapNormalMapPosZ;
8212 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
8213 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, TestTextureSize);
8216 Rec.Func := glBitmapNormalMapNegZ;
8217 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
8218 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, TestTextureSize);
8223 glBitmapSetDefaultFormat(tfEmpty);
8224 glBitmapSetDefaultMipmap(mmMipmap);
8225 glBitmapSetDefaultFilter(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
8226 glBitmapSetDefaultWrap (GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
8228 glBitmapSetDefaultFreeDataAfterGenTexture(true);
8229 glBitmapSetDefaultDeleteTextureOnFree (true);
8231 TFormatDescriptor.Init;
8233 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
8234 OpenGLInitialized := false;
8235 InitOpenGLCS := TCriticalSection.Create;
8239 TFormatDescriptor.Finalize;
8241 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
8242 FreeAndNil(InitOpenGLCS);