1 {***********************************************************
2 glBitmap by Steffen Xonna aka Lossy eX (2003-2008)
3 http://www.opengl24.de/index.php?cat=header&file=glbitmap
5 modified by Delphi OpenGL Community (http://delphigl.com/) (2013)
7 ------------------------------------------------------------
8 The contents of this file are used with permission, subject to
9 the Mozilla Public License Version 1.1 (the "License"); you may
10 not use this file except in compliance with the License. You may
11 obtain a copy of the License at
12 http://www.mozilla.org/MPL/MPL-1.1.html
13 ------------------------------------------------------------
14 Version 3.0.0 unstable
15 ------------------------------------------------------------
18 - refactoring of the complete library
20 - The define GLB_DELPHI dosn't check versions anymore. If you say you are using delphi
21 then it's your problem if that isn't true. This prevents the unit for incompatibility
22 with newer versions of Delphi.
23 - Problems with D2009+ resolved (Thanks noeska and all i forgot)
24 - GetPixel isn't set if you are loading textures inside the constructor (Thanks Wilson)
26 - AddAlphaFromglBitmap used the custom pointer instead the imagedatapointer (Thanks Wilson)
27 - Additional Datapointer for functioninterface now has the name CustomData
29 - AssigneAlphaToBitmap overwrites his own palette (Thanks Wilson)
30 - If you load an texture from an file the property Filename will be set to the name of the file
31 - Three new properties to attach custom data to the Texture objects
32 - CustomName (free for use string)
33 - CustomNameW (free for use widestring)
34 - CustomDataPointer (free for use pointer to attach other objects or complex structures)
36 - RLE TGAs loaded much faster
38 - fixed some problem with reading RLE TGAs.
40 - function clone now only copys data if it's assigned and now it also copies the ID
41 - it seems that lazarus dont like comments in comments.
43 - It's possible to set the id of the texture
44 - define GLB_NO_NATIVE_GL deactivated by default
46 - Now supports the following libraries
50 - Linux compatibillity via free pascal compatibility (delphi sources optional)
51 - BMPs now loaded manuel
53 - Property DataPtr now has the name Data
54 - Functions are more flexible between RGB(A) and BGR(A). RGB can be saved as Bitmap and will be saved as BGR
55 - Unused Depth removed
56 - Function FreeData to freeing image data added
58 - ImageID flag of TGAs was ignored. (Thanks Zwoetzen)
60 - Function SetBorderColor implemented (only used by opengl if wrap is set to GL_CLAMP_TO_BORDER)
61 - Function AddAlphaFromValue implemented to use an fixed Value as Alphachannel
62 - Function ReadOpenGLExtension is now only intern
64 - pngimage now disabled by default like all other versions.
66 - Setting up an anisotropic filter of 0 isnt allowed by nvidia (Thanks Ogridi)
68 - Fixed some Problem with Delphi 5
69 - Now uses the newest version of pngimage. Makes saving pngs much easier.
71 - Property IsCompressed and Size removed. Not really supported by Spec (Thanks Ogridi)
73 - Internal Format ifDepth8 added
74 - function GrabScreen now supports all uncompressed formats
76 - AddAlphaFromglBitmap implemented
78 - LoadFromResource and LoadFromResourceId now needs an Instance and an ResourceType (for ID)
80 - Width, Height and Depth internal changed to TglBitmapPixelPosition.
81 property Width, Height, Depth are still existing and new property Dimension are avail
83 - Added native OpenGL Support. Breaking the dglOpenGL "barrier".
85 - Added function GrabScreen to class TglBitmap2D
87 - Added support to Save images
88 - Added function Clone to Clone Instance
90 - Functions now works with Cardinals for each channel. Up to 32 Bits per channel.
92 - Several speed optimizations
94 - Internal structure change. Loading of TGA, PNG and DDS improved.
95 Data, format and size will now set directly with SetDataPtr.
96 - AddFunc now works with all Types of Images and Formats
97 - Some Funtions moved to Baseclass TglBitmap
99 - Added Support to decompress DXT3 and DXT5 compressed Images.
100 - Added Mapping to convert data from one format into an other.
102 - Added method ConvertTo in Class TglBitmap2D. Method allows to convert every
103 supported Input format (supported by GetPixel) into any uncompresed Format
104 - Added Support to decompress DXT1 compressed Images.
105 - SwapColors replaced by ConvertTo
107 - Added Support for compressed DDSs
108 - Added new internal formats (DXT1, DXT3, DXT5)
110 - Parameter Components renamed to InternalFormat
112 - Some AllocMem replaced with GetMem (little speed change)
113 - better exception handling. Better protection from memory leaks.
115 - Added support for Direct Draw Surfaces (.DDS) (uncompressed images only)
116 - Added new internal formats (RGB8, RGBA8, RGBA4, RGB5A1, RGB10A2, R5G6B5)
118 - Added support for Grayscale textures
119 - Added internal formats (Alpha, Luminance, LuminanceAlpha, BGR8, BGRA8)
121 - Added support for GL_VERSION_2_0
122 - Added support for GL_EXT_texture_filter_anisotropic
124 - Function FillWithColor fills the Image with one Color
125 - Function LoadNormalMap added
127 - ToNormalMap allows to Create an NormalMap from the Alphachannel
128 - ToNormalMap now supports Sobel (nmSobel) function.
130 - support for RLE Compressed RGB TGAs added
132 - Class TglBitmapNormalMap added to support Normalmap generation
133 - Added function ToNormalMap in class TglBitmap2D to genereate normal maps from textures.
134 3 Filters are supported. (4 Samples, 3x3 and 5x5)
136 - Method LoadCubeMapClass removed
137 - LoadCubeMap returnvalue is now the Texture paramter. Such as LoadTextures
138 - virtual abstract method GenTexture in class TglBitmap now is protected
140 - now support DescriptionFlag in LoadTga. Allows vertical flipped images to be loaded as normal
142 - little enhancement for IsPowerOfTwo
143 - TglBitmap1D.GenTexture now tests NPOT Textures
145 - some little name changes. All properties or function with Texture in name are
146 now without texture in name. We have allways texture so we dosn't name it.
148 - GenTexture now tests if texture is NPOT and NPOT-Texture are supported or
149 TextureTarget is GL_TEXTURE_RECTANGLE. Else it raised an exception.
151 - added support for GL_ARB_texture_rectangle, GL_EXT_texture_rectangle and GL_NV_texture_rectangle
153 - Function Unbind added
154 - call of SetFilter or SetTextureWrap if TextureID exists results in setting properties to opengl texture.
156 - class TglBitmapCubeMap added (allows to Create Cubemaps)
158 - Added Support for PNG Images. (http://pngdelphi.sourceforge.net/)
159 To Enable png's use the define pngimage
161 - New Functioninterface added
162 - Function GetPixel added
164 - Property BuildMipMaps renamed to MipMap
166 - property Name removed.
167 - BuildMipMaps is now a set of 3 values. None, GluBuildMipmaps and SGIS_generate_mipmap
169 - property name added. Only used in glForms!
171 - property FreeDataAfterGenTexture is now available as default (default = true)
172 - BuildMipmaps now implemented in TglBitmap1D (i've forgotten it)
173 - function MoveMemory replaced with function Move (little speed change)
174 - several calculations stored in variables (little speed change)
176 - property BuildMipsMaps added (default = true)
177 if BuildMipMaps isn't set GenTextures uses glTexImage[12]D else it use gluBuild[12]dMipmaps
178 - property FreeDataAfterGenTexture added (default = true)
179 if FreeDataAfterGenTexture is set the texturedata were deleted after the texture was generated.
180 - parameter DisableOtherTextureUnits of Bind removed
181 - parameter FreeDataAfterGeneration of GenTextures removed
183 - TglBitmap dosn't delete data if class was destroyed (fixed)
185 - Bind now enables TextureUnits (by params)
186 - GenTextures can leave data (by param)
187 - LoadTextures now optimal
189 - Performance optimization in AddFunc
190 - procedure Bind moved to subclasses
191 - Added new Class TglBitmap1D to support real OpenGL 1D Textures
193 - Texturefilter and texturewrap now also as defaults
194 Minfilter = GL_LINEAR_MIPMAP_LINEAR
195 Magfilter = GL_LINEAR
196 Wrap(str) = GL_CLAMP_TO_EDGE
197 - Added new format tfCompressed to create a compressed texture.
198 - propertys IsCompressed, TextureSize and IsResident added
199 IsCompressed and TextureSize only contains data from level 0
201 - Added function AddFunc to add PerPixelEffects to Image
202 - LoadFromFunc now based on AddFunc
203 - Invert now based on AddFunc
204 - SwapColors now based on AddFunc
206 - Added function FlipHorz
208 - Added function LaodFromFunc to create images with function
209 - Added function FlipVert
210 - Added internal format RGB(A) if GL_EXT_bgra or OpenGL 1.2 isn't supported
212 - Added Alphafunctions to calculate alpha per function
213 - Added Alpha from ColorKey using alphafunctions
215 - First full functionally Version of glBitmap
216 - Support for 24Bit and 32Bit TGA Pictures added
218 - begin of programming
219 ***********************************************************}
222 // Please uncomment the defines below to configure the glBitmap to your preferences.
223 // If you have configured the unit you can uncomment the warning above.
224 {$MESSAGE warn 'Hey. I''m the glBitmap.pas and i need to be configured. My master tell me your preferences! ;)'}
226 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
227 // Preferences ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
228 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
229 // activate to enable build-in OpenGL support with statically linked methods
230 // use dglOpenGL.pas if not enabled
231 {.$DEFINE GLB_NATIVE_OGL_STATIC}
233 // activate to enable build-in OpenGL support with dynamically linked methods
234 // use dglOpenGL.pas if not enabled
235 {.$DEFINE GLB_NATIVE_OGL_DYNAMIC}
238 // activate to enable the support for SDL_surfaces
241 // activate to enable the support for TBitmap from Delphi (not lazarus)
242 {.$DEFINE GLB_DELPHI}
244 // activate to enable the support for TLazIntfImage from Lazarus
245 {$DEFINE GLB_LAZARUS}
249 // activate to enable the support of SDL_image to load files. (READ ONLY)
250 // If you enable SDL_image all other libraries will be ignored!
251 {.$DEFINE GLB_SDL_IMAGE}
255 // activate to enable png support with the unit pngimage -> http://pngdelphi.sourceforge.net/
256 // if you enable pngimage the libPNG will be ignored
257 {.$DEFINE GLB_PNGIMAGE}
259 // activate to use the libPNG -> http://www.libpng.org/
260 // You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libpng
261 {.$DEFINE GLB_LIB_PNG}
265 // if you enable delphi jpegs the libJPEG will be ignored
266 {.$DEFINE GLB_DELPHI_JPEG}
268 // activate to use the libJPEG -> http://www.ijg.org/
269 // You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libjpeg
270 {.$DEFINE GLB_LIB_JPEG}
273 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
274 // PRIVATE: do not change anything! //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
275 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
291 {$IF DEFINED(WIN32) or DEFINED(WIN64) or DEFINED(WINDOWS)}
293 {$ELSEIF DEFINED(LINUX)}
297 // native OpenGL Support
298 {$IF DEFINED(GLB_NATIVE_OGL_STATIC) OR DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
299 {$DEFINE GLB_NATIVE_OGL}
302 // checking define combinations
304 {$IFDEF GLB_SDL_IMAGE}
306 {$MESSAGE warn 'SDL_image won''t work without SDL. SDL will be activated.'}
309 {$IFDEF GLB_PNGIMAGE}
310 {$MESSAGE warn 'The unit pngimage will be ignored because you are using SDL_image.'}
311 {$undef GLB_PNGIMAGE}
313 {$IFDEF GLB_DELPHI_JPEG}
314 {$MESSAGE warn 'The unit JPEG will be ignored because you are using SDL_image.'}
315 {$undef GLB_DELPHI_JPEG}
318 {$MESSAGE warn 'The library libPNG will be ignored because you are using SDL_image.'}
321 {$IFDEF GLB_LIB_JPEG}
322 {$MESSAGE warn 'The library libJPEG will be ignored because you are using SDL_image.'}
323 {$undef GLB_LIB_JPEG}
326 {$DEFINE GLB_SUPPORT_PNG_READ}
327 {$DEFINE GLB_SUPPORT_JPEG_READ}
331 {$IFDEF GLB_PNGIMAGE}
333 {$MESSAGE warn 'The library libPNG will be ignored if you are using pngimage.'}
337 {$DEFINE GLB_SUPPORT_PNG_READ}
338 {$DEFINE GLB_SUPPORT_PNG_WRITE}
343 {$DEFINE GLB_SUPPORT_PNG_READ}
344 {$DEFINE GLB_SUPPORT_PNG_WRITE}
348 {$IFDEF GLB_DELPHI_JPEG}
349 {$IFDEF GLB_LIB_JPEG}
350 {$MESSAGE warn 'The library libJPEG will be ignored if you are using the unit JPEG.'}
351 {$undef GLB_LIB_JPEG}
354 {$DEFINE GLB_SUPPORT_JPEG_READ}
355 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
359 {$IFDEF GLB_LIB_JPEG}
360 {$DEFINE GLB_SUPPORT_JPEG_READ}
361 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
365 {$IF DEFINED(GLB_NATIVE_OGL_STATIC) AND DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
366 {$MESSAGE warn 'GLB_NATIVE_OGL_STATIC will be ignored because you enabled GLB_NATIVE_OGL_DYNAMIC'}
380 {$IFNDEF GLB_NATIVE_OGL} dglOpenGL, {$ENDIF}
381 {$IF DEFINED(GLB_WIN) AND
382 DEFINED(GLB_NATIVE_OGL)} windows, {$IFEND}
384 {$IFDEF GLB_SDL} SDL, {$ENDIF}
385 {$IFDEF GLB_LAZARUS} IntfGraphics, GraphType, {$ENDIF}
386 {$IFDEF GLB_DELPHI} Dialogs, Graphics, {$ENDIF}
388 {$IFDEF GLB_SDL_IMAGE} SDL_image, {$ENDIF}
389 {$IFDEF GLB_PNGIMAGE} pngimage, {$ENDIF}
390 {$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}
405 GL_EXTENSIONS = $1F03;
407 GL_TEXTURE_1D = $0DE0;
408 GL_TEXTURE_2D = $0DE1;
409 GL_TEXTURE_RECTANGLE = $84F5;
411 GL_NORMAL_MAP = $8511;
412 GL_TEXTURE_CUBE_MAP = $8513;
413 GL_REFLECTION_MAP = $8512;
414 GL_TEXTURE_CUBE_MAP_POSITIVE_X = $8515;
415 GL_TEXTURE_CUBE_MAP_NEGATIVE_X = $8516;
416 GL_TEXTURE_CUBE_MAP_POSITIVE_Y = $8517;
417 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = $8518;
418 GL_TEXTURE_CUBE_MAP_POSITIVE_Z = $8519;
419 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = $851A;
421 GL_TEXTURE_WIDTH = $1000;
422 GL_TEXTURE_HEIGHT = $1001;
423 GL_TEXTURE_INTERNAL_FORMAT = $1003;
424 GL_TEXTURE_SWIZZLE_RGBA = $8E46;
431 GL_TEXTURE_GEN_S = $0C60;
432 GL_TEXTURE_GEN_T = $0C61;
433 GL_TEXTURE_GEN_R = $0C62;
434 GL_TEXTURE_GEN_Q = $0C63;
446 GL_LUMINANCE = $1909;
447 GL_LUMINANCE4 = $803F;
448 GL_LUMINANCE8 = $8040;
449 GL_LUMINANCE12 = $8041;
450 GL_LUMINANCE16 = $8042;
452 GL_LUMINANCE_ALPHA = $190A;
453 GL_LUMINANCE4_ALPHA4 = $8043;
454 GL_LUMINANCE6_ALPHA2 = $8044;
455 GL_LUMINANCE8_ALPHA8 = $8045;
456 GL_LUMINANCE12_ALPHA4 = $8046;
457 GL_LUMINANCE12_ALPHA12 = $8047;
458 GL_LUMINANCE16_ALPHA16 = $8048;
481 GL_DEPTH_COMPONENT = $1902;
482 GL_DEPTH_COMPONENT16 = $81A5;
483 GL_DEPTH_COMPONENT24 = $81A6;
484 GL_DEPTH_COMPONENT32 = $81A7;
486 GL_COMPRESSED_RGB = $84ED;
487 GL_COMPRESSED_RGBA = $84EE;
488 GL_COMPRESSED_RGB_S3TC_DXT1_EXT = $83F0;
489 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = $83F1;
490 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = $83F2;
491 GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = $83F3;
493 GL_UNSIGNED_BYTE = $1401;
494 GL_UNSIGNED_BYTE_3_3_2 = $8032;
495 GL_UNSIGNED_BYTE_2_3_3_REV = $8362;
497 GL_UNSIGNED_SHORT = $1403;
498 GL_UNSIGNED_SHORT_5_6_5 = $8363;
499 GL_UNSIGNED_SHORT_4_4_4_4 = $8033;
500 GL_UNSIGNED_SHORT_5_5_5_1 = $8034;
501 GL_UNSIGNED_SHORT_5_6_5_REV = $8364;
502 GL_UNSIGNED_SHORT_4_4_4_4_REV = $8365;
503 GL_UNSIGNED_SHORT_1_5_5_5_REV = $8366;
505 GL_UNSIGNED_INT = $1405;
506 GL_UNSIGNED_INT_8_8_8_8 = $8035;
507 GL_UNSIGNED_INT_10_10_10_2 = $8036;
508 GL_UNSIGNED_INT_8_8_8_8_REV = $8367;
509 GL_UNSIGNED_INT_2_10_10_10_REV = $8368;
512 GL_TEXTURE_MAG_FILTER = $2800;
513 GL_TEXTURE_MIN_FILTER = $2801;
515 GL_NEAREST_MIPMAP_NEAREST = $2700;
516 GL_NEAREST_MIPMAP_LINEAR = $2702;
518 GL_LINEAR_MIPMAP_NEAREST = $2701;
519 GL_LINEAR_MIPMAP_LINEAR = $2703;
522 GL_TEXTURE_WRAP_S = $2802;
523 GL_TEXTURE_WRAP_T = $2803;
524 GL_TEXTURE_WRAP_R = $8072;
527 GL_CLAMP_TO_EDGE = $812F;
528 GL_CLAMP_TO_BORDER = $812D;
529 GL_MIRRORED_REPEAT = $8370;
532 GL_GENERATE_MIPMAP = $8191;
533 GL_TEXTURE_BORDER_COLOR = $1004;
534 GL_MAX_TEXTURE_SIZE = $0D33;
535 GL_PACK_ALIGNMENT = $0D05;
536 GL_UNPACK_ALIGNMENT = $0CF5;
538 GL_TEXTURE_MAX_ANISOTROPY_EXT = $84FE;
539 GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = $84FF;
540 GL_MAX_CUBE_MAP_TEXTURE_SIZE = $851C;
541 GL_TEXTURE_GEN_MODE = $2500;
543 {$IF DEFINED(GLB_WIN)}
544 libglu = 'glu32.dll';
545 libopengl = 'opengl32.dll';
546 {$ELSEIF DEFINED(GLB_LINUX)}
547 libglu = 'libGLU.so.1';
548 libopengl = 'libGL.so.1';
552 GLboolean = BYTEBOOL;
560 PGLboolean = ^GLboolean;
565 TglCompressedTexImage1D = procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
566 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}
567 TglGetCompressedTexImage = procedure(target: GLenum; level: GLint; img: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
569 {$IF DEFINED(GLB_WIN)}
570 TwglGetProcAddress = function (ProcName: PAnsiChar): Pointer; stdcall;
571 {$ELSEIF DEFINED(GLB_LINUX)}
572 TglXGetProcAddress = function(ProcName: PAnsiChar): Pointer; cdecl;
573 TglXGetProcAddressARB = function(const name: PAnsiChar): pointer; cdecl;
576 {$IF DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
577 TglEnable = procedure(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
578 TglDisable = procedure(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
580 TglGetString = function(name: GLenum): PAnsiChar; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
581 TglGetIntegerv = procedure(pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
583 TglTexParameteri = procedure(target: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
584 TglTexParameteriv = procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
585 TglTexParameterfv = procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
586 TglGetTexParameteriv = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
587 TglGetTexParameterfv = procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
588 TglGetTexLevelParameteriv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
589 TglGetTexLevelParameterfv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
591 TglTexGeni = procedure(coord: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
592 TglGenTextures = procedure(n: GLsizei; textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
593 TglBindTexture = procedure(target: GLenum; texture: GLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
594 TglDeleteTextures = procedure(n: GLsizei; const textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
596 TglAreTexturesResident = function(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
597 TglReadPixels = procedure(x: GLint; y: GLint; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
598 TglPixelStorei = procedure(pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
600 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}
601 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}
602 TglGetTexImage = procedure(target: GLenum; level: GLint; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
604 TgluBuild1DMipmaps = function(target: GLEnum; components, width: GLint; format, atype: GLEnum; const data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
605 TgluBuild2DMipmaps = function(target: GLEnum; components, width, height: GLint; format, atype: GLEnum; const Data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
607 {$ELSEIF DEFINED(GLB_NATIVE_OGL_STATIC)}
608 procedure glEnable(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
609 procedure glDisable(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
611 function glGetString(name: GLenum): PAnsiChar; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
612 procedure glGetIntegerv(pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
614 procedure glTexParameteri(target: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
615 procedure glTexParameteriv(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
616 procedure glTexParameterfv(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
617 procedure glGetTexParameteriv(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
618 procedure glGetTexParameterfv(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
619 procedure glGetTexLevelParameteriv(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
620 procedure glGetTexLevelParameterfv(target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
622 procedure glTexGeni(coord: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
623 procedure glGenTextures(n: GLsizei; textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
624 procedure glBindTexture(target: GLenum; texture: GLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
625 procedure glDeleteTextures(n: GLsizei; const textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
627 function glAreTexturesResident(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
628 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;
629 procedure glPixelStorei(pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
631 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;
632 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;
633 procedure glGetTexImage(target: GLenum; level: GLint; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
635 function gluBuild1DMipmaps(target: GLEnum; components, width: GLint; format, atype: GLEnum; const data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libglu;
636 function gluBuild2DMipmaps(target: GLEnum; components, width, height: GLint; format, atype: GLEnum; const Data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libglu;
646 GL_SGIS_generate_mipmap,
648 GL_ARB_texture_border_clamp,
649 GL_ARB_texture_mirrored_repeat,
650 GL_ARB_texture_rectangle,
651 GL_ARB_texture_non_power_of_two,
652 GL_ARB_texture_swizzle,
653 GL_ARB_texture_cube_map,
655 GL_IBM_texture_mirrored_repeat,
657 GL_NV_texture_rectangle,
659 GL_EXT_texture_edge_clamp,
660 GL_EXT_texture_rectangle,
661 GL_EXT_texture_swizzle,
662 GL_EXT_texture_cube_map,
663 GL_EXT_texture_filter_anisotropic: Boolean;
665 glCompressedTexImage1D: TglCompressedTexImage1D;
666 glCompressedTexImage2D: TglCompressedTexImage2D;
667 glGetCompressedTexImage: TglGetCompressedTexImage;
669 {$IF DEFINED(GLB_WIN)}
670 wglGetProcAddress: TwglGetProcAddress;
671 {$ELSEIF DEFINED(GLB_LINUX)}
672 glXGetProcAddress: TglXGetProcAddress;
673 glXGetProcAddressARB: TglXGetProcAddress;
676 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
678 glDisable: TglDisable;
680 glGetString: TglGetString;
681 glGetIntegerv: TglGetIntegerv;
683 glTexParameteri: TglTexParameteri;
684 glTexParameteriv: TglTexParameteriv;
685 glTexParameterfv: TglTexParameterfv;
686 glGetTexParameteriv: TglGetTexParameteriv;
687 glGetTexParameterfv: TglGetTexParameterfv;
688 glGetTexLevelParameteriv: TglGetTexLevelParameteriv;
689 glGetTexLevelParameterfv: TglGetTexLevelParameterfv;
691 glTexGeni: TglTexGeni;
692 glGenTextures: TglGenTextures;
693 glBindTexture: TglBindTexture;
694 glDeleteTextures: TglDeleteTextures;
696 glAreTexturesResident: TglAreTexturesResident;
697 glReadPixels: TglReadPixels;
698 glPixelStorei: TglPixelStorei;
700 glTexImage1D: TglTexImage1D;
701 glTexImage2D: TglTexImage2D;
702 glGetTexImage: TglGetTexImage;
704 gluBuild1DMipmaps: TgluBuild1DMipmaps;
705 gluBuild2DMipmaps: TgluBuild2DMipmaps;
710 ////////////////////////////////////////////////////////////////////////////////////////////////////
712 tfEmpty = 0, //must be smallest value!
728 tfLuminance12Alpha12,
729 tfLuminance16Alpha16,
773 TglBitmapFileType = (
774 {$IFDEF GLB_SUPPORT_PNG_WRITE} ftPNG, {$ENDIF}
775 {$IFDEF GLB_SUPPORT_JPEG_WRITE}ftJPEG, {$ENDIF}
779 TglBitmapFileTypes = set of TglBitmapFileType;
786 TglBitmapNormalMapFunc = (
792 ////////////////////////////////////////////////////////////////////////////////////////////////////
793 EglBitmap = class(Exception);
794 EglBitmapNotSupported = class(Exception);
795 EglBitmapSizeToLarge = class(EglBitmap);
796 EglBitmapNonPowerOfTwo = class(EglBitmap);
797 EglBitmapUnsupportedFormat = class(EglBitmap)
798 constructor Create(const aFormat: TglBitmapFormat); overload;
799 constructor Create(const aMsg: String; const aFormat: TglBitmapFormat); overload;
802 ////////////////////////////////////////////////////////////////////////////////////////////////////
803 TglBitmapColorRec = packed record
805 0: (r, g, b, a: Cardinal);
806 1: (arr: array[0..3] of Cardinal);
809 TglBitmapPixelData = packed record
810 Data, Range: TglBitmapColorRec;
811 Format: TglBitmapFormat;
813 PglBitmapPixelData = ^TglBitmapPixelData;
815 ////////////////////////////////////////////////////////////////////////////////////////////////////
816 TglBitmapPixelPositionFields = set of (ffX, ffY);
817 TglBitmapPixelPosition = record
818 Fields : TglBitmapPixelPositionFields;
823 TglBitmapFormatDescriptor = class(TObject)
825 function GetIsCompressed: Boolean; virtual; abstract;
826 function GetHasAlpha: Boolean; virtual; abstract;
828 function GetglDataFormat: GLenum; virtual; abstract;
829 function GetglFormat: GLenum; virtual; abstract;
830 function GetglInternalFormat: GLenum; virtual; abstract;
832 property IsCompressed: Boolean read GetIsCompressed;
833 property HasAlpha: Boolean read GetHasAlpha;
835 property glFormat: GLenum read GetglFormat;
836 property glInternalFormat: GLenum read GetglInternalFormat;
837 property glDataFormat: GLenum read GetglDataFormat;
840 ////////////////////////////////////////////////////////////////////////////////////////////////////
842 TglBitmapFunctionRec = record
844 Size: TglBitmapPixelPosition;
845 Position: TglBitmapPixelPosition;
846 Source: TglBitmapPixelData;
847 Dest: TglBitmapPixelData;
850 TglBitmapFunction = procedure(var FuncRec: TglBitmapFunctionRec);
852 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
855 function GetFormatDesc: TglBitmapFormatDescriptor;
859 fAnisotropic: Integer;
860 fDeleteTextureOnFree: Boolean;
861 fFreeDataAfterGenTexture: Boolean;
863 fIsResident: Boolean;
864 fBorderColor: array[0..3] of Single;
866 fDimension: TglBitmapPixelPosition;
867 fMipMap: TglBitmapMipMap;
868 fFormat: TglBitmapFormat;
884 fSwizzle: array[0..3] of GLenum;
889 fCustomNameW: WideString;
890 fCustomData: Pointer;
893 function GetWidth: Integer; virtual;
894 function GetHeight: Integer; virtual;
896 function GetFileWidth: Integer; virtual;
897 function GetFileHeight: Integer; virtual;
900 procedure SetCustomData(const aValue: Pointer);
901 procedure SetCustomName(const aValue: String);
902 procedure SetCustomNameW(const aValue: WideString);
903 procedure SetDeleteTextureOnFree(const aValue: Boolean);
904 procedure SetFormat(const aValue: TglBitmapFormat);
905 procedure SetFreeDataAfterGenTexture(const aValue: Boolean);
906 procedure SetID(const aValue: Cardinal);
907 procedure SetMipMap(const aValue: TglBitmapMipMap);
908 procedure SetTarget(const aValue: Cardinal);
909 procedure SetAnisotropic(const aValue: Integer);
912 procedure SetupParameters(out aBuildWithGlu: Boolean);
913 procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
914 const aWidth: Integer = -1; const aHeight: Integer = -1); virtual; //be careful, aData could be freed by this method
915 procedure GenTexture(const aTestTextureSize: Boolean = true); virtual; abstract;
917 function FlipHorz: Boolean; virtual;
918 function FlipVert: Boolean; virtual;
920 property Width: Integer read GetWidth;
921 property Height: Integer read GetHeight;
923 property FileWidth: Integer read GetFileWidth;
924 property FileHeight: Integer read GetFileHeight;
927 property ID: Cardinal read fID write SetID;
928 property Target: Cardinal read fTarget write SetTarget;
929 property Format: TglBitmapFormat read fFormat write SetFormat;
930 property MipMap: TglBitmapMipMap read fMipMap write SetMipMap;
931 property Anisotropic: Integer read fAnisotropic write SetAnisotropic;
933 property FormatDesc: TglBitmapFormatDescriptor read GetFormatDesc;
935 property Filename: String read fFilename;
936 property CustomName: String read fCustomName write SetCustomName;
937 property CustomNameW: WideString read fCustomNameW write SetCustomNameW;
938 property CustomData: Pointer read fCustomData write SetCustomData;
940 property DeleteTextureOnFree: Boolean read fDeleteTextureOnFree write SetDeleteTextureOnFree;
941 property FreeDataAfterGenTexture: Boolean read fFreeDataAfterGenTexture write SetFreeDataAfterGenTexture;
943 property Dimension: TglBitmapPixelPosition read fDimension;
944 property Data: PByte read fData;
945 property IsResident: Boolean read fIsResident;
947 procedure AfterConstruction; override;
948 procedure BeforeDestruction; override;
950 procedure PrepareResType(var aResource: String; var aResType: PChar);
953 procedure LoadFromFile(const aFilename: String);
954 procedure LoadFromStream(const aStream: TStream); virtual;
955 procedure LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
956 const aFormat: TglBitmapFormat; const aArgs: Pointer = nil);
957 procedure LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil);
958 procedure LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
961 procedure SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
962 procedure SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType); virtual;
965 function AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer = nil): Boolean; overload;
966 function AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
967 const aFormat: TglBitmapFormat; const aArgs: Pointer = nil): Boolean; overload;
971 function AssignToSurface(out aSurface: PSDL_Surface): Boolean;
972 function AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
973 function AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
974 function AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil;
975 const aArgs: Pointer = nil): Boolean;
979 function AssignToBitmap(const aBitmap: TBitmap): Boolean;
980 function AssignFromBitmap(const aBitmap: TBitmap): Boolean;
981 function AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
982 function AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction = nil;
983 const aArgs: Pointer = nil): Boolean;
987 function AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
988 function AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
989 function AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
990 function AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction = nil;
991 const aArgs: Pointer = nil): Boolean;
994 function AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil;
995 const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
996 function AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
997 const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
999 function AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer = nil): Boolean; virtual;
1000 function AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1001 function AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1002 function AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1004 function AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte = 0): Boolean;
1005 function AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal = 0): Boolean;
1006 function AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single = 0): Boolean;
1008 function AddAlphaFromValue(const aAlpha: Byte): Boolean;
1009 function AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
1010 function AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
1012 function RemoveAlpha: Boolean; virtual;
1015 function Clone: TglBitmap;
1016 function ConvertTo(const aFormat: TglBitmapFormat): Boolean; virtual;
1017 procedure Invert(const aUseRGB: Boolean = true; const aUseAlpha: Boolean = false);
1018 procedure SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
1022 procedure FillWithColor(const aRed, aGreen, aBlue: Byte; const aAlpha: Byte = 255);
1023 procedure FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal = $FFFFFFFF);
1024 procedure FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha : Single = 1);
1027 procedure SetFilter(const aMin, aMag: GLenum);
1029 const S: GLenum = GL_CLAMP_TO_EDGE;
1030 const T: GLenum = GL_CLAMP_TO_EDGE;
1031 const R: GLenum = GL_CLAMP_TO_EDGE);
1032 procedure SetSwizzle(const r, g, b, a: GLenum);
1034 procedure Bind(const aEnableTextureUnit: Boolean = true); virtual;
1035 procedure Unbind(const aDisableTextureUnit: Boolean = true); virtual;
1038 constructor Create; overload;
1039 constructor Create(const aFileName: String); overload;
1040 constructor Create(const aStream: TStream); overload;
1041 constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat); overload;
1042 constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer = nil); overload;
1043 constructor Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil); overload;
1044 constructor Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar); overload;
1046 {$IFDEF GLB_SUPPORT_PNG_READ} function LoadPNG(const aStream: TStream): Boolean; virtual; {$ENDIF}
1047 {$ifdef GLB_SUPPORT_PNG_WRITE} procedure SavePNG(const aStream: TStream); virtual; {$ENDIF}
1049 {$IFDEF GLB_SUPPORT_JPEG_READ} function LoadJPEG(const aStream: TStream): Boolean; virtual; {$ENDIF}
1050 {$IFDEF GLB_SUPPORT_JPEG_WRITE} procedure SaveJPEG(const aStream: TStream); virtual; {$ENDIF}
1052 function LoadBMP(const aStream: TStream): Boolean; virtual;
1053 procedure SaveBMP(const aStream: TStream); virtual;
1055 function LoadTGA(const aStream: TStream): Boolean; virtual;
1056 procedure SaveTGA(const aStream: TStream); virtual;
1058 function LoadDDS(const aStream: TStream): Boolean; virtual;
1059 procedure SaveDDS(const aStream: TStream); virtual;
1062 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1063 TglBitmap1D = class(TglBitmap)
1065 procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
1066 const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
1067 procedure UploadData(const aBuildWithGlu: Boolean);
1070 procedure AfterConstruction; override;
1071 function FlipHorz: Boolean; override;
1072 procedure GenTexture(const aTestTextureSize: Boolean = true); override;
1075 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1076 TglBitmap2D = class(TglBitmap)
1078 fLines: array of PByte;
1079 function GetScanline(const aIndex: Integer): Pointer;
1080 procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
1081 const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
1082 procedure UploadData(const aTarget: GLenum; const aBuildWithGlu: Boolean);
1086 property Scanline[const aIndex: Integer]: Pointer read GetScanline;
1088 procedure AfterConstruction; override;
1090 procedure GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
1091 procedure GetDataFromTexture;
1092 procedure GenTexture(const aTestTextureSize: Boolean = true); override;
1094 function FlipHorz: Boolean; override;
1095 function FlipVert: Boolean; override;
1097 procedure ToNormalMap(const aFunc: TglBitmapNormalMapFunc = nm3x3;
1098 const aScale: Single = 2; const aUseAlpha: Boolean = false);
1101 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1102 TglBitmapCubeMap = class(TglBitmap2D)
1105 procedure GenTexture(const aTestTextureSize: Boolean = true); reintroduce;
1107 procedure AfterConstruction; override;
1108 procedure GenerateCubeMap(const aCubeTarget: Cardinal; const aTestTextureSize: Boolean = true);
1109 procedure Bind(const aEnableTexCoordsGen: Boolean = true; const aEnableTextureUnit: Boolean = true); reintroduce; virtual;
1110 procedure Unbind(const aDisableTexCoordsGen: Boolean = true; const aDisableTextureUnit: Boolean = true); reintroduce; virtual;
1113 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1114 TglBitmapNormalMap = class(TglBitmapCubeMap)
1116 procedure AfterConstruction; override;
1117 procedure GenerateNormalMap(const aSize: Integer = 32; const aTestTextureSize: Boolean = true);
1121 NULL_SIZE: TglBitmapPixelPosition = (Fields: []; X: 0; Y: 0);
1123 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
1124 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
1125 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
1126 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
1127 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
1128 procedure glBitmapSetDefaultWrap(
1129 const S: Cardinal = GL_CLAMP_TO_EDGE;
1130 const T: Cardinal = GL_CLAMP_TO_EDGE;
1131 const R: Cardinal = GL_CLAMP_TO_EDGE);
1133 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
1134 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
1135 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
1136 function glBitmapGetDefaultFormat: TglBitmapFormat;
1137 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
1138 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
1140 function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
1141 function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
1142 function glBitmapColorRecCmp(const r1, r2: TglBitmapColorRec): Boolean;
1145 glBitmapDefaultDeleteTextureOnFree: Boolean;
1146 glBitmapDefaultFreeDataAfterGenTextures: Boolean;
1147 glBitmapDefaultFormat: TglBitmapFormat;
1148 glBitmapDefaultMipmap: TglBitmapMipMap;
1149 glBitmapDefaultFilterMin: Cardinal;
1150 glBitmapDefaultFilterMag: Cardinal;
1151 glBitmapDefaultWrapS: Cardinal;
1152 glBitmapDefaultWrapT: Cardinal;
1153 glBitmapDefaultWrapR: Cardinal;
1154 glDefaultSwizzle: array[0..3] of GLenum;
1157 function CreateGrayPalette: HPALETTE;
1163 Math, syncobjs, typinfo;
1167 QWord = System.UInt64;
1174 ////////////////////////////////////////////////////////////////////////////////////////////////////
1175 TShiftRec = packed record
1177 0: (r, g, b, a: Byte);
1178 1: (arr: array[0..3] of Byte);
1181 TFormatDescriptor = class(TglBitmapFormatDescriptor)
1183 function GetRedMask: QWord;
1184 function GetGreenMask: QWord;
1185 function GetBlueMask: QWord;
1186 function GetAlphaMask: QWord;
1188 fFormat: TglBitmapFormat;
1189 fWithAlpha: TglBitmapFormat;
1190 fWithoutAlpha: TglBitmapFormat;
1191 fRGBInverted: TglBitmapFormat;
1192 fUncompressed: TglBitmapFormat;
1194 fIsCompressed: Boolean;
1196 fRange: TglBitmapColorRec;
1200 fglInternalFormat: GLenum;
1201 fglDataFormat: GLenum;
1203 function GetIsCompressed: Boolean; override;
1204 function GetHasAlpha: Boolean; override;
1206 function GetglFormat: GLenum; override;
1207 function GetglInternalFormat: GLenum; override;
1208 function GetglDataFormat: GLenum; override;
1210 function GetComponents: Integer; virtual;
1212 property Format: TglBitmapFormat read fFormat;
1213 property WithAlpha: TglBitmapFormat read fWithAlpha;
1214 property WithoutAlpha: TglBitmapFormat read fWithoutAlpha;
1215 property RGBInverted: TglBitmapFormat read fRGBInverted;
1216 property Components: Integer read GetComponents;
1217 property PixelSize: Single read fPixelSize;
1219 property Range: TglBitmapColorRec read fRange;
1220 property Shift: TShiftRec read fShift;
1222 property RedMask: QWord read GetRedMask;
1223 property GreenMask: QWord read GetGreenMask;
1224 property BlueMask: QWord read GetBlueMask;
1225 property AlphaMask: QWord read GetAlphaMask;
1227 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); virtual; abstract;
1228 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract;
1230 function GetSize(const aSize: TglBitmapPixelPosition): Integer; overload; virtual;
1231 function GetSize(const aWidth, aHeight: Integer): Integer; overload; virtual;
1233 function CreateMappingData: Pointer; virtual;
1234 procedure FreeMappingData(var aMappingData: Pointer); virtual;
1236 function IsEmpty: Boolean; virtual;
1237 function MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: QWord): Boolean; virtual;
1239 procedure PreparePixel(out aPixel: TglBitmapPixelData); virtual;
1241 constructor Create; virtual;
1243 class procedure Init;
1244 class function Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
1245 class function GetWithAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
1246 class procedure Clear;
1247 class procedure Finalize;
1249 TFormatDescriptorClass = class of TFormatDescriptor;
1251 TfdEmpty = class(TFormatDescriptor);
1253 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1254 TfdAlpha_UB1 = class(TFormatDescriptor) //1* unsigned byte
1255 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1256 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1257 constructor Create; override;
1260 TfdLuminance_UB1 = class(TFormatDescriptor) //1* unsigned byte
1261 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1262 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1263 constructor Create; override;
1266 TfdUniversal_UB1 = class(TFormatDescriptor) //1* unsigned byte
1267 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1268 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1269 constructor Create; override;
1272 TfdLuminanceAlpha_UB2 = class(TfdLuminance_UB1) //2* unsigned byte
1273 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1274 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1275 constructor Create; override;
1278 TfdRGB_UB3 = class(TFormatDescriptor) //3* unsigned byte
1279 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1280 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1281 constructor Create; override;
1284 TfdBGR_UB3 = class(TFormatDescriptor) //3* unsigned byte (inverse)
1285 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1286 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1287 constructor Create; override;
1290 TfdRGBA_UB4 = class(TfdRGB_UB3) //4* unsigned byte
1291 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1292 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1293 constructor Create; override;
1296 TfdBGRA_UB4 = class(TfdBGR_UB3) //4* unsigned byte (inverse)
1297 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1298 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1299 constructor Create; override;
1302 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1303 TfdAlpha_US1 = class(TFormatDescriptor) //1* unsigned short
1304 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1305 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1306 constructor Create; override;
1309 TfdLuminance_US1 = class(TFormatDescriptor) //1* unsigned short
1310 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1311 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1312 constructor Create; override;
1315 TfdUniversal_US1 = class(TFormatDescriptor) //1* unsigned short
1316 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1317 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1318 constructor Create; override;
1321 TfdDepth_US1 = class(TFormatDescriptor) //1* unsigned short
1322 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1323 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1324 constructor Create; override;
1327 TfdLuminanceAlpha_US2 = class(TfdLuminance_US1) //2* unsigned short
1328 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1329 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1330 constructor Create; override;
1333 TfdRGB_US3 = class(TFormatDescriptor) //3* unsigned short
1334 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1335 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1336 constructor Create; override;
1339 TfdBGR_US3 = class(TFormatDescriptor) //3* unsigned short (inverse)
1340 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1341 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1342 constructor Create; override;
1345 TfdRGBA_US4 = class(TfdRGB_US3) //4* unsigned short
1346 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1347 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1348 constructor Create; override;
1351 TfdBGRA_US4 = class(TfdBGR_US3) //4* unsigned short (inverse)
1352 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1353 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1354 constructor Create; override;
1357 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1358 TfdUniversal_UI1 = class(TFormatDescriptor) //1* unsigned int
1359 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1360 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1361 constructor Create; override;
1364 TfdDepth_UI1 = class(TFormatDescriptor) //1* unsigned int
1365 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1366 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1367 constructor Create; override;
1370 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1371 TfdAlpha4 = class(TfdAlpha_UB1)
1372 constructor Create; override;
1375 TfdAlpha8 = class(TfdAlpha_UB1)
1376 constructor Create; override;
1379 TfdAlpha12 = class(TfdAlpha_US1)
1380 constructor Create; override;
1383 TfdAlpha16 = class(TfdAlpha_US1)
1384 constructor Create; override;
1387 TfdLuminance4 = class(TfdLuminance_UB1)
1388 constructor Create; override;
1391 TfdLuminance8 = class(TfdLuminance_UB1)
1392 constructor Create; override;
1395 TfdLuminance12 = class(TfdLuminance_US1)
1396 constructor Create; override;
1399 TfdLuminance16 = class(TfdLuminance_US1)
1400 constructor Create; override;
1403 TfdLuminance4Alpha4 = class(TfdLuminanceAlpha_UB2)
1404 constructor Create; override;
1407 TfdLuminance6Alpha2 = class(TfdLuminanceAlpha_UB2)
1408 constructor Create; override;
1411 TfdLuminance8Alpha8 = class(TfdLuminanceAlpha_UB2)
1412 constructor Create; override;
1415 TfdLuminance12Alpha4 = class(TfdLuminanceAlpha_US2)
1416 constructor Create; override;
1419 TfdLuminance12Alpha12 = class(TfdLuminanceAlpha_US2)
1420 constructor Create; override;
1423 TfdLuminance16Alpha16 = class(TfdLuminanceAlpha_US2)
1424 constructor Create; override;
1427 TfdR3G3B2 = class(TfdUniversal_UB1)
1428 constructor Create; override;
1431 TfdRGB4 = class(TfdUniversal_US1)
1432 constructor Create; override;
1435 TfdR5G6B5 = class(TfdUniversal_US1)
1436 constructor Create; override;
1439 TfdRGB5 = class(TfdUniversal_US1)
1440 constructor Create; override;
1443 TfdRGB8 = class(TfdRGB_UB3)
1444 constructor Create; override;
1447 TfdRGB10 = class(TfdUniversal_UI1)
1448 constructor Create; override;
1451 TfdRGB12 = class(TfdRGB_US3)
1452 constructor Create; override;
1455 TfdRGB16 = class(TfdRGB_US3)
1456 constructor Create; override;
1459 TfdRGBA2 = class(TfdRGBA_UB4)
1460 constructor Create; override;
1463 TfdRGBA4 = class(TfdUniversal_US1)
1464 constructor Create; override;
1467 TfdRGB5A1 = class(TfdUniversal_US1)
1468 constructor Create; override;
1471 TfdRGBA8 = class(TfdRGBA_UB4)
1472 constructor Create; override;
1475 TfdRGB10A2 = class(TfdUniversal_UI1)
1476 constructor Create; override;
1479 TfdRGBA12 = class(TfdRGBA_US4)
1480 constructor Create; override;
1483 TfdRGBA16 = class(TfdRGBA_US4)
1484 constructor Create; override;
1487 TfdBGR4 = class(TfdUniversal_US1)
1488 constructor Create; override;
1491 TfdB5G6R5 = class(TfdUniversal_US1)
1492 constructor Create; override;
1495 TfdBGR5 = class(TfdUniversal_US1)
1496 constructor Create; override;
1499 TfdBGR8 = class(TfdBGR_UB3)
1500 constructor Create; override;
1503 TfdBGR10 = class(TfdUniversal_UI1)
1504 constructor Create; override;
1507 TfdBGR12 = class(TfdBGR_US3)
1508 constructor Create; override;
1511 TfdBGR16 = class(TfdBGR_US3)
1512 constructor Create; override;
1515 TfdBGRA2 = class(TfdBGRA_UB4)
1516 constructor Create; override;
1519 TfdBGRA4 = class(TfdUniversal_US1)
1520 constructor Create; override;
1523 TfdBGR5A1 = class(TfdUniversal_US1)
1524 constructor Create; override;
1527 TfdBGRA8 = class(TfdBGRA_UB4)
1528 constructor Create; override;
1531 TfdBGR10A2 = class(TfdUniversal_UI1)
1532 constructor Create; override;
1535 TfdBGRA12 = class(TfdBGRA_US4)
1536 constructor Create; override;
1539 TfdBGRA16 = class(TfdBGRA_US4)
1540 constructor Create; override;
1543 TfdDepth16 = class(TfdDepth_US1)
1544 constructor Create; override;
1547 TfdDepth24 = class(TfdDepth_UI1)
1548 constructor Create; override;
1551 TfdDepth32 = class(TfdDepth_UI1)
1552 constructor Create; override;
1555 TfdS3tcDtx1RGBA = class(TFormatDescriptor)
1556 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1557 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1558 constructor Create; override;
1561 TfdS3tcDtx3RGBA = class(TFormatDescriptor)
1562 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1563 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1564 constructor Create; override;
1567 TfdS3tcDtx5RGBA = class(TFormatDescriptor)
1568 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1569 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1570 constructor Create; override;
1573 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1574 TbmpBitfieldFormat = class(TFormatDescriptor)
1576 procedure SetRedMask (const aValue: QWord);
1577 procedure SetGreenMask(const aValue: QWord);
1578 procedure SetBlueMask (const aValue: QWord);
1579 procedure SetAlphaMask(const aValue: QWord);
1581 procedure Update(aMask: QWord; out aRange: Cardinal; out aShift: Byte);
1583 property RedMask: QWord read GetRedMask write SetRedMask;
1584 property GreenMask: QWord read GetGreenMask write SetGreenMask;
1585 property BlueMask: QWord read GetBlueMask write SetBlueMask;
1586 property AlphaMask: QWord read GetAlphaMask write SetAlphaMask;
1588 property PixelSize: Single read fPixelSize write fPixelSize;
1590 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1591 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1594 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1595 TbmpColorTableEnty = packed record
1598 TbmpColorTable = array of TbmpColorTableEnty;
1599 TbmpColorTableFormat = class(TFormatDescriptor)
1601 fColorTable: TbmpColorTable;
1603 property PixelSize: Single read fPixelSize write fPixelSize;
1604 property ColorTable: TbmpColorTable read fColorTable write fColorTable;
1605 property Range: TglBitmapColorRec read fRange write fRange;
1606 property Shift: TShiftRec read fShift write fShift;
1607 property Format: TglBitmapFormat read fFormat write fFormat;
1609 procedure CreateColorTable;
1611 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1612 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1613 destructor Destroy; override;
1617 LUMINANCE_WEIGHT_R = 0.30;
1618 LUMINANCE_WEIGHT_G = 0.59;
1619 LUMINANCE_WEIGHT_B = 0.11;
1621 ALPHA_WEIGHT_R = 0.30;
1622 ALPHA_WEIGHT_G = 0.59;
1623 ALPHA_WEIGHT_B = 0.11;
1625 DEPTH_WEIGHT_R = 0.333333333;
1626 DEPTH_WEIGHT_G = 0.333333333;
1627 DEPTH_WEIGHT_B = 0.333333333;
1629 UNSUPPORTED_FORMAT = 'the given format isn''t supported by this function.';
1631 FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
1644 TfdLuminance4Alpha4,
1645 TfdLuminance6Alpha2,
1646 TfdLuminance8Alpha8,
1647 TfdLuminance12Alpha4,
1648 TfdLuminance12Alpha12,
1649 TfdLuminance16Alpha16,
1694 FormatDescriptorCS: TCriticalSection;
1695 FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
1697 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1698 constructor EglBitmapUnsupportedFormat.Create(const aFormat: TglBitmapFormat);
1700 inherited Create('unsupported format: ' + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1703 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1704 constructor EglBitmapUnsupportedFormat.Create(const aMsg: String; const aFormat: TglBitmapFormat);
1706 inherited Create(aMsg + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1709 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1710 function glBitmapPosition(X, Y: Integer): TglBitmapPixelPosition;
1712 result.Fields := [];
1715 result.Fields := result.Fields + [ffX];
1717 result.Fields := result.Fields + [ffY];
1719 result.X := Max(0, X);
1720 result.Y := Max(0, Y);
1723 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1724 function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
1732 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1733 function glBitmapColorRecCmp(const r1, r2: TglBitmapColorRec): Boolean;
1738 for i := 0 to high(r1.arr) do
1739 if (r1.arr[i] <> r2.arr[i]) then
1744 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1745 function glBitmapShiftRec(const r, g, b, a: Byte): TShiftRec;
1753 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1754 function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
1763 tfR3G3B2, tfLuminance8,
1766 tfRGB4, tfRGB5, tfR5G6B5, tfRGB5A1, tfRGBA4,
1767 tfBGR4, tfBGR5, tfB5G6R5, tfBGR5A1, tfBGRA4,
1773 tfRGB10, tfRGB10A2, tfRGBA8,
1774 tfBGR10, tfBGR10A2, tfBGRA8]) then
1775 result := result + [ftBMP];
1779 tfLuminance8, tfAlpha8,
1782 tfLuminance16, tfLuminance8Alpha8,
1783 tfRGB5, tfRGB5A1, tfRGBA4,
1784 tfBGR5, tfBGR5A1, tfBGRA4,
1790 tfRGB10A2, tfRGBA8, tfBGR10A2, tfBGRA8]) then
1791 result := result + [ftTGA];
1795 tfAlpha8, tfLuminance8, tfLuminance4Alpha4, tfLuminance6Alpha2,
1796 tfR3G3B2, tfRGBA2, tfBGRA2,
1799 tfAlpha16, tfLuminance16, tfLuminance8Alpha8, tfLuminance12Alpha4,
1800 tfRGB4, tfR5G6B5, tfRGB5, tfRGBA4, tfRGB5A1,
1801 tfBGR4, tfB5G6R5, tfBGR5, tfBGRA4, tfBGR5A1,
1807 tfLuminance16Alpha16,
1812 tfS3tcDtx1RGBA, tfS3tcDtx3RGBA, tfS3tcDtx5RGBA]) then
1813 result := result + [ftDDS];
1815 {$IFDEF GLB_SUPPORT_PNG_WRITE}
1817 tfAlpha8, tfLuminance8, tfLuminance8Alpha8,
1819 tfBGR8, tfBGRA8] then
1820 result := result + [ftPNG];
1823 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
1824 if aFormat in [tfAlpha8, tfLuminance8, tfRGB8, tfBGR8] then
1825 result := result + [ftJPEG];
1829 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1830 function IsPowerOfTwo(aNumber: Integer): Boolean;
1832 while (aNumber and 1) = 0 do
1833 aNumber := aNumber shr 1;
1834 result := aNumber = 1;
1837 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1838 function GetTopMostBit(aBitSet: QWord): Integer;
1841 while aBitSet > 0 do begin
1843 aBitSet := aBitSet shr 1;
1847 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1848 function CountSetBits(aBitSet: QWord): Integer;
1851 while aBitSet > 0 do begin
1852 if (aBitSet and 1) = 1 then
1854 aBitSet := aBitSet shr 1;
1858 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1859 function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
1862 LUMINANCE_WEIGHT_R * aPixel.Data.r +
1863 LUMINANCE_WEIGHT_G * aPixel.Data.g +
1864 LUMINANCE_WEIGHT_B * aPixel.Data.b);
1867 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1868 function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
1871 DEPTH_WEIGHT_R * aPixel.Data.r +
1872 DEPTH_WEIGHT_G * aPixel.Data.g +
1873 DEPTH_WEIGHT_B * aPixel.Data.b);
1876 {$IFDEF GLB_NATIVE_OGL}
1877 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1878 //OpenGLInitialization///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1879 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1881 GL_LibHandle: Pointer = nil;
1883 function glbGetProcAddress(aProcName: PChar; aLibHandle: Pointer = nil): Pointer;
1885 if not Assigned(aLibHandle) then
1886 aLibHandle := GL_LibHandle;
1888 {$IF DEFINED(GLB_WIN)}
1889 result := GetProcAddress({%H-}HMODULE(aLibHandle), aProcName);
1890 if Assigned(result) then
1893 if Assigned(wglGetProcAddress) then
1894 result := wglGetProcAddress(aProcName);
1895 {$ELSEIF DEFINED(GLB_LINUX)}
1896 if Assigned(glXGetProcAddress) then begin
1897 result := glXGetProcAddress(aProcName);
1898 if Assigned(result) then
1902 if Assigned(glXGetProcAddressARB) then begin
1903 result := glXGetProcAddressARB(aProcName);
1904 if Assigned(result) then
1908 result := dlsym(aLibHandle, aProcName);
1910 if not Assigned(result) then
1911 raise EglBitmap.Create('unable to load procedure form library: ' + aProcName);
1914 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
1916 GLU_LibHandle: Pointer = nil;
1917 OpenGLInitialized: Boolean;
1918 InitOpenGLCS: TCriticalSection;
1920 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1921 procedure glbInitOpenGL;
1923 ////////////////////////////////////////////////////////////////////////////////
1924 function glbLoadLibrary(const aName: PChar): Pointer;
1926 {$IF DEFINED(GLB_WIN)}
1927 result := {%H-}Pointer(LoadLibrary(aName));
1928 {$ELSEIF DEFINED(GLB_LINUX)}
1929 result := dlopen(Name, RTLD_LAZY);
1935 ////////////////////////////////////////////////////////////////////////////////
1936 function glbFreeLibrary(const aLibHandle: Pointer): Boolean;
1939 if not Assigned(aLibHandle) then
1942 {$IF DEFINED(GLB_WIN)}
1943 Result := FreeLibrary({%H-}HINST(aLibHandle));
1944 {$ELSEIF DEFINED(GLB_LINUX)}
1945 Result := dlclose(aLibHandle) = 0;
1950 if Assigned(GL_LibHandle) then
1951 glbFreeLibrary(GL_LibHandle);
1953 if Assigned(GLU_LibHandle) then
1954 glbFreeLibrary(GLU_LibHandle);
1956 GL_LibHandle := glbLoadLibrary(libopengl);
1957 if not Assigned(GL_LibHandle) then
1958 raise EglBitmap.Create('unable to load library: ' + libopengl);
1960 GLU_LibHandle := glbLoadLibrary(libglu);
1961 if not Assigned(GLU_LibHandle) then
1962 raise EglBitmap.Create('unable to load library: ' + libglu);
1965 {$IF DEFINED(GLB_WIN)}
1966 wglGetProcAddress := glbGetProcAddress('wglGetProcAddress');
1967 {$ELSEIF DEFINED(GLB_LINUX)}
1968 glXGetProcAddress := glbGetProcAddress('glXGetProcAddress');
1969 glXGetProcAddressARB := glbGetProcAddress('glXGetProcAddressARB');
1972 glEnable := glbGetProcAddress('glEnable');
1973 glDisable := glbGetProcAddress('glDisable');
1974 glGetString := glbGetProcAddress('glGetString');
1975 glGetIntegerv := glbGetProcAddress('glGetIntegerv');
1976 glTexParameteri := glbGetProcAddress('glTexParameteri');
1977 glTexParameteriv := glbGetProcAddress('glTexParameteriv');
1978 glTexParameterfv := glbGetProcAddress('glTexParameterfv');
1979 glGetTexParameteriv := glbGetProcAddress('glGetTexParameteriv');
1980 glGetTexParameterfv := glbGetProcAddress('glGetTexParameterfv');
1981 glGetTexLevelParameteriv := glbGetProcAddress('glGetTexLevelParameteriv');
1982 glGetTexLevelParameterfv := glbGetProcAddress('glGetTexLevelParameterfv');
1983 glTexGeni := glbGetProcAddress('glTexGeni');
1984 glGenTextures := glbGetProcAddress('glGenTextures');
1985 glBindTexture := glbGetProcAddress('glBindTexture');
1986 glDeleteTextures := glbGetProcAddress('glDeleteTextures');
1987 glAreTexturesResident := glbGetProcAddress('glAreTexturesResident');
1988 glReadPixels := glbGetProcAddress('glReadPixels');
1989 glPixelStorei := glbGetProcAddress('glPixelStorei');
1990 glTexImage1D := glbGetProcAddress('glTexImage1D');
1991 glTexImage2D := glbGetProcAddress('glTexImage2D');
1992 glGetTexImage := glbGetProcAddress('glGetTexImage');
1994 gluBuild1DMipmaps := glbGetProcAddress('gluBuild1DMipmaps', GLU_LibHandle);
1995 gluBuild2DMipmaps := glbGetProcAddress('gluBuild2DMipmaps', GLU_LibHandle);
1997 glbFreeLibrary(GL_LibHandle);
1998 glbFreeLibrary(GLU_LibHandle);
2003 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2004 procedure glbReadOpenGLExtensions;
2007 MajorVersion, MinorVersion: Integer;
2009 ///////////////////////////////////////////////////////////////////////////////////////////
2010 procedure TrimVersionString(aBuffer: AnsiString; out aMajor, aMinor: Integer);
2017 Separator := Pos(AnsiString('.'), aBuffer);
2018 if (Separator > 1) and (Separator < Length(aBuffer)) and
2019 (aBuffer[Separator - 1] in ['0'..'9']) and
2020 (aBuffer[Separator + 1] in ['0'..'9']) then begin
2023 while (Separator > 0) and (aBuffer[Separator] in ['0'..'9']) do
2026 Delete(aBuffer, 1, Separator);
2027 Separator := Pos(AnsiString('.'), aBuffer) + 1;
2029 while (Separator <= Length(aBuffer)) and (AnsiChar(aBuffer[Separator]) in ['0'..'9']) do
2032 Delete(aBuffer, Separator, 255);
2033 Separator := Pos(AnsiString('.'), aBuffer);
2035 aMajor := StrToInt(Copy(String(aBuffer), 1, Separator - 1));
2036 aMinor := StrToInt(Copy(String(aBuffer), Separator + 1, 1));
2040 ///////////////////////////////////////////////////////////////////////////////////////////
2041 function CheckExtension(const Extension: AnsiString): Boolean;
2045 ExtPos := Pos(Extension, Buffer);
2046 result := ExtPos > 0;
2048 result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
2051 ///////////////////////////////////////////////////////////////////////////////////////////
2052 function CheckVersion(const aMajor, aMinor: Integer): Boolean;
2054 result := (MajorVersion > aMajor) or ((MajorVersion = aMajor) and (MinorVersion >= aMinor));
2058 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
2061 if not OpenGLInitialized then begin
2063 OpenGLInitialized := true;
2071 Buffer := glGetString(GL_VERSION);
2072 TrimVersionString(Buffer, MajorVersion, MinorVersion);
2074 GL_VERSION_1_2 := CheckVersion(1, 2);
2075 GL_VERSION_1_3 := CheckVersion(1, 3);
2076 GL_VERSION_1_4 := CheckVersion(1, 4);
2077 GL_VERSION_2_0 := CheckVersion(2, 0);
2078 GL_VERSION_3_3 := CheckVersion(3, 3);
2081 Buffer := glGetString(GL_EXTENSIONS);
2082 GL_ARB_texture_border_clamp := CheckExtension('GL_ARB_texture_border_clamp');
2083 GL_ARB_texture_non_power_of_two := CheckExtension('GL_ARB_texture_non_power_of_two');
2084 GL_ARB_texture_swizzle := CheckExtension('GL_ARB_texture_swizzle');
2085 GL_ARB_texture_cube_map := CheckExtension('GL_ARB_texture_cube_map');
2086 GL_ARB_texture_rectangle := CheckExtension('GL_ARB_texture_rectangle');
2087 GL_ARB_texture_mirrored_repeat := CheckExtension('GL_ARB_texture_mirrored_repeat');
2088 GL_EXT_texture_edge_clamp := CheckExtension('GL_EXT_texture_edge_clamp');
2089 GL_EXT_texture_filter_anisotropic := CheckExtension('GL_EXT_texture_filter_anisotropic');
2090 GL_EXT_texture_rectangle := CheckExtension('GL_EXT_texture_rectangle');
2091 GL_EXT_texture_swizzle := CheckExtension('GL_EXT_texture_swizzle');
2092 GL_EXT_texture_cube_map := CheckExtension('GL_EXT_texture_cube_map');
2093 GL_NV_texture_rectangle := CheckExtension('GL_NV_texture_rectangle');
2094 GL_IBM_texture_mirrored_repeat := CheckExtension('GL_IBM_texture_mirrored_repeat');
2095 GL_SGIS_generate_mipmap := CheckExtension('GL_SGIS_generate_mipmap');
2097 if GL_VERSION_1_3 then begin
2098 glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1D');
2099 glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2D');
2100 glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImage');
2102 glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1DARB');
2103 glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2DARB');
2104 glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImageARB');
2109 {$IFDEF GLB_SDL_IMAGE}
2110 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2111 // SDL Image Helper /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2112 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2113 function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
2115 result := TStream(context^.unknown.data1).Seek(offset, whence);
2118 function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
2120 result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
2123 function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
2125 result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
2128 function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
2133 function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
2135 result := SDL_AllocRW;
2137 if result = nil then
2138 raise EglBitmapException.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
2140 result^.seek := glBitmapRWseek;
2141 result^.read := glBitmapRWread;
2142 result^.write := glBitmapRWwrite;
2143 result^.close := glBitmapRWclose;
2144 result^.unknown.data1 := Stream;
2148 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2149 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
2151 glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
2154 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2155 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
2157 glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
2160 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2161 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
2163 glBitmapDefaultMipmap := aValue;
2166 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2167 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
2169 glBitmapDefaultFormat := aFormat;
2172 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2173 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
2175 glBitmapDefaultFilterMin := aMin;
2176 glBitmapDefaultFilterMag := aMag;
2179 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2180 procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
2182 glBitmapDefaultWrapS := S;
2183 glBitmapDefaultWrapT := T;
2184 glBitmapDefaultWrapR := R;
2187 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2188 procedure glBitmapSetDefaultSwizzle(const r: GLenum = GL_RED; g: GLenum = GL_GREEN; b: GLenum = GL_BLUE; a: GLenum = GL_ALPHA);
2190 glDefaultSwizzle[0] := r;
2191 glDefaultSwizzle[1] := g;
2192 glDefaultSwizzle[2] := b;
2193 glDefaultSwizzle[3] := a;
2196 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2197 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
2199 result := glBitmapDefaultDeleteTextureOnFree;
2202 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2203 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
2205 result := glBitmapDefaultFreeDataAfterGenTextures;
2208 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2209 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
2211 result := glBitmapDefaultMipmap;
2214 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2215 function glBitmapGetDefaultFormat: TglBitmapFormat;
2217 result := glBitmapDefaultFormat;
2220 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2221 procedure glBitmapGetDefaultFilter(var aMin, aMag: GLenum);
2223 aMin := glBitmapDefaultFilterMin;
2224 aMag := glBitmapDefaultFilterMag;
2227 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2228 procedure glBitmapGetDefaultTextureWrap(var S, T, R: GLenum);
2230 S := glBitmapDefaultWrapS;
2231 T := glBitmapDefaultWrapT;
2232 R := glBitmapDefaultWrapR;
2235 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2236 procedure glBitmapGetDefaultSwizzle(var r, g, b, a: GLenum);
2238 r := glDefaultSwizzle[0];
2239 g := glDefaultSwizzle[1];
2240 b := glDefaultSwizzle[2];
2241 a := glDefaultSwizzle[3];
2244 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2245 //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2246 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2247 function TFormatDescriptor.GetRedMask: QWord;
2249 result := fRange.r shl fShift.r;
2252 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2253 function TFormatDescriptor.GetGreenMask: QWord;
2255 result := fRange.g shl fShift.g;
2258 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2259 function TFormatDescriptor.GetBlueMask: QWord;
2261 result := fRange.b shl fShift.b;
2264 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2265 function TFormatDescriptor.GetAlphaMask: QWord;
2267 result := fRange.a shl fShift.a;
2270 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2271 function TFormatDescriptor.GetIsCompressed: Boolean;
2273 result := fIsCompressed;
2276 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2277 function TFormatDescriptor.GetHasAlpha: Boolean;
2279 result := (fRange.a > 0);
2282 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2283 function TFormatDescriptor.GetglFormat: GLenum;
2285 result := fglFormat;
2288 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2289 function TFormatDescriptor.GetglInternalFormat: GLenum;
2291 result := fglInternalFormat;
2294 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2295 function TFormatDescriptor.GetglDataFormat: GLenum;
2297 result := fglDataFormat;
2300 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2301 function TFormatDescriptor.GetComponents: Integer;
2307 if (fRange.arr[i] > 0) then
2311 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2312 function TFormatDescriptor.GetSize(const aSize: TglBitmapPixelPosition): Integer;
2316 if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
2317 w := Max(1, aSize.X);
2318 h := Max(1, aSize.Y);
2319 result := GetSize(w, h);
2324 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2325 function TFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer;
2328 if (aWidth <= 0) or (aHeight <= 0) then
2330 result := Ceil(aWidth * aHeight * fPixelSize);
2333 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2334 function TFormatDescriptor.CreateMappingData: Pointer;
2339 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2340 procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
2345 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2346 function TFormatDescriptor.IsEmpty: Boolean;
2348 result := (fFormat = tfEmpty);
2351 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2352 function TFormatDescriptor.MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: QWord): Boolean;
2355 if (aRedMask = 0) and (aGreenMask = 0) and (aBlueMask = 0) and (aAlphaMask = 0) then
2356 raise EglBitmap.Create('FormatCheckFormat - All Masks are 0');
2357 if (aRedMask <> RedMask) then
2359 if (aGreenMask <> GreenMask) then
2361 if (aBlueMask <> BlueMask) then
2363 if (aAlphaMask <> AlphaMask) then
2368 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2369 procedure TFormatDescriptor.PreparePixel(out aPixel: TglBitmapPixelData);
2371 FillChar(aPixel{%H-}, SizeOf(aPixel), 0);
2372 aPixel.Data := fRange;
2373 aPixel.Range := fRange;
2374 aPixel.Format := fFormat;
2377 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2378 constructor TFormatDescriptor.Create;
2383 fWithAlpha := tfEmpty;
2384 fWithoutAlpha := tfEmpty;
2385 fRGBInverted := tfEmpty;
2386 fUncompressed := tfEmpty;
2388 fIsCompressed := false;
2391 fglInternalFormat := 0;
2394 FillChar(fRange, 0, SizeOf(fRange));
2395 FillChar(fShift, 0, SizeOf(fShift));
2398 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2399 //TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2400 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2401 procedure TfdAlpha_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2403 aData^ := aPixel.Data.a;
2407 procedure TfdAlpha_UB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2412 aPixel.Data.a := aData^;
2416 constructor TfdAlpha_UB1.Create;
2421 fglFormat := GL_ALPHA;
2422 fglDataFormat := GL_UNSIGNED_BYTE;
2425 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2426 //TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2427 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2428 procedure TfdLuminance_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2430 aData^ := LuminanceWeight(aPixel);
2434 procedure TfdLuminance_UB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2436 aPixel.Data.r := aData^;
2437 aPixel.Data.g := aData^;
2438 aPixel.Data.b := aData^;
2443 constructor TfdLuminance_UB1.Create;
2450 fglFormat := GL_LUMINANCE;
2451 fglDataFormat := GL_UNSIGNED_BYTE;
2454 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2455 //TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2456 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2457 procedure TfdUniversal_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2463 if (fRange.arr[i] > 0) then
2464 aData^ := aData^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2468 procedure TfdUniversal_UB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2473 aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and fRange.arr[i];
2477 constructor TfdUniversal_UB1.Create;
2483 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2484 //TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2485 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2486 procedure TfdLuminanceAlpha_UB2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2488 inherited Map(aPixel, aData, aMapData);
2489 aData^ := aPixel.Data.a;
2493 procedure TfdLuminanceAlpha_UB2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2495 inherited Unmap(aData, aPixel, aMapData);
2496 aPixel.Data.a := aData^;
2500 constructor TfdLuminanceAlpha_UB2.Create;
2506 fglFormat := GL_LUMINANCE_ALPHA;
2507 fglDataFormat := GL_UNSIGNED_BYTE;
2510 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2511 //TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2512 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2513 procedure TfdRGB_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2515 aData^ := aPixel.Data.r;
2517 aData^ := aPixel.Data.g;
2519 aData^ := aPixel.Data.b;
2523 procedure TfdRGB_UB3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2525 aPixel.Data.r := aData^;
2527 aPixel.Data.g := aData^;
2529 aPixel.Data.b := aData^;
2534 constructor TfdRGB_UB3.Create;
2544 fglFormat := GL_RGB;
2545 fglDataFormat := GL_UNSIGNED_BYTE;
2548 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2549 //TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2550 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2551 procedure TfdBGR_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2553 aData^ := aPixel.Data.b;
2555 aData^ := aPixel.Data.g;
2557 aData^ := aPixel.Data.r;
2561 procedure TfdBGR_UB3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2563 aPixel.Data.b := aData^;
2565 aPixel.Data.g := aData^;
2567 aPixel.Data.r := aData^;
2572 constructor TfdBGR_UB3.Create;
2581 fglFormat := GL_BGR;
2582 fglDataFormat := GL_UNSIGNED_BYTE;
2585 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2586 //TdfRGBA_UB4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2587 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2588 procedure TfdRGBA_UB4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2590 inherited Map(aPixel, aData, aMapData);
2591 aData^ := aPixel.Data.a;
2595 procedure TfdRGBA_UB4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2597 inherited Unmap(aData, aPixel, aMapData);
2598 aPixel.Data.a := aData^;
2602 constructor TfdRGBA_UB4.Create;
2608 fglFormat := GL_RGBA;
2609 fglDataFormat := GL_UNSIGNED_BYTE;
2612 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2613 //TfdBGRA_UB4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2614 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2615 procedure TfdBGRA_UB4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2617 inherited Map(aPixel, aData, aMapData);
2618 aData^ := aPixel.Data.a;
2622 procedure TfdBGRA_UB4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2624 inherited Unmap(aData, aPixel, aMapData);
2625 aPixel.Data.a := aData^;
2629 constructor TfdBGRA_UB4.Create;
2635 fglFormat := GL_BGRA;
2636 fglDataFormat := GL_UNSIGNED_BYTE;
2639 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2640 //TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2641 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2642 procedure TfdAlpha_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2644 PWord(aData)^ := aPixel.Data.a;
2648 procedure TfdAlpha_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2653 aPixel.Data.a := PWord(aData)^;
2657 constructor TfdAlpha_US1.Create;
2662 fglFormat := GL_ALPHA;
2663 fglDataFormat := GL_UNSIGNED_SHORT;
2666 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2667 //TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2668 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2669 procedure TfdLuminance_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2671 PWord(aData)^ := LuminanceWeight(aPixel);
2675 procedure TfdLuminance_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2677 aPixel.Data.r := PWord(aData)^;
2678 aPixel.Data.g := PWord(aData)^;
2679 aPixel.Data.b := PWord(aData)^;
2684 constructor TfdLuminance_US1.Create;
2691 fglFormat := GL_LUMINANCE;
2692 fglDataFormat := GL_UNSIGNED_SHORT;
2695 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2696 //TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2697 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2698 procedure TfdUniversal_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2704 if (fRange.arr[i] > 0) then
2705 PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2709 procedure TfdUniversal_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2714 aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and fRange.arr[i];
2718 constructor TfdUniversal_US1.Create;
2724 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2725 //TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2726 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2727 procedure TfdDepth_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2729 PWord(aData)^ := DepthWeight(aPixel);
2733 procedure TfdDepth_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2735 aPixel.Data.r := PWord(aData)^;
2736 aPixel.Data.g := PWord(aData)^;
2737 aPixel.Data.b := PWord(aData)^;
2742 constructor TfdDepth_US1.Create;
2749 fglFormat := GL_DEPTH_COMPONENT;
2750 fglDataFormat := GL_UNSIGNED_SHORT;
2753 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2754 //TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2755 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2756 procedure TfdLuminanceAlpha_US2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2758 inherited Map(aPixel, aData, aMapData);
2759 PWord(aData)^ := aPixel.Data.a;
2763 procedure TfdLuminanceAlpha_US2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2765 inherited Unmap(aData, aPixel, aMapData);
2766 aPixel.Data.a := PWord(aData)^;
2770 constructor TfdLuminanceAlpha_US2.Create;
2776 fglFormat := GL_LUMINANCE_ALPHA;
2777 fglDataFormat := GL_UNSIGNED_SHORT;
2780 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2781 //TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2782 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2783 procedure TfdRGB_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2785 PWord(aData)^ := aPixel.Data.r;
2787 PWord(aData)^ := aPixel.Data.g;
2789 PWord(aData)^ := aPixel.Data.b;
2793 procedure TfdRGB_US3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2795 aPixel.Data.r := PWord(aData)^;
2797 aPixel.Data.g := PWord(aData)^;
2799 aPixel.Data.b := PWord(aData)^;
2804 constructor TfdRGB_US3.Create;
2814 fglFormat := GL_RGB;
2815 fglDataFormat := GL_UNSIGNED_SHORT;
2818 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2819 //TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2820 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2821 procedure TfdBGR_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2823 PWord(aData)^ := aPixel.Data.b;
2825 PWord(aData)^ := aPixel.Data.g;
2827 PWord(aData)^ := aPixel.Data.r;
2831 procedure TfdBGR_US3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2833 aPixel.Data.b := PWord(aData)^;
2835 aPixel.Data.g := PWord(aData)^;
2837 aPixel.Data.r := PWord(aData)^;
2842 constructor TfdBGR_US3.Create;
2852 fglFormat := GL_BGR;
2853 fglDataFormat := GL_UNSIGNED_SHORT;
2856 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2857 //TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2858 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2859 procedure TfdRGBA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2861 inherited Map(aPixel, aData, aMapData);
2862 PWord(aData)^ := aPixel.Data.a;
2866 procedure TfdRGBA_US4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2868 inherited Unmap(aData, aPixel, aMapData);
2869 aPixel.Data.a := PWord(aData)^;
2873 constructor TfdRGBA_US4.Create;
2879 fglFormat := GL_RGBA;
2880 fglDataFormat := GL_UNSIGNED_SHORT;
2883 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2884 //TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2885 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2886 procedure TfdBGRA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2888 inherited Map(aPixel, aData, aMapData);
2889 PWord(aData)^ := aPixel.Data.a;
2893 procedure TfdBGRA_US4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2895 inherited Unmap(aData, aPixel, aMapData);
2896 aPixel.Data.a := PWord(aData)^;
2900 constructor TfdBGRA_US4.Create;
2906 fglFormat := GL_BGRA;
2907 fglDataFormat := GL_UNSIGNED_SHORT;
2910 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2911 //TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2912 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2913 procedure TfdUniversal_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2917 PCardinal(aData)^ := 0;
2919 if (fRange.arr[i] > 0) then
2920 PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2924 procedure TfdUniversal_UI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2929 aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and fRange.arr[i];
2933 constructor TfdUniversal_UI1.Create;
2939 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2940 //TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2941 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2942 procedure TfdDepth_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2944 PCardinal(aData)^ := DepthWeight(aPixel);
2948 procedure TfdDepth_UI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2950 aPixel.Data.r := PCardinal(aData)^;
2951 aPixel.Data.g := PCardinal(aData)^;
2952 aPixel.Data.b := PCardinal(aData)^;
2957 constructor TfdDepth_UI1.Create;
2961 fRange.r := $FFFFFFFF;
2962 fRange.g := $FFFFFFFF;
2963 fRange.b := $FFFFFFFF;
2964 fglFormat := GL_DEPTH_COMPONENT;
2965 fglDataFormat := GL_UNSIGNED_INT;
2968 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2969 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2970 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2971 constructor TfdAlpha4.Create;
2974 fFormat := tfAlpha4;
2975 fWithAlpha := tfAlpha4;
2976 fglInternalFormat := GL_ALPHA4;
2979 constructor TfdAlpha8.Create;
2982 fFormat := tfAlpha8;
2983 fWithAlpha := tfAlpha8;
2984 fglInternalFormat := GL_ALPHA8;
2987 constructor TfdAlpha12.Create;
2990 fFormat := tfAlpha12;
2991 fWithAlpha := tfAlpha12;
2992 fglInternalFormat := GL_ALPHA12;
2995 constructor TfdAlpha16.Create;
2998 fFormat := tfAlpha16;
2999 fWithAlpha := tfAlpha16;
3000 fglInternalFormat := GL_ALPHA16;
3003 constructor TfdLuminance4.Create;
3006 fFormat := tfLuminance4;
3007 fWithAlpha := tfLuminance4Alpha4;
3008 fWithoutAlpha := tfLuminance4;
3009 fglInternalFormat := GL_LUMINANCE4;
3012 constructor TfdLuminance8.Create;
3015 fFormat := tfLuminance8;
3016 fWithAlpha := tfLuminance8Alpha8;
3017 fWithoutAlpha := tfLuminance8;
3018 fglInternalFormat := GL_LUMINANCE8;
3021 constructor TfdLuminance12.Create;
3024 fFormat := tfLuminance12;
3025 fWithAlpha := tfLuminance12Alpha12;
3026 fWithoutAlpha := tfLuminance12;
3027 fglInternalFormat := GL_LUMINANCE12;
3030 constructor TfdLuminance16.Create;
3033 fFormat := tfLuminance16;
3034 fWithAlpha := tfLuminance16Alpha16;
3035 fWithoutAlpha := tfLuminance16;
3036 fglInternalFormat := GL_LUMINANCE16;
3039 constructor TfdLuminance4Alpha4.Create;
3042 fFormat := tfLuminance4Alpha4;
3043 fWithAlpha := tfLuminance4Alpha4;
3044 fWithoutAlpha := tfLuminance4;
3045 fglInternalFormat := GL_LUMINANCE4_ALPHA4;
3048 constructor TfdLuminance6Alpha2.Create;
3051 fFormat := tfLuminance6Alpha2;
3052 fWithAlpha := tfLuminance6Alpha2;
3053 fWithoutAlpha := tfLuminance8;
3054 fglInternalFormat := GL_LUMINANCE6_ALPHA2;
3057 constructor TfdLuminance8Alpha8.Create;
3060 fFormat := tfLuminance8Alpha8;
3061 fWithAlpha := tfLuminance8Alpha8;
3062 fWithoutAlpha := tfLuminance8;
3063 fglInternalFormat := GL_LUMINANCE8_ALPHA8;
3066 constructor TfdLuminance12Alpha4.Create;
3069 fFormat := tfLuminance12Alpha4;
3070 fWithAlpha := tfLuminance12Alpha4;
3071 fWithoutAlpha := tfLuminance12;
3072 fglInternalFormat := GL_LUMINANCE12_ALPHA4;
3075 constructor TfdLuminance12Alpha12.Create;
3078 fFormat := tfLuminance12Alpha12;
3079 fWithAlpha := tfLuminance12Alpha12;
3080 fWithoutAlpha := tfLuminance12;
3081 fglInternalFormat := GL_LUMINANCE12_ALPHA12;
3084 constructor TfdLuminance16Alpha16.Create;
3087 fFormat := tfLuminance16Alpha16;
3088 fWithAlpha := tfLuminance16Alpha16;
3089 fWithoutAlpha := tfLuminance16;
3090 fglInternalFormat := GL_LUMINANCE16_ALPHA16;
3093 constructor TfdR3G3B2.Create;
3096 fFormat := tfR3G3B2;
3097 fWithAlpha := tfRGBA2;
3098 fWithoutAlpha := tfR3G3B2;
3105 fglFormat := GL_RGB;
3106 fglInternalFormat := GL_R3_G3_B2;
3107 fglDataFormat := GL_UNSIGNED_BYTE_2_3_3_REV;
3110 constructor TfdRGB4.Create;
3114 fWithAlpha := tfRGBA4;
3115 fWithoutAlpha := tfRGB4;
3116 fRGBInverted := tfBGR4;
3123 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3124 fglInternalFormat := GL_RGB4;
3125 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3128 constructor TfdR5G6B5.Create;
3131 fFormat := tfR5G6B5;
3132 fWithAlpha := tfRGBA4;
3133 fWithoutAlpha := tfR5G6B5;
3134 fRGBInverted := tfB5G6R5;
3141 fglFormat := GL_RGB;
3142 fglInternalFormat := GL_RGB565;
3143 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5_REV;
3146 constructor TfdRGB5.Create;
3150 fWithAlpha := tfRGB5A1;
3151 fWithoutAlpha := tfRGB5;
3152 fRGBInverted := tfBGR5;
3159 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3160 fglInternalFormat := GL_RGB5;
3161 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3164 constructor TfdRGB8.Create;
3168 fWithAlpha := tfRGBA8;
3169 fWithoutAlpha := tfRGB8;
3170 fRGBInverted := tfBGR8;
3171 fglInternalFormat := GL_RGB8;
3174 constructor TfdRGB10.Create;
3178 fWithAlpha := tfRGB10A2;
3179 fWithoutAlpha := tfRGB10;
3180 fRGBInverted := tfBGR10;
3187 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3188 fglInternalFormat := GL_RGB10;
3189 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3192 constructor TfdRGB12.Create;
3196 fWithAlpha := tfRGBA12;
3197 fWithoutAlpha := tfRGB12;
3198 fRGBInverted := tfBGR12;
3199 fglInternalFormat := GL_RGB12;
3202 constructor TfdRGB16.Create;
3206 fWithAlpha := tfRGBA16;
3207 fWithoutAlpha := tfRGB16;
3208 fRGBInverted := tfBGR16;
3209 fglInternalFormat := GL_RGB16;
3212 constructor TfdRGBA2.Create;
3216 fWithAlpha := tfRGBA2;
3217 fWithoutAlpha := tfR3G3B2;
3218 fRGBInverted := tfBGRA2;
3219 fglInternalFormat := GL_RGBA2;
3222 constructor TfdRGBA4.Create;
3226 fWithAlpha := tfRGBA4;
3227 fWithoutAlpha := tfRGB4;
3228 fRGBInverted := tfBGRA4;
3237 fglFormat := GL_RGBA;
3238 fglInternalFormat := GL_RGBA4;
3239 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3242 constructor TfdRGB5A1.Create;
3245 fFormat := tfRGB5A1;
3246 fWithAlpha := tfRGB5A1;
3247 fWithoutAlpha := tfRGB5;
3248 fRGBInverted := tfBGR5A1;
3257 fglFormat := GL_RGBA;
3258 fglInternalFormat := GL_RGB5_A1;
3259 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3262 constructor TfdRGBA8.Create;
3266 fWithAlpha := tfRGBA8;
3267 fWithoutAlpha := tfRGB8;
3268 fRGBInverted := tfBGRA8;
3269 fglInternalFormat := GL_RGBA8;
3272 constructor TfdRGB10A2.Create;
3275 fFormat := tfRGB10A2;
3276 fWithAlpha := tfRGB10A2;
3277 fWithoutAlpha := tfRGB10;
3278 fRGBInverted := tfBGR10A2;
3287 fglFormat := GL_RGBA;
3288 fglInternalFormat := GL_RGB10_A2;
3289 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3292 constructor TfdRGBA12.Create;
3295 fFormat := tfRGBA12;
3296 fWithAlpha := tfRGBA12;
3297 fWithoutAlpha := tfRGB12;
3298 fRGBInverted := tfBGRA12;
3299 fglInternalFormat := GL_RGBA12;
3302 constructor TfdRGBA16.Create;
3305 fFormat := tfRGBA16;
3306 fWithAlpha := tfRGBA16;
3307 fWithoutAlpha := tfRGB16;
3308 fRGBInverted := tfBGRA16;
3309 fglInternalFormat := GL_RGBA16;
3312 constructor TfdBGR4.Create;
3317 fWithAlpha := tfBGRA4;
3318 fWithoutAlpha := tfBGR4;
3319 fRGBInverted := tfRGB4;
3328 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3329 fglInternalFormat := GL_RGB4;
3330 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3333 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3334 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3335 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3336 constructor TfdB5G6R5.Create;
3339 fFormat := tfB5G6R5;
3340 fWithAlpha := tfBGRA4;
3341 fWithoutAlpha := tfB5G6R5;
3342 fRGBInverted := tfR5G6B5;
3349 fglFormat := GL_RGB; //B5G6R5 is only possible as R5G6B5 -> use reverted dataformat
3350 fglInternalFormat := GL_RGB8;
3351 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5;
3354 constructor TfdBGR5.Create;
3359 fWithAlpha := tfBGR5A1;
3360 fWithoutAlpha := tfBGR5;
3361 fRGBInverted := tfRGB5;
3370 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3371 fglInternalFormat := GL_RGB5;
3372 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3375 constructor TfdBGR8.Create;
3379 fWithAlpha := tfBGRA8;
3380 fWithoutAlpha := tfBGR8;
3381 fRGBInverted := tfRGB8;
3382 fglInternalFormat := GL_RGB8;
3385 constructor TfdBGR10.Create;
3389 fWithAlpha := tfBGR10A2;
3390 fWithoutAlpha := tfBGR10;
3391 fRGBInverted := tfRGB10;
3400 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3401 fglInternalFormat := GL_RGB10;
3402 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3405 constructor TfdBGR12.Create;
3409 fWithAlpha := tfBGRA12;
3410 fWithoutAlpha := tfBGR12;
3411 fRGBInverted := tfRGB12;
3412 fglInternalFormat := GL_RGB12;
3415 constructor TfdBGR16.Create;
3419 fWithAlpha := tfBGRA16;
3420 fWithoutAlpha := tfBGR16;
3421 fRGBInverted := tfRGB16;
3422 fglInternalFormat := GL_RGB16;
3425 constructor TfdBGRA2.Create;
3429 fWithAlpha := tfBGRA4;
3430 fWithoutAlpha := tfBGR4;
3431 fRGBInverted := tfRGBA2;
3432 fglInternalFormat := GL_RGBA2;
3435 constructor TfdBGRA4.Create;
3439 fWithAlpha := tfBGRA4;
3440 fWithoutAlpha := tfBGR4;
3441 fRGBInverted := tfRGBA4;
3450 fglFormat := GL_BGRA;
3451 fglInternalFormat := GL_RGBA4;
3452 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3455 constructor TfdBGR5A1.Create;
3458 fFormat := tfBGR5A1;
3459 fWithAlpha := tfBGR5A1;
3460 fWithoutAlpha := tfBGR5;
3461 fRGBInverted := tfRGB5A1;
3470 fglFormat := GL_BGRA;
3471 fglInternalFormat := GL_RGB5_A1;
3472 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3475 constructor TfdBGRA8.Create;
3479 fWithAlpha := tfBGRA8;
3480 fWithoutAlpha := tfBGR8;
3481 fRGBInverted := tfRGBA8;
3482 fglInternalFormat := GL_RGBA8;
3485 constructor TfdBGR10A2.Create;
3488 fFormat := tfBGR10A2;
3489 fWithAlpha := tfBGR10A2;
3490 fWithoutAlpha := tfBGR10;
3491 fRGBInverted := tfRGB10A2;
3500 fglFormat := GL_BGRA;
3501 fglInternalFormat := GL_RGB10_A2;
3502 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3505 constructor TfdBGRA12.Create;
3508 fFormat := tfBGRA12;
3509 fWithAlpha := tfBGRA12;
3510 fWithoutAlpha := tfBGR12;
3511 fRGBInverted := tfRGBA12;
3512 fglInternalFormat := GL_RGBA12;
3515 constructor TfdBGRA16.Create;
3518 fFormat := tfBGRA16;
3519 fWithAlpha := tfBGRA16;
3520 fWithoutAlpha := tfBGR16;
3521 fRGBInverted := tfRGBA16;
3522 fglInternalFormat := GL_RGBA16;
3525 constructor TfdDepth16.Create;
3528 fFormat := tfDepth16;
3529 fWithAlpha := tfEmpty;
3530 fWithoutAlpha := tfDepth16;
3531 fglInternalFormat := GL_DEPTH_COMPONENT16;
3534 constructor TfdDepth24.Create;
3537 fFormat := tfDepth24;
3538 fWithAlpha := tfEmpty;
3539 fWithoutAlpha := tfDepth24;
3540 fglInternalFormat := GL_DEPTH_COMPONENT24;
3543 constructor TfdDepth32.Create;
3546 fFormat := tfDepth32;
3547 fWithAlpha := tfEmpty;
3548 fWithoutAlpha := tfDepth32;
3549 fglInternalFormat := GL_DEPTH_COMPONENT32;
3552 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3553 //TfdS3tcDtx1RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3554 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3555 procedure TfdS3tcDtx1RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3557 raise EglBitmap.Create('mapping for compressed formats is not supported');
3560 procedure TfdS3tcDtx1RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3562 raise EglBitmap.Create('mapping for compressed formats is not supported');
3565 constructor TfdS3tcDtx1RGBA.Create;
3568 fFormat := tfS3tcDtx1RGBA;
3569 fWithAlpha := tfS3tcDtx1RGBA;
3570 fUncompressed := tfRGB5A1;
3572 fIsCompressed := true;
3573 fglFormat := GL_COMPRESSED_RGBA;
3574 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
3575 fglDataFormat := GL_UNSIGNED_BYTE;
3578 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3579 //TfdS3tcDtx3RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3580 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3581 procedure TfdS3tcDtx3RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3583 raise EglBitmap.Create('mapping for compressed formats is not supported');
3586 procedure TfdS3tcDtx3RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3588 raise EglBitmap.Create('mapping for compressed formats is not supported');
3591 constructor TfdS3tcDtx3RGBA.Create;
3594 fFormat := tfS3tcDtx3RGBA;
3595 fWithAlpha := tfS3tcDtx3RGBA;
3596 fUncompressed := tfRGBA8;
3598 fIsCompressed := true;
3599 fglFormat := GL_COMPRESSED_RGBA;
3600 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
3601 fglDataFormat := GL_UNSIGNED_BYTE;
3604 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3605 //TfdS3tcDtx5RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3606 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3607 procedure TfdS3tcDtx5RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3609 raise EglBitmap.Create('mapping for compressed formats is not supported');
3612 procedure TfdS3tcDtx5RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3614 raise EglBitmap.Create('mapping for compressed formats is not supported');
3617 constructor TfdS3tcDtx5RGBA.Create;
3620 fFormat := tfS3tcDtx3RGBA;
3621 fWithAlpha := tfS3tcDtx3RGBA;
3622 fUncompressed := tfRGBA8;
3624 fIsCompressed := true;
3625 fglFormat := GL_COMPRESSED_RGBA;
3626 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
3627 fglDataFormat := GL_UNSIGNED_BYTE;
3630 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3631 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3632 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3633 class procedure TFormatDescriptor.Init;
3635 if not Assigned(FormatDescriptorCS) then
3636 FormatDescriptorCS := TCriticalSection.Create;
3639 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3640 class function TFormatDescriptor.Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
3642 FormatDescriptorCS.Enter;
3644 result := FormatDescriptors[aFormat];
3645 if not Assigned(result) then begin
3646 result := FORMAT_DESCRIPTOR_CLASSES[aFormat].Create;
3647 FormatDescriptors[aFormat] := result;
3650 FormatDescriptorCS.Leave;
3654 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3655 class function TFormatDescriptor.GetWithAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
3657 result := Get(Get(aFormat).WithAlpha);
3660 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3661 class procedure TFormatDescriptor.Clear;
3665 FormatDescriptorCS.Enter;
3667 for f := low(FormatDescriptors) to high(FormatDescriptors) do
3668 FreeAndNil(FormatDescriptors[f]);
3670 FormatDescriptorCS.Leave;
3674 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3675 class procedure TFormatDescriptor.Finalize;
3678 FreeAndNil(FormatDescriptorCS);
3681 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3682 //TBitfieldFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3683 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3684 procedure TbmpBitfieldFormat.SetRedMask(const aValue: QWord);
3686 Update(aValue, fRange.r, fShift.r);
3689 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3690 procedure TbmpBitfieldFormat.SetGreenMask(const aValue: QWord);
3692 Update(aValue, fRange.g, fShift.g);
3695 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3696 procedure TbmpBitfieldFormat.SetBlueMask(const aValue: QWord);
3698 Update(aValue, fRange.b, fShift.b);
3701 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3702 procedure TbmpBitfieldFormat.SetAlphaMask(const aValue: QWord);
3704 Update(aValue, fRange.a, fShift.a);
3707 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3708 procedure TbmpBitfieldFormat.Update(aMask: QWord; out aRange: Cardinal; out
3715 while (aMask > 0) and ((aMask and 1) = 0) do begin
3717 aMask := aMask shr 1;
3720 while (aMask > 0) do begin
3721 aRange := aRange shl 1;
3722 aMask := aMask shr 1;
3726 fPixelSize := Round(GetTopMostBit(RedMask or GreenMask or BlueMask or AlphaMask) / 8);
3729 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3730 procedure TbmpBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3736 ((aPixel.Data.r and fRange.r) shl fShift.r) or
3737 ((aPixel.Data.g and fRange.g) shl fShift.g) or
3738 ((aPixel.Data.b and fRange.b) shl fShift.b) or
3739 ((aPixel.Data.a and fRange.a) shl fShift.a);
3740 s := Round(fPixelSize);
3743 2: PWord(aData)^ := data;
3744 4: PCardinal(aData)^ := data;
3745 8: PQWord(aData)^ := data;
3747 raise EglBitmap.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
3752 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3753 procedure TbmpBitfieldFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3758 s := Round(fPixelSize);
3761 2: data := PWord(aData)^;
3762 4: data := PCardinal(aData)^;
3763 8: data := PQWord(aData)^;
3765 raise EglBitmap.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
3768 aPixel.Data.arr[i] := (data shr fShift.arr[i]) and fRange.arr[i];
3772 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3773 //TColorTableFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3774 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3775 procedure TbmpColorTableFormat.CreateColorTable;
3779 if not (Format in [tfLuminance4, tfLuminance8, tfR3G3B2]) then
3780 raise EglBitmap.Create(UNSUPPORTED_FORMAT);
3782 if (Format = tfLuminance4) then
3783 SetLength(fColorTable, 16)
3785 SetLength(fColorTable, 256);
3789 for i := 0 to High(fColorTable) do begin
3790 fColorTable[i].r := 16 * i;
3791 fColorTable[i].g := 16 * i;
3792 fColorTable[i].b := 16 * i;
3793 fColorTable[i].a := 0;
3798 for i := 0 to High(fColorTable) do begin
3799 fColorTable[i].r := i;
3800 fColorTable[i].g := i;
3801 fColorTable[i].b := i;
3802 fColorTable[i].a := 0;
3807 for i := 0 to High(fColorTable) do begin
3808 fColorTable[i].r := Round(((i shr Shift.r) and Range.r) / Range.r * 255);
3809 fColorTable[i].g := Round(((i shr Shift.g) and Range.g) / Range.g * 255);
3810 fColorTable[i].b := Round(((i shr Shift.b) and Range.b) / Range.b * 255);
3811 fColorTable[i].a := 0;
3817 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3818 procedure TbmpColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3822 if not (Format in [tfLuminance4, tfLuminance8, tfR3G3B2]) then
3823 raise EglBitmap.Create(UNSUPPORTED_FORMAT);
3827 if (aMapData = nil) then
3829 d := LuminanceWeight(aPixel) and Range.r;
3830 aData^ := aData^ or (d shl (4 - {%H-}PtrUInt(aMapData)));
3831 inc(PByte(aMapData), 4);
3832 if ({%H-}PtrUInt(aMapData) >= 8) then begin
3839 aData^ := LuminanceWeight(aPixel) and Range.r;
3845 ((aPixel.Data.r and Range.r) shl Shift.r) or
3846 ((aPixel.Data.g and Range.g) shl Shift.g) or
3847 ((aPixel.Data.b and Range.b) shl Shift.b));
3853 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3854 procedure TbmpColorTableFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3861 s := Trunc(fPixelSize);
3862 f := fPixelSize - s;
3863 bits := Round(8 * f);
3865 0: idx := (aData^ shr (8 - bits - {%H-}PtrInt(aMapData))) and ((1 shl bits) - 1);
3867 2: idx := PWord(aData)^;
3868 4: idx := PCardinal(aData)^;
3869 8: idx := PQWord(aData)^;
3871 raise EglBitmap.CreateFmt('invalid pixel size: %.3f', [fPixelSize]);
3873 if (idx >= Length(fColorTable)) then
3874 raise EglBitmap.CreateFmt('invalid color index: %d', [idx]);
3875 with fColorTable[idx] do begin
3881 inc(PByte(aMapData), bits);
3882 if ({%H-}PtrUInt(aMapData) >= 8) then begin
3884 dec(PByte(aMapData), 8);
3889 destructor TbmpColorTableFormat.Destroy;
3891 SetLength(fColorTable, 0);
3895 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3896 //TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3897 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3898 procedure glBitmapConvertPixel(var aPixel: TglBitmapPixelData; const aSourceFD, aDestFD: TFormatDescriptor);
3902 for i := 0 to 3 do begin
3903 if (aSourceFD.Range.arr[i] <> aDestFD.Range.arr[i]) then begin
3904 if (aSourceFD.Range.arr[i] > 0) then
3905 aPixel.Data.arr[i] := Round(aPixel.Data.arr[i] / aSourceFD.Range.arr[i] * aDestFD.Range.arr[i])
3907 aPixel.Data.arr[i] := aDestFD.Range.arr[i];
3912 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3913 procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
3915 with aFuncRec do begin
3916 if (Source.Range.r > 0) then
3917 Dest.Data.r := Source.Data.r;
3918 if (Source.Range.g > 0) then
3919 Dest.Data.g := Source.Data.g;
3920 if (Source.Range.b > 0) then
3921 Dest.Data.b := Source.Data.b;
3922 if (Source.Range.a > 0) then
3923 Dest.Data.a := Source.Data.a;
3927 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3928 procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
3932 with aFuncRec do begin
3934 if (Source.Range.arr[i] > 0) then
3935 Dest.Data.arr[i] := Round(Dest.Range.arr[i] * Source.Data.arr[i] / Source.Range.arr[i]);
3940 TShiftData = packed record
3942 0: (r, g, b, a: SmallInt);
3943 1: (arr: array[0..3] of SmallInt);
3945 PShiftData = ^TShiftData;
3947 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3948 procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
3954 if (Source.Range.arr[i] > 0) then
3955 Dest.Data.arr[i] := Source.Data.arr[i] shr PShiftData(Args)^.arr[i];
3958 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3959 procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
3961 with aFuncRec do begin
3962 Dest.Data := Source.Data;
3963 if ({%H-}PtrUInt(Args) and $1 > 0) then begin
3964 Dest.Data.r := Dest.Data.r xor Dest.Range.r;
3965 Dest.Data.g := Dest.Data.g xor Dest.Range.g;
3966 Dest.Data.b := Dest.Data.b xor Dest.Range.b;
3968 if ({%H-}PtrUInt(Args) and $2 > 0) then begin
3969 Dest.Data.a := Dest.Data.a xor Dest.Range.a;
3974 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3975 procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
3979 with aFuncRec do begin
3981 Dest.Data.arr[i] := PglBitmapPixelData(Args)^.Data.arr[i];
3985 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3986 procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
3990 with FuncRec do begin
3991 if (FuncRec.Args = nil) then begin //source has no alpha
3993 Source.Data.r / Source.Range.r * ALPHA_WEIGHT_R +
3994 Source.Data.g / Source.Range.g * ALPHA_WEIGHT_G +
3995 Source.Data.b / Source.Range.b * ALPHA_WEIGHT_B;
3996 Dest.Data.a := Round(Dest.Range.a * Temp);
3998 Dest.Data.a := Round(Source.Data.a / Source.Range.a * Dest.Range.a);
4002 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4003 procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4005 PglBitmapPixelData = ^TglBitmapPixelData;
4007 with FuncRec do begin
4008 Dest.Data.r := Source.Data.r;
4009 Dest.Data.g := Source.Data.g;
4010 Dest.Data.b := Source.Data.b;
4012 with PglBitmapPixelData(Args)^ do
4013 if ((Dest.Data.r <= Data.r) and (Dest.Data.r >= Range.r) and
4014 (Dest.Data.g <= Data.g) and (Dest.Data.g >= Range.g) and
4015 (Dest.Data.b <= Data.b) and (Dest.Data.b >= Range.b)) then
4018 Dest.Data.a := Dest.Range.a;
4022 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4023 procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4025 with FuncRec do begin
4026 Dest.Data.r := Source.Data.r;
4027 Dest.Data.g := Source.Data.g;
4028 Dest.Data.b := Source.Data.b;
4029 Dest.Data.a := PCardinal(Args)^;
4033 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4034 procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
4037 TRGBPix = array [0..2] of byte;
4041 while aWidth > 0 do begin
4042 Temp := PRGBPix(aData)^[0];
4043 PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
4044 PRGBPix(aData)^[2] := Temp;
4054 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4055 //TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4056 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4057 function TglBitmap.GetFormatDesc: TglBitmapFormatDescriptor;
4059 result := TFormatDescriptor.Get(Format);
4062 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4063 function TglBitmap.GetWidth: Integer;
4065 if (ffX in fDimension.Fields) then
4066 result := fDimension.X
4071 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4072 function TglBitmap.GetHeight: Integer;
4074 if (ffY in fDimension.Fields) then
4075 result := fDimension.Y
4080 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4081 function TglBitmap.GetFileWidth: Integer;
4083 result := Max(1, Width);
4086 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4087 function TglBitmap.GetFileHeight: Integer;
4089 result := Max(1, Height);
4092 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4093 procedure TglBitmap.SetCustomData(const aValue: Pointer);
4095 if fCustomData = aValue then
4097 fCustomData := aValue;
4100 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4101 procedure TglBitmap.SetCustomName(const aValue: String);
4103 if fCustomName = aValue then
4105 fCustomName := aValue;
4108 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4109 procedure TglBitmap.SetCustomNameW(const aValue: WideString);
4111 if fCustomNameW = aValue then
4113 fCustomNameW := aValue;
4116 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4117 procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
4119 if fDeleteTextureOnFree = aValue then
4121 fDeleteTextureOnFree := aValue;
4124 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4125 procedure TglBitmap.SetFormat(const aValue: TglBitmapFormat);
4127 if fFormat = aValue then
4129 if TFormatDescriptor.Get(Format).PixelSize <> TFormatDescriptor.Get(aValue).PixelSize then
4130 raise EglBitmapUnsupportedFormat.Create(Format);
4131 SetDataPointer(fData, aValue, Width, Height); //be careful, Data could be freed by this method
4134 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4135 procedure TglBitmap.SetFreeDataAfterGenTexture(const aValue: Boolean);
4137 if fFreeDataAfterGenTexture = aValue then
4139 fFreeDataAfterGenTexture := aValue;
4142 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4143 procedure TglBitmap.SetID(const aValue: Cardinal);
4145 if fID = aValue then
4150 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4151 procedure TglBitmap.SetMipMap(const aValue: TglBitmapMipMap);
4153 if fMipMap = aValue then
4158 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4159 procedure TglBitmap.SetTarget(const aValue: Cardinal);
4161 if fTarget = aValue then
4166 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4167 procedure TglBitmap.SetAnisotropic(const aValue: Integer);
4169 MaxAnisotropic: Integer;
4171 fAnisotropic := aValue;
4172 if (ID > 0) then begin
4173 if GL_EXT_texture_filter_anisotropic then begin
4174 if fAnisotropic > 0 then begin
4176 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
4177 if aValue > MaxAnisotropic then
4178 fAnisotropic := MaxAnisotropic;
4179 glTexParameteri(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, fAnisotropic);
4187 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4188 procedure TglBitmap.CreateID;
4191 glDeleteTextures(1, @fID);
4192 glGenTextures(1, @fID);
4196 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4197 procedure TglBitmap.SetupParameters(out aBuildWithGlu: Boolean);
4199 // Set Up Parameters
4200 SetWrap(fWrapS, fWrapT, fWrapR);
4201 SetFilter(fFilterMin, fFilterMag);
4202 SetAnisotropic(fAnisotropic);
4203 SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
4205 if (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
4206 SetSwizzle(fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
4208 // Mip Maps Generation Mode
4209 aBuildWithGlu := false;
4210 if (MipMap = mmMipmap) then begin
4211 if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
4212 glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
4214 aBuildWithGlu := true;
4215 end else if (MipMap = mmMipmapGlu) then
4216 aBuildWithGlu := true;
4219 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4220 procedure TglBitmap.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
4221 const aWidth: Integer; const aHeight: Integer);
4225 if (Data <> aData) then begin
4226 if (Assigned(Data)) then
4231 FillChar(fDimension, SizeOf(fDimension), 0);
4232 if not Assigned(fData) then begin
4237 if aWidth <> -1 then begin
4238 fDimension.Fields := fDimension.Fields + [ffX];
4239 fDimension.X := aWidth;
4242 if aHeight <> -1 then begin
4243 fDimension.Fields := fDimension.Fields + [ffY];
4244 fDimension.Y := aHeight;
4247 s := TFormatDescriptor.Get(aFormat).PixelSize;
4249 fPixelSize := Ceil(s);
4250 fRowSize := Ceil(s * aWidth);
4254 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4255 function TglBitmap.FlipHorz: Boolean;
4260 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4261 function TglBitmap.FlipVert: Boolean;
4266 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4267 //TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4268 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4269 procedure TglBitmap.AfterConstruction;
4271 inherited AfterConstruction;
4275 fIsResident := false;
4277 fFormat := glBitmapGetDefaultFormat;
4278 fMipMap := glBitmapDefaultMipmap;
4279 fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
4280 fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
4282 glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
4283 glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
4284 glBitmapGetDefaultSwizzle (fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
4287 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4288 procedure TglBitmap.BeforeDestruction;
4293 SetDataPointer(NewData, tfEmpty); //be careful, Data could be freed by this method
4294 if (fID > 0) and fDeleteTextureOnFree then
4295 glDeleteTextures(1, @fID);
4296 inherited BeforeDestruction;
4299 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4300 procedure TglBitmap.PrepareResType(var aResource: String; var aResType: PChar);
4304 if not Assigned(aResType) then begin
4305 TempPos := Pos('.', aResource);
4306 aResType := PChar(UpperCase(Copy(aResource, TempPos + 1, Length(aResource) - TempPos)));
4307 aResource := UpperCase(Copy(aResource, 0, TempPos -1));
4311 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4312 procedure TglBitmap.LoadFromFile(const aFilename: String);
4316 if not FileExists(aFilename) then
4317 raise EglBitmap.Create('file does not exist: ' + aFilename);
4318 fFilename := aFilename;
4319 fs := TFileStream.Create(fFilename, fmOpenRead);
4328 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4329 procedure TglBitmap.LoadFromStream(const aStream: TStream);
4331 {$IFDEF GLB_SUPPORT_PNG_READ}
4332 if not LoadPNG(aStream) then
4334 {$IFDEF GLB_SUPPORT_JPEG_READ}
4335 if not LoadJPEG(aStream) then
4337 if not LoadDDS(aStream) then
4338 if not LoadTGA(aStream) then
4339 if not LoadBMP(aStream) then
4340 raise EglBitmap.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
4343 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4344 procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
4345 const aFormat: TglBitmapFormat; const aArgs: Pointer);
4350 size := TFormatDescriptor.Get(aFormat).GetSize(aSize);
4351 GetMem(tmpData, size);
4353 FillChar(tmpData^, size, #$FF);
4354 SetDataPointer(tmpData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
4356 if Assigned(tmpData) then
4360 AddFunc(Self, aFunc, false, Format, aArgs);
4363 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4364 procedure TglBitmap.LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar);
4366 rs: TResourceStream;
4368 PrepareResType(aResource, aResType);
4369 rs := TResourceStream.Create(aInstance, aResource, aResType);
4377 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4378 procedure TglBitmap.LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
4380 rs: TResourceStream;
4382 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
4390 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4391 procedure TglBitmap.SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
4395 fs := TFileStream.Create(aFileName, fmCreate);
4398 SaveToStream(fs, aFileType);
4404 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4405 procedure TglBitmap.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
4408 {$IFDEF GLB_SUPPORT_PNG_WRITE}
4409 ftPNG: SavePNG(aStream);
4411 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
4412 ftJPEG: SaveJPEG(aStream);
4414 ftDDS: SaveDDS(aStream);
4415 ftTGA: SaveTGA(aStream);
4416 ftBMP: SaveBMP(aStream);
4420 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4421 function TglBitmap.AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer): Boolean;
4423 result := AddFunc(Self, aFunc, aCreateTemp, Format, aArgs);
4426 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4427 function TglBitmap.AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
4428 const aFormat: TglBitmapFormat; const aArgs: Pointer): Boolean;
4430 DestData, TmpData, SourceData: pByte;
4431 TempHeight, TempWidth: Integer;
4432 SourceFD, DestFD: TFormatDescriptor;
4433 SourceMD, DestMD: Pointer;
4435 FuncRec: TglBitmapFunctionRec;
4437 Assert(Assigned(Data));
4438 Assert(Assigned(aSource));
4439 Assert(Assigned(aSource.Data));
4442 if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
4443 SourceFD := TFormatDescriptor.Get(aSource.Format);
4444 DestFD := TFormatDescriptor.Get(aFormat);
4446 if (SourceFD.IsCompressed) then
4447 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', SourceFD.Format);
4448 if (DestFD.IsCompressed) then
4449 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', DestFD.Format);
4451 // inkompatible Formats so CreateTemp
4452 if (SourceFD.PixelSize <> DestFD.PixelSize) then
4453 aCreateTemp := true;
4456 TempHeight := Max(1, aSource.Height);
4457 TempWidth := Max(1, aSource.Width);
4459 FuncRec.Sender := Self;
4460 FuncRec.Args := aArgs;
4463 if aCreateTemp then begin
4464 GetMem(TmpData, DestFD.GetSize(TempWidth, TempHeight));
4465 DestData := TmpData;
4470 SourceFD.PreparePixel(FuncRec.Source);
4471 DestFD.PreparePixel (FuncRec.Dest);
4473 SourceMD := SourceFD.CreateMappingData;
4474 DestMD := DestFD.CreateMappingData;
4476 FuncRec.Size := aSource.Dimension;
4477 FuncRec.Position.Fields := FuncRec.Size.Fields;
4480 SourceData := aSource.Data;
4481 FuncRec.Position.Y := 0;
4482 while FuncRec.Position.Y < TempHeight do begin
4483 FuncRec.Position.X := 0;
4484 while FuncRec.Position.X < TempWidth do begin
4485 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
4487 DestFD.Map(FuncRec.Dest, DestData, DestMD);
4488 inc(FuncRec.Position.X);
4490 inc(FuncRec.Position.Y);
4493 // Updating Image or InternalFormat
4495 SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height) //be careful, Data could be freed by this method
4496 else if (aFormat <> fFormat) then
4501 SourceFD.FreeMappingData(SourceMD);
4502 DestFD.FreeMappingData(DestMD);
4505 if aCreateTemp and Assigned(TmpData) then
4513 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4514 function TglBitmap.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
4516 Row, RowSize: Integer;
4517 SourceData, TmpData: PByte;
4519 FormatDesc: TFormatDescriptor;
4521 function GetRowPointer(Row: Integer): pByte;
4523 result := aSurface.pixels;
4524 Inc(result, Row * RowSize);
4530 FormatDesc := TFormatDescriptor.Get(Format);
4531 if FormatDesc.IsCompressed then
4532 raise EglBitmapUnsupportedFormat.Create(Format);
4534 if Assigned(Data) then begin
4535 case Trunc(FormatDesc.PixelSize) of
4541 raise EglBitmapUnsupportedFormat.Create(Format);
4544 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
4545 FormatDesc.RedMask, FormatDesc.GreenMask, FormatDesc.BlueMask, FormatDesc.AlphaMask);
4547 RowSize := FormatDesc.GetSize(FileWidth, 1);
4549 for Row := 0 to FileHeight-1 do begin
4550 TmpData := GetRowPointer(Row);
4551 if Assigned(TmpData) then begin
4552 Move(SourceData^, TmpData^, RowSize);
4553 inc(SourceData, RowSize);
4560 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4561 function TglBitmap.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
4563 pSource, pData, pTempData: PByte;
4564 Row, RowSize, TempWidth, TempHeight: Integer;
4565 IntFormat: TglBitmapFormat;
4566 FormatDesc: TFormatDescriptor;
4568 function GetRowPointer(Row: Integer): pByte;
4570 result := aSurface^.pixels;
4571 Inc(result, Row * RowSize);
4576 if (Assigned(aSurface)) then begin
4577 with aSurface^.format^ do begin
4578 for IntFormat := High(TglBitmapFormat) to Low(TglBitmapFormat) do begin
4579 FormatDesc := TFormatDescriptor.Get(IntFormat);
4580 if (FormatDesc.MaskMatch(RMask, GMask, BMask, AMask)) then
4583 if (IntFormat = tfEmpty) then
4584 raise EglBitmapException.Create('AssignFromSurface - Invalid Pixelformat.');
4587 TempWidth := aSurface^.w;
4588 TempHeight := aSurface^.h;
4589 RowSize := FormatDesc.GetSize(TempWidth, 1);
4590 GetMem(pData, TempHeight * RowSize);
4593 for Row := 0 to TempHeight -1 do begin
4594 pSource := GetRowPointer(Row);
4595 if (Assigned(pSource)) then begin
4596 Move(pSource^, pTempData^, RowSize);
4597 Inc(pTempData, RowSize);
4600 SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
4603 if Assigned(pData) then
4610 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4611 function TglBitmap.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
4613 Row, Col, AlphaInterleave: Integer;
4614 pSource, pDest: PByte;
4616 function GetRowPointer(Row: Integer): pByte;
4618 result := aSurface.pixels;
4619 Inc(result, Row * Width);
4624 if Assigned(Data) then begin
4625 if Format in [tfAlpha8, tfLuminance8Alpha8, tfBGRA8, tfRGBA8] then begin
4626 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
4628 AlphaInterleave := 0;
4631 AlphaInterleave := 1;
4633 AlphaInterleave := 3;
4637 for Row := 0 to Height -1 do begin
4638 pDest := GetRowPointer(Row);
4639 if Assigned(pDest) then begin
4640 for Col := 0 to Width -1 do begin
4641 Inc(pSource, AlphaInterleave);
4653 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4654 function TglBitmap.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
4658 bmp := TglBitmap2D.Create;
4660 bmp.AssignFromSurface(aSurface);
4661 result := AddAlphaFromGlBitmap(bmp, aFunc, aArgs);
4669 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4670 function CreateGrayPalette: HPALETTE;
4675 GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
4677 Pal.palVersion := $300;
4678 Pal.palNumEntries := 256;
4680 for Idx := 0 to Pal.palNumEntries - 1 do begin
4681 Pal.palPalEntry[Idx].peRed := Idx;
4682 Pal.palPalEntry[Idx].peGreen := Idx;
4683 Pal.palPalEntry[Idx].peBlue := Idx;
4684 Pal.palPalEntry[Idx].peFlags := 0;
4686 Result := CreatePalette(Pal^);
4690 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4691 function TglBitmap.AssignToBitmap(const aBitmap: TBitmap): Boolean;
4694 pSource, pData: PByte;
4697 if Assigned(Data) then begin
4698 if Assigned(aBitmap) then begin
4699 aBitmap.Width := Width;
4700 aBitmap.Height := Height;
4703 tfAlpha8, tfLuminance8: begin
4704 aBitmap.PixelFormat := pf8bit;
4705 aBitmap.Palette := CreateGrayPalette;
4708 aBitmap.PixelFormat := pf15bit;
4710 aBitmap.PixelFormat := pf16bit;
4712 aBitmap.PixelFormat := pf24bit;
4714 aBitmap.PixelFormat := pf32bit;
4716 raise EglBitmapException.Create('AssignToBitmap - Invalid Pixelformat.');
4720 for Row := 0 to FileHeight -1 do begin
4721 pData := aBitmap.Scanline[Row];
4722 Move(pSource^, pData^, fRowSize);
4723 Inc(pSource, fRowSize);
4724 if (Format in [tfRGB8, tfRGBA8]) then // swap RGB(A) to BGR(A)
4725 SwapRGB(pData, FileWidth, Format = tfRGBA8);
4732 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4733 function TglBitmap.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
4735 pSource, pData, pTempData: PByte;
4736 Row, RowSize, TempWidth, TempHeight: Integer;
4737 IntFormat: TglBitmapFormat;
4741 if (Assigned(aBitmap)) then begin
4742 case aBitmap.PixelFormat of
4744 IntFormat := tfLuminance8;
4746 IntFormat := tfRGB5A1;
4748 IntFormat := tfR5G6B5;
4750 IntFormat := tfBGR8;
4752 IntFormat := tfBGRA8;
4754 raise EglBitmapException.Create('AssignFromBitmap - Invalid Pixelformat.');
4757 TempWidth := aBitmap.Width;
4758 TempHeight := aBitmap.Height;
4759 RowSize := TFormatDescriptor.Get(IntFormat).GetSize(TempWidth, 1);
4760 GetMem(pData, TempHeight * RowSize);
4763 for Row := 0 to TempHeight -1 do begin
4764 pSource := aBitmap.Scanline[Row];
4765 if (Assigned(pSource)) then begin
4766 Move(pSource^, pTempData^, RowSize);
4767 Inc(pTempData, RowSize);
4770 SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
4773 if Assigned(pData) then
4780 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4781 function TglBitmap.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
4783 Row, Col, AlphaInterleave: Integer;
4784 pSource, pDest: PByte;
4788 if Assigned(Data) then begin
4789 if (Format in [tfAlpha8, tfLuminance8Alpha8, tfRGBA8, tfBGRA8]) then begin
4790 if Assigned(aBitmap) then begin
4791 aBitmap.PixelFormat := pf8bit;
4792 aBitmap.Palette := CreateGrayPalette;
4793 aBitmap.Width := Width;
4794 aBitmap.Height := Height;
4798 AlphaInterleave := 1;
4800 AlphaInterleave := 3;
4802 AlphaInterleave := 0;
4808 for Row := 0 to Height -1 do begin
4809 pDest := aBitmap.Scanline[Row];
4810 if Assigned(pDest) then begin
4811 for Col := 0 to Width -1 do begin
4812 Inc(pSource, AlphaInterleave);
4825 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4826 function TglBitmap.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
4830 tex := TglBitmap2D.Create;
4832 tex.AssignFromBitmap(ABitmap);
4833 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
4840 {$IFDEF GLB_LAZARUS}
4841 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4842 function TglBitmap.AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
4844 rid: TRawImageDescription;
4845 FormatDesc: TFormatDescriptor;
4848 if not Assigned(aImage) or (Format = tfEmpty) then
4850 FormatDesc := TFormatDescriptor.Get(Format);
4851 if FormatDesc.IsCompressed then
4854 FillChar(rid{%H-}, SizeOf(rid), 0);
4856 tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16,
4857 tfLuminance4, tfLuminance8, tfLuminance12, tfLuminance16,
4858 tfLuminance4Alpha4, tfLuminance8Alpha8, tfLuminance12Alpha4, tfLuminance12Alpha12, tfLuminance16Alpha16]) then
4859 rid.Format := ricfGray
4861 rid.Format := ricfRGBA;
4864 rid.Height := Height;
4865 rid.Depth := CountSetBits(FormatDesc.Range.r or FormatDesc.Range.g or FormatDesc.Range.b or FormatDesc.Range.a);
4866 rid.BitOrder := riboBitsInOrder;
4867 rid.ByteOrder := riboLSBFirst;
4868 rid.LineOrder := riloTopToBottom;
4869 rid.LineEnd := rileTight;
4870 rid.BitsPerPixel := Round(8 * FormatDesc.PixelSize);
4871 rid.RedPrec := CountSetBits(FormatDesc.Range.r);
4872 rid.GreenPrec := CountSetBits(FormatDesc.Range.g);
4873 rid.BluePrec := CountSetBits(FormatDesc.Range.b);
4874 rid.AlphaPrec := CountSetBits(FormatDesc.Range.a);
4875 rid.RedShift := FormatDesc.Shift.r;
4876 rid.GreenShift := FormatDesc.Shift.g;
4877 rid.BlueShift := FormatDesc.Shift.b;
4878 rid.AlphaShift := FormatDesc.Shift.a;
4880 rid.MaskBitsPerPixel := 0;
4881 rid.PaletteColorCount := 0;
4883 aImage.DataDescription := rid;
4886 Move(Data^, aImage.PixelData^, FormatDesc.GetSize(Dimension));
4891 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4892 function TglBitmap.AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
4895 FormatDesc: TFormatDescriptor;
4900 if not Assigned(aImage) then
4902 for f := High(f) downto Low(f) do begin
4903 FormatDesc := TFormatDescriptor.Get(f);
4904 with aImage.DataDescription do
4905 if FormatDesc.MaskMatch(
4906 (QWord(1 shl RedPrec )-1) shl RedShift,
4907 (QWord(1 shl GreenPrec)-1) shl GreenShift,
4908 (QWord(1 shl BluePrec )-1) shl BlueShift,
4909 (QWord(1 shl AlphaPrec)-1) shl AlphaShift) then
4913 if (f = tfEmpty) then
4916 ImageSize := FormatDesc.GetSize(aImage.Width, aImage.Height);
4917 ImageData := GetMem(ImageSize);
4919 Move(aImage.PixelData^, ImageData^, (aImage.Width * aImage.Height * aImage.DataDescription.BitsPerPixel) shr 3);
4920 SetDataPointer(ImageData, f, aImage.Width, aImage.Height); //be careful, Data could be freed by this method
4922 if Assigned(ImageData) then
4930 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4931 function TglBitmap.AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
4933 rid: TRawImageDescription;
4934 FormatDesc: TFormatDescriptor;
4935 Pixel: TglBitmapPixelData;
4941 if not Assigned(aImage) or (Format = tfEmpty) then
4943 FormatDesc := TFormatDescriptor.Get(Format);
4944 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
4947 FillChar(rid{%H-}, SizeOf(rid), 0);
4948 rid.Format := ricfGray;
4950 rid.Height := Height;
4951 rid.Depth := CountSetBits(FormatDesc.Range.a);
4952 rid.BitOrder := riboBitsInOrder;
4953 rid.ByteOrder := riboLSBFirst;
4954 rid.LineOrder := riloTopToBottom;
4955 rid.LineEnd := rileTight;
4956 rid.BitsPerPixel := 8 * Ceil(rid.Depth / 8);
4957 rid.RedPrec := CountSetBits(FormatDesc.Range.a);
4962 rid.GreenShift := 0;
4964 rid.AlphaShift := 0;
4966 rid.MaskBitsPerPixel := 0;
4967 rid.PaletteColorCount := 0;
4969 aImage.DataDescription := rid;
4972 srcMD := FormatDesc.CreateMappingData;
4974 FormatDesc.PreparePixel(Pixel);
4976 dst := aImage.PixelData;
4977 for y := 0 to Height-1 do
4978 for x := 0 to Width-1 do begin
4979 FormatDesc.Unmap(src, Pixel, srcMD);
4980 case rid.BitsPerPixel of
4982 dst^ := Pixel.Data.a;
4986 PWord(dst)^ := Pixel.Data.a;
4990 PByteArray(dst)^[0] := PByteArray(@Pixel.Data.a)^[0];
4991 PByteArray(dst)^[1] := PByteArray(@Pixel.Data.a)^[1];
4992 PByteArray(dst)^[2] := PByteArray(@Pixel.Data.a)^[2];
4996 PCardinal(dst)^ := Pixel.Data.a;
5000 raise EglBitmapUnsupportedFormat.Create(Format);
5004 FormatDesc.FreeMappingData(srcMD);
5009 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5010 function TglBitmap.AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5014 tex := TglBitmap2D.Create;
5016 tex.AssignFromLazIntfImage(aImage);
5017 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5024 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5025 function TglBitmap.AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar;
5026 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5028 rs: TResourceStream;
5030 PrepareResType(aResource, aResType);
5031 rs := TResourceStream.Create(aInstance, aResource, aResType);
5033 result := AddAlphaFromStream(rs, aFunc, aArgs);
5039 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5040 function TglBitmap.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
5041 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5043 rs: TResourceStream;
5045 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
5047 result := AddAlphaFromStream(rs, aFunc, aArgs);
5053 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5054 function TglBitmap.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5056 if TFormatDescriptor.Get(Format).IsCompressed then
5057 raise EglBitmapUnsupportedFormat.Create(Format);
5058 result := AddFunc(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs);
5061 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5062 function TglBitmap.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5066 FS := TFileStream.Create(aFileName, fmOpenRead);
5068 result := AddAlphaFromStream(FS, aFunc, aArgs);
5074 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5075 function TglBitmap.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5079 tex := TglBitmap2D.Create(aStream);
5081 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5087 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5088 function TglBitmap.AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5090 DestData, DestData2, SourceData: pByte;
5091 TempHeight, TempWidth: Integer;
5092 SourceFD, DestFD: TFormatDescriptor;
5093 SourceMD, DestMD, DestMD2: Pointer;
5095 FuncRec: TglBitmapFunctionRec;
5099 Assert(Assigned(Data));
5100 Assert(Assigned(aBitmap));
5101 Assert(Assigned(aBitmap.Data));
5103 if ((aBitmap.Width = Width) and (aBitmap.Height = Height)) then begin
5104 result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
5106 SourceFD := TFormatDescriptor.Get(aBitmap.Format);
5107 DestFD := TFormatDescriptor.Get(Format);
5109 if not Assigned(aFunc) then begin
5110 aFunc := glBitmapAlphaFunc;
5111 FuncRec.Args := {%H-}Pointer(SourceFD.HasAlpha);
5113 FuncRec.Args := aArgs;
5116 TempHeight := aBitmap.FileHeight;
5117 TempWidth := aBitmap.FileWidth;
5119 FuncRec.Sender := Self;
5120 FuncRec.Size := Dimension;
5121 FuncRec.Position.Fields := FuncRec.Size.Fields;
5125 SourceData := aBitmap.Data;
5128 SourceFD.PreparePixel(FuncRec.Source);
5129 DestFD.PreparePixel (FuncRec.Dest);
5131 SourceMD := SourceFD.CreateMappingData;
5132 DestMD := DestFD.CreateMappingData;
5133 DestMD2 := DestFD.CreateMappingData;
5135 FuncRec.Position.Y := 0;
5136 while FuncRec.Position.Y < TempHeight do begin
5137 FuncRec.Position.X := 0;
5138 while FuncRec.Position.X < TempWidth do begin
5139 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
5140 DestFD.Unmap (DestData, FuncRec.Dest, DestMD);
5142 DestFD.Map(FuncRec.Dest, DestData2, DestMD2);
5143 inc(FuncRec.Position.X);
5145 inc(FuncRec.Position.Y);
5148 SourceFD.FreeMappingData(SourceMD);
5149 DestFD.FreeMappingData(DestMD);
5150 DestFD.FreeMappingData(DestMD2);
5155 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5156 function TglBitmap.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
5158 result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
5161 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5162 function TglBitmap.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
5164 PixelData: TglBitmapPixelData;
5166 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
5167 result := AddAlphaFromColorKeyFloat(
5168 aRed / PixelData.Range.r,
5169 aGreen / PixelData.Range.g,
5170 aBlue / PixelData.Range.b,
5171 aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b)));
5174 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5175 function TglBitmap.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
5177 values: array[0..2] of Single;
5180 PixelData: TglBitmapPixelData;
5182 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
5183 with PixelData do begin
5185 values[1] := aGreen;
5188 for i := 0 to 2 do begin
5189 tmp := Trunc(Range.arr[i] * aDeviation);
5190 Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp));
5191 Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp));
5196 result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, @PixelData);
5199 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5200 function TglBitmap.AddAlphaFromValue(const aAlpha: Byte): Boolean;
5202 result := AddAlphaFromValueFloat(aAlpha / $FF);
5205 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5206 function TglBitmap.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
5208 PixelData: TglBitmapPixelData;
5210 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
5211 result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
5214 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5215 function TglBitmap.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
5217 PixelData: TglBitmapPixelData;
5219 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
5221 Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
5222 result := AddAlphaFromFunc(glBitmapValueAlphaFunc, @PixelData.Data.a);
5225 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5226 function TglBitmap.RemoveAlpha: Boolean;
5228 FormatDesc: TFormatDescriptor;
5231 FormatDesc := TFormatDescriptor.Get(Format);
5232 if Assigned(Data) then begin
5233 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
5234 raise EglBitmapUnsupportedFormat.Create(Format);
5235 result := ConvertTo(FormatDesc.WithoutAlpha);
5239 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5240 function TglBitmap.Clone: TglBitmap;
5247 Temp := (ClassType.Create as TglBitmap);
5249 // copy texture data if assigned
5250 if Assigned(Data) then begin
5251 Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
5252 GetMem(TempPtr, Size);
5254 Move(Data^, TempPtr^, Size);
5255 Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
5257 if Assigned(TempPtr) then
5263 Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
5268 Temp.fTarget := Target;
5269 Temp.fFormat := Format;
5270 Temp.fMipMap := MipMap;
5271 Temp.fAnisotropic := Anisotropic;
5272 Temp.fBorderColor := fBorderColor;
5273 Temp.fDeleteTextureOnFree := DeleteTextureOnFree;
5274 Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
5275 Temp.fFilterMin := fFilterMin;
5276 Temp.fFilterMag := fFilterMag;
5277 Temp.fWrapS := fWrapS;
5278 Temp.fWrapT := fWrapT;
5279 Temp.fWrapR := fWrapR;
5280 Temp.fFilename := fFilename;
5281 Temp.fCustomName := fCustomName;
5282 Temp.fCustomNameW := fCustomNameW;
5283 Temp.fCustomData := fCustomData;
5292 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5293 function TglBitmap.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
5295 SourceFD, DestFD: TFormatDescriptor;
5296 SourcePD, DestPD: TglBitmapPixelData;
5297 ShiftData: TShiftData;
5299 function CanCopyDirect: Boolean;
5302 ((SourcePD.Range.r = DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
5303 ((SourcePD.Range.g = DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
5304 ((SourcePD.Range.b = DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
5305 ((SourcePD.Range.a = DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
5308 function CanShift: Boolean;
5311 ((SourcePD.Range.r >= DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
5312 ((SourcePD.Range.g >= DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
5313 ((SourcePD.Range.b >= DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
5314 ((SourcePD.Range.a >= DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
5317 function GetShift(aSource, aDest: Cardinal) : ShortInt;
5320 while (aSource > aDest) and (aSource > 0) do begin
5322 aSource := aSource shr 1;
5327 if (aFormat <> fFormat) and (aFormat <> tfEmpty) then begin
5328 SourceFD := TFormatDescriptor.Get(Format);
5329 DestFD := TFormatDescriptor.Get(aFormat);
5331 SourceFD.PreparePixel(SourcePD);
5332 DestFD.PreparePixel (DestPD);
5334 if CanCopyDirect then
5335 result := AddFunc(Self, glBitmapConvertCopyFunc, false, aFormat)
5336 else if CanShift then begin
5337 ShiftData.r := GetShift(SourcePD.Range.r, DestPD.Range.r);
5338 ShiftData.g := GetShift(SourcePD.Range.g, DestPD.Range.g);
5339 ShiftData.b := GetShift(SourcePD.Range.b, DestPD.Range.b);
5340 ShiftData.a := GetShift(SourcePD.Range.a, DestPD.Range.a);
5341 result := AddFunc(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, @ShiftData);
5343 result := AddFunc(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
5348 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5349 procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
5351 if aUseRGB or aUseAlpha then
5352 AddFunc(glBitmapInvertFunc, false, {%H-}Pointer(
5353 ((PtrInt(aUseAlpha) and 1) shl 1) or
5354 (PtrInt(aUseRGB) and 1) ));
5357 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5358 procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
5360 fBorderColor[0] := aRed;
5361 fBorderColor[1] := aGreen;
5362 fBorderColor[2] := aBlue;
5363 fBorderColor[3] := aAlpha;
5364 if (ID > 0) then begin
5366 glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
5370 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5371 procedure TglBitmap.FreeData;
5376 SetDataPointer(TempPtr, tfEmpty); //be careful, Data could be freed by this method
5379 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5380 procedure TglBitmap.FillWithColor(const aRed, aGreen, aBlue: Byte;
5381 const aAlpha: Byte);
5383 FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
5386 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5387 procedure TglBitmap.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
5389 PixelData: TglBitmapPixelData;
5391 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
5393 aRed / PixelData.Range.r,
5394 aGreen / PixelData.Range.g,
5395 aBlue / PixelData.Range.b,
5396 aAlpha / PixelData.Range.a);
5399 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5400 procedure TglBitmap.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
5402 PixelData: TglBitmapPixelData;
5404 TFormatDescriptor.Get(Format).PreparePixel(PixelData);
5405 with PixelData do begin
5406 Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed)));
5407 Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen)));
5408 Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue)));
5409 Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha)));
5411 AddFunc(glBitmapFillWithColorFunc, false, @PixelData);
5414 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5415 procedure TglBitmap.SetFilter(const aMin, aMag: GLenum);
5420 fFilterMin := GL_NEAREST;
5422 fFilterMin := GL_LINEAR;
5423 GL_NEAREST_MIPMAP_NEAREST:
5424 fFilterMin := GL_NEAREST_MIPMAP_NEAREST;
5425 GL_LINEAR_MIPMAP_NEAREST:
5426 fFilterMin := GL_LINEAR_MIPMAP_NEAREST;
5427 GL_NEAREST_MIPMAP_LINEAR:
5428 fFilterMin := GL_NEAREST_MIPMAP_LINEAR;
5429 GL_LINEAR_MIPMAP_LINEAR:
5430 fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
5432 raise EglBitmap.Create('SetFilter - Unknow MIN filter.');
5438 fFilterMag := GL_NEAREST;
5440 fFilterMag := GL_LINEAR;
5442 raise EglBitmap.Create('SetFilter - Unknow MAG filter.');
5446 if (ID > 0) then begin
5448 glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
5450 if (MipMap = mmNone) or (Target = GL_TEXTURE_RECTANGLE) then begin
5452 GL_NEAREST, GL_LINEAR:
5453 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
5454 GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR:
5455 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5456 GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR:
5457 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5460 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
5464 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5465 procedure TglBitmap.SetWrap(const S: GLenum; const T: GLenum; const R: GLenum);
5467 procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
5471 aTarget := GL_CLAMP;
5474 aTarget := GL_REPEAT;
5476 GL_CLAMP_TO_EDGE: begin
5477 if GL_VERSION_1_2 or GL_EXT_texture_edge_clamp then
5478 aTarget := GL_CLAMP_TO_EDGE
5480 aTarget := GL_CLAMP;
5483 GL_CLAMP_TO_BORDER: begin
5484 if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
5485 aTarget := GL_CLAMP_TO_BORDER
5487 aTarget := GL_CLAMP;
5490 GL_MIRRORED_REPEAT: begin
5491 if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
5492 aTarget := GL_MIRRORED_REPEAT
5494 raise EglBitmap.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
5497 raise EglBitmap.Create('SetWrap - Unknow Texturewrap');
5502 CheckAndSetWrap(S, fWrapS);
5503 CheckAndSetWrap(T, fWrapT);
5504 CheckAndSetWrap(R, fWrapR);
5506 if (ID > 0) then begin
5508 glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
5509 glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
5510 glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
5514 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5515 procedure TglBitmap.SetSwizzle(const r, g, b, a: GLenum);
5517 procedure CheckAndSetValue(const aValue: GLenum; const aIndex: Integer);
5519 if (aValue = GL_ZERO) or (aValue = GL_ONE) or (aValue = GL_ALPHA) or
5520 (aValue = GL_RED) or (aValue = GL_GREEN) or (aValue = GL_BLUE) then
5521 fSwizzle[aIndex] := aValue
5523 raise EglBitmap.Create('SetSwizzle - Unknow Swizle Value');
5527 if not (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
5528 raise EglBitmapNotSupported.Create('texture swizzle is not supported');
5529 CheckAndSetValue(r, 0);
5530 CheckAndSetValue(g, 1);
5531 CheckAndSetValue(b, 2);
5532 CheckAndSetValue(a, 3);
5534 if (ID > 0) then begin
5536 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_RGBA, @fSwizzle[0]);
5540 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5541 procedure TglBitmap.Bind(const aEnableTextureUnit: Boolean);
5543 if aEnableTextureUnit then
5546 glBindTexture(Target, ID);
5549 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5550 procedure TglBitmap.Unbind(const aDisableTextureUnit: Boolean);
5552 if aDisableTextureUnit then
5554 glBindTexture(Target, 0);
5557 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5558 constructor TglBitmap.Create;
5560 if (ClassType = TglBitmap) then
5561 raise EglBitmap.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
5562 {$IFDEF GLB_NATIVE_OGL}
5563 glbReadOpenGLExtensions;
5568 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5569 constructor TglBitmap.Create(const aFileName: String);
5572 LoadFromFile(aFileName);
5575 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5576 constructor TglBitmap.Create(const aStream: TStream);
5579 LoadFromStream(aStream);
5582 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5583 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat);
5589 ImageSize := TFormatDescriptor.Get(aFormat).GetSize(aSize);
5590 GetMem(Image, ImageSize);
5592 FillChar(Image^, ImageSize, #$FF);
5593 SetDataPointer(Image, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
5595 if Assigned(Image) then
5601 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5602 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat;
5603 const aFunc: TglBitmapFunction; const aArgs: Pointer);
5606 LoadFromFunc(aSize, aFunc, aFormat, aArgs);
5609 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5610 constructor TglBitmap.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
5613 LoadFromResource(aInstance, aResource, aResType);
5616 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5617 constructor TglBitmap.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
5620 LoadFromResourceID(aInstance, aResourceID, aResType);
5623 {$IFDEF GLB_SUPPORT_PNG_READ}
5624 {$IF DEFINED(GLB_SDL_IMAGE)}
5625 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5626 //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5627 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5628 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
5630 Surface: PSDL_Surface;
5634 RWops := glBitmapCreateRWops(aStream);
5636 if IMG_isPNG(RWops) > 0 then begin
5637 Surface := IMG_LoadPNG_RW(RWops);
5639 AssignFromSurface(Surface);
5642 SDL_FreeSurface(Surface);
5650 {$ELSEIF DEFINED(GLB_LIB_PNG)}
5651 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5652 procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
5654 TStream(png_get_io_ptr(png)).Read(buffer^, size);
5657 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5658 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
5661 signature: array [0..7] of byte;
5663 png_info: png_infop;
5665 TempHeight, TempWidth: Integer;
5666 Format: TglBitmapFormat;
5669 png_rows: array of pByte;
5670 Row, LineSize: Integer;
5674 if not init_libPNG then
5675 raise Exception.Create('LoadPNG - unable to initialize libPNG.');
5679 StreamPos := aStream.Position;
5680 aStream.Read(signature{%H-}, 8);
5681 aStream.Position := StreamPos;
5683 if png_check_sig(@signature, 8) <> 0 then begin
5685 png := png_create_read_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
5687 raise EglBitmapException.Create('LoadPng - couldn''t create read struct.');
5690 png_info := png_create_info_struct(png);
5691 if png_info = nil then begin
5692 png_destroy_read_struct(@png, nil, nil);
5693 raise EglBitmapException.Create('LoadPng - couldn''t create info struct.');
5696 // set read callback
5697 png_set_read_fn(png, aStream, glBitmap_libPNG_read_func);
5699 // read informations
5700 png_read_info(png, png_info);
5703 TempHeight := png_get_image_height(png, png_info);
5704 TempWidth := png_get_image_width(png, png_info);
5707 case png_get_color_type(png, png_info) of
5708 PNG_COLOR_TYPE_GRAY:
5709 Format := tfLuminance8;
5710 PNG_COLOR_TYPE_GRAY_ALPHA:
5711 Format := tfLuminance8Alpha8;
5714 PNG_COLOR_TYPE_RGB_ALPHA:
5717 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
5720 // cut upper 8 bit from 16 bit formats
5721 if png_get_bit_depth(png, png_info) > 8 then
5722 png_set_strip_16(png);
5724 // expand bitdepth smaller than 8
5725 if png_get_bit_depth(png, png_info) < 8 then
5726 png_set_expand(png);
5728 // allocating mem for scanlines
5729 LineSize := png_get_rowbytes(png, png_info);
5730 GetMem(png_data, TempHeight * LineSize);
5732 SetLength(png_rows, TempHeight);
5733 for Row := Low(png_rows) to High(png_rows) do begin
5734 png_rows[Row] := png_data;
5735 Inc(png_rows[Row], Row * LineSize);
5738 // read complete image into scanlines
5739 png_read_image(png, @png_rows[0]);
5742 png_read_end(png, png_info);
5744 // destroy read struct
5745 png_destroy_read_struct(@png, @png_info, nil);
5747 SetLength(png_rows, 0);
5750 SetDataPointer(png_data, Format, TempWidth, TempHeight); //be careful, Data could be freed by this method
5754 if Assigned(png_data) then
5764 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
5765 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5766 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
5771 Row, Col, PixSize, LineSize: Integer;
5772 NewImage, pSource, pDest, pAlpha: pByte;
5773 PngFormat: TglBitmapFormat;
5774 FormatDesc: TFormatDescriptor;
5777 PngHeader: String[8] = #137#80#78#71#13#10#26#10;
5782 StreamPos := aStream.Position;
5783 aStream.Read(Header[0], SizeOf(Header));
5784 aStream.Position := StreamPos;
5786 {Test if the header matches}
5787 if Header = PngHeader then begin
5788 Png := TPNGObject.Create;
5790 Png.LoadFromStream(aStream);
5792 case Png.Header.ColorType of
5794 PngFormat := tfLuminance8;
5795 COLOR_GRAYSCALEALPHA:
5796 PngFormat := tfLuminance8Alpha8;
5798 PngFormat := tfBGR8;
5800 PngFormat := tfBGRA8;
5802 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
5805 FormatDesc := TFormatDescriptor.Get(PngFormat);
5806 PixSize := Round(FormatDesc.PixelSize);
5807 LineSize := FormatDesc.GetSize(Png.Header.Width, 1);
5809 GetMem(NewImage, LineSize * Integer(Png.Header.Height));
5813 case Png.Header.ColorType of
5814 COLOR_RGB, COLOR_GRAYSCALE:
5816 for Row := 0 to Png.Height -1 do begin
5817 Move (Png.Scanline[Row]^, pDest^, LineSize);
5818 Inc(pDest, LineSize);
5821 COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA:
5823 PixSize := PixSize -1;
5825 for Row := 0 to Png.Height -1 do begin
5826 pSource := Png.Scanline[Row];
5827 pAlpha := pByte(Png.AlphaScanline[Row]);
5829 for Col := 0 to Png.Width -1 do begin
5830 Move (pSource^, pDest^, PixSize);
5831 Inc(pSource, PixSize);
5832 Inc(pDest, PixSize);
5841 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
5844 SetDataPointer(NewImage, PngFormat, Png.Header.Width, Png.Header.Height); //be careful, Data could be freed by this method
5848 if Assigned(NewImage) then
5860 {$IFDEF GLB_SUPPORT_PNG_WRITE}
5861 {$IFDEF GLB_LIB_PNG}
5862 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5863 procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
5865 TStream(png_get_io_ptr(png)).Write(buffer^, size);
5869 {$IF DEFINED(GLB_LIB_PNG)}
5870 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5871 procedure TglBitmap.SavePNG(const aStream: TStream);
5874 png_info: png_infop;
5875 png_rows: array of pByte;
5879 FormatDesc: TFormatDescriptor;
5881 if not (ftPNG in FormatGetSupportedFiles(Format)) then
5882 raise EglBitmapUnsupportedFormat.Create(Format);
5884 if not init_libPNG then
5885 raise Exception.Create('unable to initialize libPNG.');
5889 tfAlpha8, tfLuminance8:
5890 ColorType := PNG_COLOR_TYPE_GRAY;
5892 ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
5894 ColorType := PNG_COLOR_TYPE_RGB;
5896 ColorType := PNG_COLOR_TYPE_RGBA;
5898 raise EglBitmapUnsupportedFormat.Create(Format);
5901 FormatDesc := TFormatDescriptor.Get(Format);
5902 LineSize := FormatDesc.GetSize(Width, 1);
5904 // creating array for scanline
5905 SetLength(png_rows, Height);
5907 for Row := 0 to Height - 1 do begin
5908 png_rows[Row] := Data;
5909 Inc(png_rows[Row], Row * LineSize)
5913 png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
5915 raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
5918 png_info := png_create_info_struct(png);
5919 if png_info = nil then begin
5920 png_destroy_write_struct(@png, nil);
5921 raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
5924 // set read callback
5925 png_set_write_fn(png, aStream, glBitmap_libPNG_write_func, nil);
5928 png_set_compression_level(png, 6);
5930 if Format in [tfBGR8, tfBGRA8] then
5933 png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
5934 png_write_info(png, png_info);
5935 png_write_image(png, @png_rows[0]);
5936 png_write_end(png, png_info);
5937 png_destroy_write_struct(@png, @png_info);
5939 SetLength(png_rows, 0);
5946 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
5947 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5948 procedure TglBitmap.SavePNG(const aStream: TStream);
5952 pSource, pDest: pByte;
5953 X, Y, PixSize: Integer;
5954 ColorType: Cardinal;
5960 if not (ftPNG in FormatGetSupportedFiles (Format)) then
5961 raise EglBitmapUnsupportedFormat.Create(Format);
5964 tfAlpha8, tfLuminance8: begin
5965 ColorType := COLOR_GRAYSCALE;
5969 tfLuminance8Alpha8: begin
5970 ColorType := COLOR_GRAYSCALEALPHA;
5974 tfBGR8, tfRGB8: begin
5975 ColorType := COLOR_RGB;
5979 tfBGRA8, tfRGBA8: begin
5980 ColorType := COLOR_RGBALPHA;
5985 raise EglBitmapUnsupportedFormat.Create(Format);
5988 Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
5992 for Y := 0 to Height -1 do begin
5993 pDest := png.ScanLine[Y];
5994 for X := 0 to Width -1 do begin
5995 Move(pSource^, pDest^, PixSize);
5996 Inc(pDest, PixSize);
5997 Inc(pSource, PixSize);
5999 png.AlphaScanline[Y]^[X] := pSource^;
6004 // convert RGB line to BGR
6005 if Format in [tfRGB8, tfRGBA8] then begin
6006 pTemp := png.ScanLine[Y];
6007 for X := 0 to Width -1 do begin
6008 Temp := pByteArray(pTemp)^[0];
6009 pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
6010 pByteArray(pTemp)^[2] := Temp;
6017 Png.CompressionLevel := 6;
6018 Png.SaveToStream(aStream);
6026 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6027 //JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6028 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6029 {$IFDEF GLB_LIB_JPEG}
6031 glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
6032 glBitmap_libJPEG_source_mgr = record
6033 pub: jpeg_source_mgr;
6036 SrcBuffer: array [1..4096] of byte;
6039 glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
6040 glBitmap_libJPEG_dest_mgr = record
6041 pub: jpeg_destination_mgr;
6043 DestStream: TStream;
6044 DestBuffer: array [1..4096] of byte;
6047 procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
6053 procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
6059 procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
6064 procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
6070 procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
6076 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6077 function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
6079 src: glBitmap_libJPEG_source_mgr_ptr;
6082 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
6084 bytes := src^.SrcStream.Read(src^.SrcBuffer[1], 4096);
6085 if (bytes <= 0) then begin
6086 src^.SrcBuffer[1] := $FF;
6087 src^.SrcBuffer[2] := JPEG_EOI;
6091 src^.pub.next_input_byte := @(src^.SrcBuffer[1]);
6092 src^.pub.bytes_in_buffer := bytes;
6097 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6098 procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
6100 src: glBitmap_libJPEG_source_mgr_ptr;
6102 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
6104 if num_bytes > 0 then begin
6105 // wanted byte isn't in buffer so set stream position and read buffer
6106 if num_bytes > src^.pub.bytes_in_buffer then begin
6107 src^.SrcStream.Position := src^.SrcStream.Position + num_bytes - src^.pub.bytes_in_buffer;
6108 src^.pub.fill_input_buffer(cinfo);
6110 // wanted byte is in buffer so only skip
6111 inc(src^.pub.next_input_byte, num_bytes);
6112 dec(src^.pub.bytes_in_buffer, num_bytes);
6117 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6118 function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
6120 dest: glBitmap_libJPEG_dest_mgr_ptr;
6122 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
6124 if dest^.pub.free_in_buffer < Cardinal(Length(dest^.DestBuffer)) then begin
6125 // write complete buffer
6126 dest^.DestStream.Write(dest^.DestBuffer[1], SizeOf(dest^.DestBuffer));
6129 dest^.pub.next_output_byte := @dest^.DestBuffer[1];
6130 dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
6136 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6137 procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
6140 dest: glBitmap_libJPEG_dest_mgr_ptr;
6142 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
6144 for Idx := Low(dest^.DestBuffer) to High(dest^.DestBuffer) do begin
6145 // check for endblock
6146 if (Idx < High(dest^.DestBuffer)) and (dest^.DestBuffer[Idx] = $FF) and (dest^.DestBuffer[Idx +1] = JPEG_EOI) then begin
6148 dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
6153 dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
6158 {$IFDEF GLB_SUPPORT_JPEG_READ}
6159 {$IF DEFINED(GLB_SDL_IMAGE)}
6160 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6161 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6163 Surface: PSDL_Surface;
6168 RWops := glBitmapCreateRWops(aStream);
6170 if IMG_isJPG(RWops) > 0 then begin
6171 Surface := IMG_LoadJPG_RW(RWops);
6173 AssignFromSurface(Surface);
6176 SDL_FreeSurface(Surface);
6184 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
6185 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6186 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6189 Temp: array[0..1]of Byte;
6191 jpeg: jpeg_decompress_struct;
6192 jpeg_err: jpeg_error_mgr;
6194 IntFormat: TglBitmapFormat;
6196 TempHeight, TempWidth: Integer;
6201 FormatDesc: TFormatDescriptor;
6205 if not init_libJPEG then
6206 raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
6209 // reading first two bytes to test file and set cursor back to begin
6210 StreamPos := aStream.Position;
6211 aStream.Read({%H-}Temp[0], 2);
6212 aStream.Position := StreamPos;
6214 // if Bitmap then read file.
6215 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
6216 FillChar(jpeg{%H-}, SizeOf(jpeg_decompress_struct), $00);
6217 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
6220 jpeg.err := jpeg_std_error(@jpeg_err);
6221 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
6222 jpeg_err.output_message := glBitmap_libJPEG_output_message;
6224 // decompression struct
6225 jpeg_create_decompress(@jpeg);
6227 // allocation space for streaming methods
6228 jpeg.src := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_source_mgr));
6230 // seeting up custom functions
6231 with glBitmap_libJPEG_source_mgr_ptr(jpeg.src)^ do begin
6232 pub.init_source := glBitmap_libJPEG_init_source;
6233 pub.fill_input_buffer := glBitmap_libJPEG_fill_input_buffer;
6234 pub.skip_input_data := glBitmap_libJPEG_skip_input_data;
6235 pub.resync_to_restart := jpeg_resync_to_restart; // use default method
6236 pub.term_source := glBitmap_libJPEG_term_source;
6238 pub.bytes_in_buffer := 0; // forces fill_input_buffer on first read
6239 pub.next_input_byte := nil; // until buffer loaded
6241 SrcStream := aStream;
6244 // set global decoding state
6245 jpeg.global_state := DSTATE_START;
6247 // read header of jpeg
6248 jpeg_read_header(@jpeg, false);
6250 // setting output parameter
6251 case jpeg.jpeg_color_space of
6254 jpeg.out_color_space := JCS_GRAYSCALE;
6255 IntFormat := tfLuminance8;
6258 jpeg.out_color_space := JCS_RGB;
6259 IntFormat := tfRGB8;
6263 jpeg_start_decompress(@jpeg);
6265 TempHeight := jpeg.output_height;
6266 TempWidth := jpeg.output_width;
6268 FormatDesc := TFormatDescriptor.Get(IntFormat);
6270 // creating new image
6271 GetMem(pImage, FormatDesc.GetSize(TempWidth, TempHeight));
6275 for Row := 0 to TempHeight -1 do begin
6276 jpeg_read_scanlines(@jpeg, @pTemp, 1);
6277 Inc(pTemp, FormatDesc.GetSize(TempWidth, 1));
6280 // finish decompression
6281 jpeg_finish_decompress(@jpeg);
6283 // destroy decompression
6284 jpeg_destroy_decompress(@jpeg);
6286 SetDataPointer(pImage, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
6290 if Assigned(pImage) then
6300 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
6301 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6302 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6307 Temp: array[0..1]of Byte;
6311 // reading first two bytes to test file and set cursor back to begin
6312 StreamPos := aStream.Position;
6313 aStream.Read(Temp[0], 2);
6314 aStream.Position := StreamPos;
6316 // if Bitmap then read file.
6317 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
6318 bmp := TBitmap.Create;
6320 jpg := TJPEGImage.Create;
6322 jpg.LoadFromStream(aStream);
6324 result := AssignFromBitmap(bmp);
6336 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
6337 {$IF DEFINED(GLB_LIB_JPEG)}
6338 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6339 procedure TglBitmap.SaveJPEG(const aStream: TStream);
6341 jpeg: jpeg_compress_struct;
6342 jpeg_err: jpeg_error_mgr;
6344 pTemp, pTemp2: pByte;
6346 procedure CopyRow(pDest, pSource: pByte);
6350 for X := 0 to Width - 1 do begin
6351 pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
6352 pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
6353 pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
6360 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
6361 raise EglBitmapUnsupportedFormat.Create(Format);
6363 if not init_libJPEG then
6364 raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
6367 FillChar(jpeg{%H-}, SizeOf(jpeg_compress_struct), $00);
6368 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
6371 jpeg.err := jpeg_std_error(@jpeg_err);
6372 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
6373 jpeg_err.output_message := glBitmap_libJPEG_output_message;
6375 // compression struct
6376 jpeg_create_compress(@jpeg);
6378 // allocation space for streaming methods
6379 jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
6381 // seeting up custom functions
6382 with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
6383 pub.init_destination := glBitmap_libJPEG_init_destination;
6384 pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
6385 pub.term_destination := glBitmap_libJPEG_term_destination;
6387 pub.next_output_byte := @DestBuffer[1];
6388 pub.free_in_buffer := Length(DestBuffer);
6390 DestStream := aStream;
6393 // very important state
6394 jpeg.global_state := CSTATE_START;
6395 jpeg.image_width := Width;
6396 jpeg.image_height := Height;
6398 tfAlpha8, tfLuminance8: begin
6399 jpeg.input_components := 1;
6400 jpeg.in_color_space := JCS_GRAYSCALE;
6402 tfRGB8, tfBGR8: begin
6403 jpeg.input_components := 3;
6404 jpeg.in_color_space := JCS_RGB;
6408 jpeg_set_defaults(@jpeg);
6409 jpeg_set_quality(@jpeg, 95, true);
6410 jpeg_start_compress(@jpeg, true);
6413 if Format = tfBGR8 then
6414 GetMem(pTemp2, fRowSize)
6419 for Row := 0 to jpeg.image_height -1 do begin
6421 if Format = tfBGR8 then
6422 CopyRow(pTemp2, pTemp)
6427 jpeg_write_scanlines(@jpeg, @pTemp2, 1);
6428 inc(pTemp, fRowSize);
6432 if Format = tfBGR8 then
6435 jpeg_finish_compress(@jpeg);
6436 jpeg_destroy_compress(@jpeg);
6442 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
6443 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6444 procedure TglBitmap.SaveJPEG(const aStream: TStream);
6449 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
6450 raise EglBitmapUnsupportedFormat.Create(Format);
6452 Bmp := TBitmap.Create;
6454 Jpg := TJPEGImage.Create;
6456 AssignToBitmap(Bmp);
6457 if (Format in [tfAlpha8, tfLuminance8]) then begin
6458 Jpg.Grayscale := true;
6459 Jpg.PixelFormat := jf8Bit;
6462 Jpg.SaveToStream(aStream);
6473 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6474 //BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6475 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6482 BMP_COMP_BITFIELDS = 3;
6485 TBMPHeader = packed record
6490 bfOffBits: Cardinal;
6493 TBMPInfo = packed record
6499 biCompression: Cardinal;
6500 biSizeImage: Cardinal;
6501 biXPelsPerMeter: Longint;
6502 biYPelsPerMeter: Longint;
6503 biClrUsed: Cardinal;
6504 biClrImportant: Cardinal;
6507 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6508 function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
6510 //////////////////////////////////////////////////////////////////////////////////////////////////
6511 function ReadInfo(out aInfo: TBMPInfo; out aMask: TglBitmapColorRec): TglBitmapFormat;
6514 aStream.Read(aInfo{%H-}, SizeOf(aInfo));
6515 FillChar(aMask{%H-}, SizeOf(aMask), 0);
6518 case aInfo.biCompression of
6520 BMP_COMP_RLE8: begin
6521 raise EglBitmap.Create('RLE compression is not supported');
6523 BMP_COMP_BITFIELDS: begin
6524 if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
6525 aStream.Read(aMask.r, SizeOf(aMask.r));
6526 aStream.Read(aMask.g, SizeOf(aMask.g));
6527 aStream.Read(aMask.b, SizeOf(aMask.b));
6528 aStream.Read(aMask.a, SizeOf(aMask.a));
6530 raise EglBitmap.Create('Bitfields are only supported for 16bit and 32bit formats');
6534 //get suitable format
6535 case aInfo.biBitCount of
6536 8: result := tfLuminance8;
6537 16: result := tfBGR5;
6538 24: result := tfBGR8;
6539 32: result := tfBGRA8;
6543 function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TbmpColorTableFormat;
6546 ColorTable: TbmpColorTable;
6549 if (aInfo.biBitCount >= 16) then
6551 aFormat := tfLuminance8;
6552 c := aInfo.biClrUsed;
6554 c := 1 shl aInfo.biBitCount;
6555 SetLength(ColorTable, c);
6556 for i := 0 to c-1 do begin
6557 aStream.Read(ColorTable[i], SizeOf(TbmpColorTableEnty));
6558 if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then
6562 result := TbmpColorTableFormat.Create;
6563 result.PixelSize := aInfo.biBitCount / 8;
6564 result.ColorTable := ColorTable;
6565 result.Range := glBitmapColorRec($FF, $FF, $FF, $00);
6568 //////////////////////////////////////////////////////////////////////////////////////////////////
6569 function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapColorRec;
6570 const aInfo: TBMPInfo): TbmpBitfieldFormat;
6572 TmpFormat: TglBitmapFormat;
6573 FormatDesc: TFormatDescriptor;
6576 if (aMask.r <> 0) or (aMask.g <> 0) or (aMask.b <> 0) or (aMask.a <> 0) then begin
6577 for TmpFormat := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
6578 FormatDesc := TFormatDescriptor.Get(TmpFormat);
6579 if FormatDesc.MaskMatch(aMask.r, aMask.g, aMask.b, aMask.a) then begin
6580 aFormat := FormatDesc.Format;
6585 if (aMask.a = 0) and TFormatDescriptor.Get(aFormat).HasAlpha then
6586 aFormat := TFormatDescriptor.Get(aFormat).WithoutAlpha;
6587 if (aMask.a <> 0) and not TFormatDescriptor.Get(aFormat).HasAlpha then
6588 aFormat := TFormatDescriptor.Get(aFormat).WithAlpha;
6590 result := TbmpBitfieldFormat.Create;
6591 result.PixelSize := aInfo.biBitCount / 8;
6592 result.RedMask := aMask.r;
6593 result.GreenMask := aMask.g;
6594 result.BlueMask := aMask.b;
6595 result.AlphaMask := aMask.a;
6602 ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
6603 PaddingBuff: Cardinal;
6604 LineBuf, ImageData, TmpData: PByte;
6605 SourceMD, DestMD: Pointer;
6606 BmpFormat: TglBitmapFormat;
6609 Mask: TglBitmapColorRec;
6614 SpecialFormat: TFormatDescriptor;
6615 FormatDesc: TFormatDescriptor;
6617 //////////////////////////////////////////////////////////////////////////////////////////////////
6618 procedure SpecialFormatReadLine(aData: PByte; aLineBuf: PByte);
6621 Pixel: TglBitmapPixelData;
6623 aStream.Read(aLineBuf^, rbLineSize);
6624 SpecialFormat.PreparePixel(Pixel);
6625 for i := 0 to Info.biWidth-1 do begin
6626 SpecialFormat.Unmap(aLineBuf, Pixel, SourceMD);
6627 glBitmapConvertPixel(Pixel, SpecialFormat, FormatDesc);
6628 FormatDesc.Map(Pixel, aData, DestMD);
6634 BmpFormat := tfEmpty;
6635 SpecialFormat := nil;
6641 StartPos := aStream.Position;
6642 aStream.Read(Header{%H-}, SizeOf(Header));
6644 if Header.bfType = BMP_MAGIC then begin
6646 BmpFormat := ReadInfo(Info, Mask);
6647 SpecialFormat := ReadColorTable(BmpFormat, Info);
6648 if not Assigned(SpecialFormat) then
6649 SpecialFormat := CheckBitfields(BmpFormat, Mask, Info);
6650 aStream.Position := StartPos + Header.bfOffBits;
6652 if (BmpFormat <> tfEmpty) then begin
6653 FormatDesc := TFormatDescriptor.Get(BmpFormat);
6654 rbLineSize := Round(Info.biWidth * Info.biBitCount / 8); //ReadBuffer LineSize
6655 wbLineSize := Trunc(Info.biWidth * FormatDesc.PixelSize);
6656 Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
6659 DestMD := FormatDesc.CreateMappingData;
6660 ImageSize := FormatDesc.GetSize(Info.biWidth, abs(Info.biHeight));
6661 GetMem(ImageData, ImageSize);
6662 if Assigned(SpecialFormat) then begin
6663 GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
6664 SourceMD := SpecialFormat.CreateMappingData;
6669 FillChar(ImageData^, ImageSize, $FF);
6670 TmpData := ImageData;
6671 if (Info.biHeight > 0) then
6672 Inc(TmpData, wbLineSize * (Info.biHeight-1));
6673 for i := 0 to Abs(Info.biHeight)-1 do begin
6674 if Assigned(SpecialFormat) then
6675 SpecialFormatReadLine(TmpData, LineBuf) //if is special format read and convert data
6677 aStream.Read(TmpData^, wbLineSize); //else only read data
6678 if (Info.biHeight > 0) then
6679 dec(TmpData, wbLineSize)
6681 inc(TmpData, wbLineSize);
6682 aStream.Read(PaddingBuff{%H-}, Padding);
6684 SetDataPointer(ImageData, BmpFormat, Info.biWidth, abs(Info.biHeight)); //be careful, Data could be freed by this method
6687 if Assigned(LineBuf) then
6689 if Assigned(SourceMD) then
6690 SpecialFormat.FreeMappingData(SourceMD);
6691 FormatDesc.FreeMappingData(DestMD);
6694 if Assigned(ImageData) then
6699 raise EglBitmap.Create('LoadBMP - No suitable format found');
6701 aStream.Position := StartPos;
6705 FreeAndNil(SpecialFormat);
6708 else aStream.Position := StartPos;
6711 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6712 procedure TglBitmap.SaveBMP(const aStream: TStream);
6716 Converter: TbmpColorTableFormat;
6717 FormatDesc: TFormatDescriptor;
6718 SourceFD, DestFD: Pointer;
6719 pData, srcData, dstData, ConvertBuffer: pByte;
6721 Pixel: TglBitmapPixelData;
6722 ImageSize, wbLineSize, rbLineSize, Padding, LineIdx, PixelIdx: Integer;
6723 RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
6725 PaddingBuff: Cardinal;
6727 function GetLineWidth : Integer;
6729 result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
6733 if not (ftBMP in FormatGetSupportedFiles(Format)) then
6734 raise EglBitmapUnsupportedFormat.Create(Format);
6737 FormatDesc := TFormatDescriptor.Get(Format);
6738 ImageSize := FormatDesc.GetSize(Dimension);
6740 FillChar(Header{%H-}, SizeOf(Header), 0);
6741 Header.bfType := BMP_MAGIC;
6742 Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
6743 Header.bfReserved1 := 0;
6744 Header.bfReserved2 := 0;
6745 Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
6747 FillChar(Info{%H-}, SizeOf(Info), 0);
6748 Info.biSize := SizeOf(Info);
6749 Info.biWidth := Width;
6750 Info.biHeight := Height;
6752 Info.biCompression := BMP_COMP_RGB;
6753 Info.biSizeImage := ImageSize;
6758 Info.biBitCount := 4;
6759 Header.bfSize := Header.bfSize + 16 * SizeOf(Cardinal);
6760 Header.bfOffBits := Header.bfOffBits + 16 * SizeOf(Cardinal); //16 ColorTable entries
6761 Converter := TbmpColorTableFormat.Create;
6762 Converter.PixelSize := 0.5;
6763 Converter.Format := Format;
6764 Converter.Range := glBitmapColorRec($F, $F, $F, $0);
6765 Converter.CreateColorTable;
6768 tfR3G3B2, tfLuminance8: begin
6769 Info.biBitCount := 8;
6770 Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
6771 Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal); //256 ColorTable entries
6772 Converter := TbmpColorTableFormat.Create;
6773 Converter.PixelSize := 1;
6774 Converter.Format := Format;
6775 if (Format = tfR3G3B2) then begin
6776 Converter.Range := glBitmapColorRec($7, $7, $3, $0);
6777 Converter.Shift := glBitmapShiftRec(0, 3, 6, 0);
6779 Converter.Range := glBitmapColorRec($FF, $FF, $FF, $0);
6780 Converter.CreateColorTable;
6783 tfRGB4, tfRGB5, tfR5G6B5, tfRGB5A1, tfRGBA4,
6784 tfBGR4, tfBGR5, tfB5G6R5, tfBGR5A1, tfBGRA4: begin
6785 Info.biBitCount := 16;
6786 Info.biCompression := BMP_COMP_BITFIELDS;
6789 tfBGR8, tfRGB8: begin
6790 Info.biBitCount := 24;
6793 tfRGB10, tfRGB10A2, tfRGBA8,
6794 tfBGR10, tfBGR10A2, tfBGRA8: begin
6795 Info.biBitCount := 32;
6796 Info.biCompression := BMP_COMP_BITFIELDS;
6799 raise EglBitmapUnsupportedFormat.Create(Format);
6801 Info.biXPelsPerMeter := 2835;
6802 Info.biYPelsPerMeter := 2835;
6805 if Info.biCompression = BMP_COMP_BITFIELDS then begin
6806 Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
6807 Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
6809 RedMask := FormatDesc.RedMask;
6810 GreenMask := FormatDesc.GreenMask;
6811 BlueMask := FormatDesc.BlueMask;
6812 AlphaMask := FormatDesc.AlphaMask;
6816 aStream.Write(Header, SizeOf(Header));
6817 aStream.Write(Info, SizeOf(Info));
6820 if Assigned(Converter) then
6821 aStream.Write(Converter.ColorTable[0].b,
6822 SizeOf(TbmpColorTableEnty) * Length(Converter.ColorTable));
6825 if Info.biCompression = BMP_COMP_BITFIELDS then begin
6826 aStream.Write(RedMask, SizeOf(Cardinal));
6827 aStream.Write(GreenMask, SizeOf(Cardinal));
6828 aStream.Write(BlueMask, SizeOf(Cardinal));
6829 aStream.Write(AlphaMask, SizeOf(Cardinal));
6833 rbLineSize := Round(Info.biWidth * FormatDesc.PixelSize);
6834 wbLineSize := Round(Info.biWidth * Info.biBitCount / 8);
6835 Padding := GetLineWidth - wbLineSize;
6839 inc(pData, (Height-1) * rbLineSize);
6841 // prepare row buffer. But only for RGB because RGBA supports color masks
6842 // so it's possible to change color within the image.
6843 if Assigned(Converter) then begin
6844 FormatDesc.PreparePixel(Pixel);
6845 GetMem(ConvertBuffer, wbLineSize);
6846 SourceFD := FormatDesc.CreateMappingData;
6847 DestFD := Converter.CreateMappingData;
6849 ConvertBuffer := nil;
6852 for LineIdx := 0 to Height - 1 do begin
6854 if Assigned(Converter) then begin
6856 dstData := ConvertBuffer;
6857 for PixelIdx := 0 to Info.biWidth-1 do begin
6858 FormatDesc.Unmap(srcData, Pixel, SourceFD);
6859 glBitmapConvertPixel(Pixel, FormatDesc, Converter);
6860 Converter.Map(Pixel, dstData, DestFD);
6862 aStream.Write(ConvertBuffer^, wbLineSize);
6864 aStream.Write(pData^, rbLineSize);
6866 dec(pData, rbLineSize);
6867 if (Padding > 0) then
6868 aStream.Write(PaddingBuff, Padding);
6871 // destroy row buffer
6872 if Assigned(ConvertBuffer) then begin
6873 FormatDesc.FreeMappingData(SourceFD);
6874 Converter.FreeMappingData(DestFD);
6875 FreeMem(ConvertBuffer);
6879 if Assigned(Converter) then
6884 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6885 //TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6886 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6888 TTGAHeader = packed record
6892 //ColorMapSpec: Array[0..4] of Byte;
6893 ColorMapStart: Word;
6894 ColorMapLength: Word;
6895 ColorMapEntrySize: Byte;
6905 TGA_UNCOMPRESSED_RGB = 2;
6906 TGA_UNCOMPRESSED_GRAY = 3;
6907 TGA_COMPRESSED_RGB = 10;
6908 TGA_COMPRESSED_GRAY = 11;
6910 TGA_NONE_COLOR_TABLE = 0;
6912 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6913 function TglBitmap.LoadTGA(const aStream: TStream): Boolean;
6916 ImageData: System.PByte;
6917 StartPosition: Int64;
6918 PixelSize, LineSize: Integer;
6919 tgaFormat: TglBitmapFormat;
6920 FormatDesc: TFormatDescriptor;
6921 Counter: packed record
6923 low, high, dir: Integer;
6930 ////////////////////////////////////////////////////////////////////////////////////////
6931 procedure ReadUncompressed;
6934 buf, tmp1, tmp2: System.PByte;
6937 if (Counter.X.dir < 0) then
6938 GetMem(buf, LineSize);
6940 while (Counter.Y.low <> Counter.Y.high + counter.Y.dir) do begin
6942 inc(tmp1, (Counter.Y.low * LineSize)); //pointer to LineStart
6943 if (Counter.X.dir < 0) then begin //flip X
6944 aStream.Read(buf^, LineSize);
6946 inc(tmp2, LineSize - PixelSize); //pointer to last pixel in line
6947 for i := 0 to Header.Width-1 do begin //for all pixels in line
6948 for j := 0 to PixelSize-1 do begin //for all bytes in pixel
6953 dec(tmp2, 2*PixelSize); //move 2 backwards, because j-loop moved 1 forward
6956 aStream.Read(tmp1^, LineSize);
6957 inc(Counter.Y.low, Counter.Y.dir); //move to next line index
6960 if Assigned(buf) then
6965 ////////////////////////////////////////////////////////////////////////////////////////
6966 procedure ReadCompressed;
6968 /////////////////////////////////////////////////////////////////
6970 TmpData: System.PByte;
6971 LinePixelsRead: Integer;
6972 procedure CheckLine;
6974 if (LinePixelsRead >= Header.Width) then begin
6975 LinePixelsRead := 0;
6976 inc(Counter.Y.low, Counter.Y.dir); //next line index
6977 TmpData := ImageData;
6978 inc(TmpData, Counter.Y.low * LineSize); //set line
6979 if (Counter.X.dir < 0) then //if x flipped then
6980 inc(TmpData, LineSize - PixelSize); //set last pixel
6984 /////////////////////////////////////////////////////////////////
6987 CacheSize, CachePos: Integer;
6988 procedure CachedRead(out Buffer; Count: Integer);
6992 if (CachePos + Count > CacheSize) then begin
6993 //if buffer overflow save non read bytes
6995 if (CacheSize - CachePos > 0) then begin
6996 BytesRead := CacheSize - CachePos;
6997 Move(PByteArray(Cache)^[CachePos], Buffer{%H-}, BytesRead);
6998 inc(CachePos, BytesRead);
7001 //load cache from file
7002 CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
7003 aStream.Read(Cache^, CacheSize);
7006 //read rest of requested bytes
7007 if (Count - BytesRead > 0) then begin
7008 Move(PByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
7009 inc(CachePos, Count - BytesRead);
7012 //if no buffer overflow just read the data
7013 Move(PByteArray(Cache)^[CachePos], Buffer, Count);
7014 inc(CachePos, Count);
7018 procedure PixelToBuffer(const aData: PByte; var aBuffer: PByte);
7023 inc(aBuffer, Counter.X.dir);
7026 PWord(aBuffer)^ := PWord(aData)^;
7027 inc(aBuffer, 2 * Counter.X.dir);
7030 PByteArray(aBuffer)^[0] := PByteArray(aData)^[0];
7031 PByteArray(aBuffer)^[1] := PByteArray(aData)^[1];
7032 PByteArray(aBuffer)^[2] := PByteArray(aData)^[2];
7033 inc(aBuffer, 3 * Counter.X.dir);
7036 PCardinal(aBuffer)^ := PCardinal(aData)^;
7037 inc(aBuffer, 4 * Counter.X.dir);
7043 TotalPixelsToRead, TotalPixelsRead: Integer;
7045 buf: array [0..3] of Byte; //1 pixel is max 32bit long
7046 PixelRepeat: Boolean;
7047 PixelsToRead, PixelCount: Integer;
7052 TotalPixelsToRead := Header.Width * Header.Height;
7053 TotalPixelsRead := 0;
7054 LinePixelsRead := 0;
7056 GetMem(Cache, CACHE_SIZE);
7058 TmpData := ImageData;
7059 inc(TmpData, Counter.Y.low * LineSize); //set line
7060 if (Counter.X.dir < 0) then //if x flipped then
7061 inc(TmpData, LineSize - PixelSize); //set last pixel
7065 CachedRead(Temp, 1);
7066 PixelRepeat := (Temp and $80) > 0;
7067 PixelsToRead := (Temp and $7F) + 1;
7068 inc(TotalPixelsRead, PixelsToRead);
7071 CachedRead(buf[0], PixelSize);
7072 while (PixelsToRead > 0) do begin
7074 PixelCount := Min(Header.Width - LinePixelsRead, PixelsToRead); //max read to EOL or EOF
7075 while (PixelCount > 0) do begin
7076 if not PixelRepeat then
7077 CachedRead(buf[0], PixelSize);
7078 PixelToBuffer(@buf[0], TmpData);
7079 inc(LinePixelsRead);
7084 until (TotalPixelsRead >= TotalPixelsToRead);
7090 function IsGrayFormat: Boolean;
7092 result := Header.ImageType in [TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_GRAY];
7098 // reading header to test file and set cursor back to begin
7099 StartPosition := aStream.Position;
7100 aStream.Read(Header{%H-}, SizeOf(Header));
7102 // no colormapped files
7103 if (Header.ColorMapType = TGA_NONE_COLOR_TABLE) and (Header.ImageType in [
7104 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY]) then
7107 if Header.ImageID <> 0 then // skip image ID
7108 aStream.Position := aStream.Position + Header.ImageID;
7110 tgaFormat := tfEmpty;
7112 8: if IsGrayFormat then case (Header.ImageDesc and $F) of
7113 0: tgaFormat := tfLuminance8;
7114 8: tgaFormat := tfAlpha8;
7117 16: if IsGrayFormat then case (Header.ImageDesc and $F) of
7118 0: tgaFormat := tfLuminance16;
7119 8: tgaFormat := tfLuminance8Alpha8;
7120 end else case (Header.ImageDesc and $F) of
7121 0: tgaFormat := tfBGR5;
7122 1: tgaFormat := tfBGR5A1;
7123 4: tgaFormat := tfBGRA4;
7126 24: if not IsGrayFormat then case (Header.ImageDesc and $F) of
7127 0: tgaFormat := tfBGR8;
7130 32: if not IsGrayFormat then case (Header.ImageDesc and $F) of
7131 2: tgaFormat := tfBGR10A2;
7132 8: tgaFormat := tfBGRA8;
7136 if (tgaFormat = tfEmpty) then
7137 raise EglBitmap.Create('LoadTga - unsupported format');
7139 FormatDesc := TFormatDescriptor.Get(tgaFormat);
7140 PixelSize := FormatDesc.GetSize(1, 1);
7141 LineSize := FormatDesc.GetSize(Header.Width, 1);
7143 GetMem(ImageData, LineSize * Header.Height);
7146 if ((Header.ImageDesc and (1 shl 4)) > 0) then begin
7147 Counter.X.low := Header.Height-1;;
7148 Counter.X.high := 0;
7149 Counter.X.dir := -1;
7152 Counter.X.high := Header.Height-1;
7157 if ((Header.ImageDesc and (1 shl 5)) > 0) then begin
7159 Counter.Y.high := Header.Height-1;
7162 Counter.Y.low := Header.Height-1;;
7163 Counter.Y.high := 0;
7164 Counter.Y.dir := -1;
7168 case Header.ImageType of
7169 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY:
7171 TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY:
7175 SetDataPointer(ImageData, tgaFormat, Header.Width, Header.Height); //be careful, Data could be freed by this method
7178 if Assigned(ImageData) then
7183 aStream.Position := StartPosition;
7186 else aStream.Position := StartPosition;
7189 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7190 procedure TglBitmap.SaveTGA(const aStream: TStream);
7193 LineSize, Size, x, y: Integer;
7194 Pixel: TglBitmapPixelData;
7195 LineBuf, SourceData, DestData: PByte;
7196 SourceMD, DestMD: Pointer;
7197 FormatDesc: TFormatDescriptor;
7198 Converter: TFormatDescriptor;
7200 if not (ftTGA in FormatGetSupportedFiles(Format)) then
7201 raise EglBitmapUnsupportedFormat.Create(Format);
7204 FillChar(Header{%H-}, SizeOf(Header), 0);
7207 if (Format in [tfLuminance8, tfLuminance6Alpha2, tfLuminance4Alpha4, tfAlpha8,
7208 tfLuminance16, tfLuminance12Alpha4, tfLuminance8Alpha8]) then
7209 Header.ImageType := TGA_UNCOMPRESSED_GRAY
7211 Header.ImageType := TGA_UNCOMPRESSED_RGB;
7214 if (Format in [tfLuminance8, tfLuminance6Alpha2, tfLuminance4Alpha4, tfAlpha8]) then
7216 else if (Format in [tfLuminance16, tfLuminance12Alpha4, tfLuminance8Alpha8,
7217 tfRGB5, tfBGR5, tfRGB5A1, tfBGR5A1, tfRGBA4, tfBGRA4]) then
7219 else if (Format in [tfBGR8, tfRGB8]) then
7227 Header.ImageDesc := 1 and $F;
7228 tfRGB10A2, tfBGR10A2:
7229 Header.ImageDesc := 2 and $F;
7231 Header.ImageDesc := 4 and $F;
7232 tfAlpha8, tfLuminance8Alpha8, tfRGBA8, tfBGRA8:
7233 Header.ImageDesc := 8 and $F;
7236 Header.Width := Width;
7237 Header.Height := Height;
7238 Header.ImageDesc := Header.ImageDesc or $20; //flip y
7239 aStream.Write(Header, SizeOf(Header));
7241 // convert RGB(A) to BGR(A)
7243 FormatDesc := TFormatDescriptor.Get(Format);
7244 Size := FormatDesc.GetSize(Dimension);
7245 if Format in [tfRGB5, tfRGB5A1, tfRGBA4, tfRGB8, tfRGB10A2, tfRGBA8] then begin
7246 if (FormatDesc.RGBInverted = tfEmpty) then
7247 raise EglBitmap.Create('inverted RGB format is empty');
7248 Converter := TFormatDescriptor.Get(FormatDesc.RGBInverted);
7249 if not glBitmapColorRecCmp(Converter.Range, FormatDesc.Range) or
7250 (Converter.PixelSize <> FormatDesc.PixelSize) then
7251 raise EglBitmap.Create('invalid inverted RGB format');
7254 if Assigned(Converter) then begin
7255 LineSize := FormatDesc.GetSize(Width, 1);
7256 GetMem(LineBuf, LineSize);
7257 SourceMD := FormatDesc.CreateMappingData;
7258 DestMD := Converter.CreateMappingData;
7261 for y := 0 to Height-1 do begin
7262 DestData := LineBuf;
7263 for x := 0 to Width-1 do begin
7264 FormatDesc.Unmap(SourceData, Pixel, SourceMD);
7265 Converter.Map(Pixel, DestData, DestMD);
7267 aStream.Write(LineBuf^, LineSize);
7271 FormatDesc.FreeMappingData(SourceMD);
7272 FormatDesc.FreeMappingData(DestMD);
7275 aStream.Write(Data^, Size);
7278 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7279 //DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7280 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7282 DDS_MAGIC: Cardinal = $20534444;
7284 // DDS_header.dwFlags
7285 DDSD_CAPS = $00000001;
7286 DDSD_HEIGHT = $00000002;
7287 DDSD_WIDTH = $00000004;
7288 DDSD_PIXELFORMAT = $00001000;
7290 // DDS_header.sPixelFormat.dwFlags
7291 DDPF_ALPHAPIXELS = $00000001;
7292 DDPF_ALPHA = $00000002;
7293 DDPF_FOURCC = $00000004;
7294 DDPF_RGB = $00000040;
7295 DDPF_LUMINANCE = $00020000;
7297 // DDS_header.sCaps.dwCaps1
7298 DDSCAPS_TEXTURE = $00001000;
7300 // DDS_header.sCaps.dwCaps2
7301 DDSCAPS2_CUBEMAP = $00000200;
7303 D3DFMT_DXT1 = $31545844;
7304 D3DFMT_DXT3 = $33545844;
7305 D3DFMT_DXT5 = $35545844;
7308 TDDSPixelFormat = packed record
7312 dwRGBBitCount: Cardinal;
7313 dwRBitMask: Cardinal;
7314 dwGBitMask: Cardinal;
7315 dwBBitMask: Cardinal;
7316 dwABitMask: Cardinal;
7319 TDDSCaps = packed record
7323 dwReserved: Cardinal;
7326 TDDSHeader = packed record
7331 dwPitchOrLinearSize: Cardinal;
7333 dwMipMapCount: Cardinal;
7334 dwReserved: array[0..10] of Cardinal;
7335 PixelFormat: TDDSPixelFormat;
7337 dwReserved2: Cardinal;
7340 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7341 function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
7344 Converter: TbmpBitfieldFormat;
7346 function GetDDSFormat: TglBitmapFormat;
7348 fd: TFormatDescriptor;
7350 Range: TglBitmapColorRec;
7354 with Header.PixelFormat do begin
7356 if ((dwFlags and DDPF_FOURCC) > 0) then begin
7357 case Header.PixelFormat.dwFourCC of
7358 D3DFMT_DXT1: result := tfS3tcDtx1RGBA;
7359 D3DFMT_DXT3: result := tfS3tcDtx3RGBA;
7360 D3DFMT_DXT5: result := tfS3tcDtx5RGBA;
7362 end else if ((Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0) then begin
7364 //find matching format
7365 for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
7366 fd := TFormatDescriptor.Get(result);
7367 if fd.MaskMatch(dwRBitMask, dwGBitMask, dwBBitMask, dwABitMask) and
7368 (8 * fd.PixelSize = dwRGBBitCount) then
7372 //find format with same Range
7373 Range.r := dwRBitMask;
7374 Range.g := dwGBitMask;
7375 Range.b := dwBBitMask;
7376 Range.a := dwABitMask;
7377 for i := 0 to 3 do begin
7378 while ((Range.arr[i] and 1) = 0) and (Range.arr[i] > 0) do
7379 Range.arr[i] := Range.arr[i] shr 1;
7381 for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
7382 fd := TFormatDescriptor.Get(result);
7385 if (fd.Range.arr[i] <> Range.arr[i]) then begin
7393 //no format with same range found -> use default
7394 if (result = tfEmpty) then begin
7395 if (dwABitMask > 0) then
7401 Converter := TbmpBitfieldFormat.Create;
7402 Converter.RedMask := dwRBitMask;
7403 Converter.GreenMask := dwGBitMask;
7404 Converter.BlueMask := dwBBitMask;
7405 Converter.AlphaMask := dwABitMask;
7406 Converter.PixelSize := dwRGBBitCount / 8;
7413 x, y, LineSize, RowSize, Magic: Cardinal;
7414 NewImage, TmpData, RowData, SrcData: System.PByte;
7415 SourceMD, DestMD: Pointer;
7416 Pixel: TglBitmapPixelData;
7417 ddsFormat: TglBitmapFormat;
7418 FormatDesc: TFormatDescriptor;
7423 StreamPos := aStream.Position;
7426 aStream.Read(Magic{%H-}, sizeof(Magic));
7427 if (Magic <> DDS_MAGIC) then begin
7428 aStream.Position := StreamPos;
7433 aStream.Read(Header{%H-}, sizeof(Header));
7434 if (Header.dwSize <> SizeOf(Header)) or
7435 ((Header.dwFlags and (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) <>
7436 (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) then
7438 aStream.Position := StreamPos;
7442 if ((Header.Caps.dwCaps1 and DDSCAPS2_CUBEMAP) > 0) then
7443 raise EglBitmap.Create('LoadDDS - CubeMaps are not supported');
7445 ddsFormat := GetDDSFormat;
7447 if (ddsFormat = tfEmpty) then
7448 raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
7450 FormatDesc := TFormatDescriptor.Get(ddsFormat);
7451 LineSize := Trunc(Header.dwWidth * FormatDesc.PixelSize);
7452 GetMem(NewImage, Header.dwHeight * LineSize);
7454 TmpData := NewImage;
7457 if Assigned(Converter) then begin
7458 RowSize := Round(Header.dwWidth * Header.PixelFormat.dwRGBBitCount / 8);
7459 GetMem(RowData, RowSize);
7460 SourceMD := Converter.CreateMappingData;
7461 DestMD := FormatDesc.CreateMappingData;
7463 for y := 0 to Header.dwHeight-1 do begin
7464 TmpData := NewImage;
7465 inc(TmpData, y * LineSize);
7467 aStream.Read(SrcData^, RowSize);
7468 for x := 0 to Header.dwWidth-1 do begin
7469 Converter.Unmap(SrcData, Pixel, SourceMD);
7470 glBitmapConvertPixel(Pixel, Converter, FormatDesc);
7471 FormatDesc.Map(Pixel, TmpData, DestMD);
7475 Converter.FreeMappingData(SourceMD);
7476 FormatDesc.FreeMappingData(DestMD);
7482 if ((Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0) then begin
7483 RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
7484 for Y := 0 to Header.dwHeight-1 do begin
7485 aStream.Read(TmpData^, RowSize);
7486 Inc(TmpData, LineSize);
7491 if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0 then begin
7492 RowSize := (Header.PixelFormat.dwRGBBitCount * Header.dwWidth) shr 3;
7493 for Y := 0 to Header.dwHeight-1 do begin
7494 aStream.Read(TmpData^, RowSize);
7495 Inc(TmpData, LineSize);
7498 raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
7500 SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight); //be careful, Data could be freed by this method
7503 if Assigned(NewImage) then
7508 FreeAndNil(Converter);
7512 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7513 procedure TglBitmap.SaveDDS(const aStream: TStream);
7516 FormatDesc: TFormatDescriptor;
7518 if not (ftDDS in FormatGetSupportedFiles(Format)) then
7519 raise EglBitmapUnsupportedFormat.Create(Format);
7521 FormatDesc := TFormatDescriptor.Get(Format);
7524 FillChar(Header{%H-}, SizeOf(Header), 0);
7525 Header.dwSize := SizeOf(Header);
7526 Header.dwFlags := DDSD_WIDTH or DDSD_HEIGHT or DDSD_CAPS or DDSD_PIXELFORMAT;
7528 Header.dwWidth := Max(1, Width);
7529 Header.dwHeight := Max(1, Height);
7532 Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
7535 Header.PixelFormat.dwSize := sizeof(Header);
7536 if (FormatDesc.IsCompressed) then begin
7537 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_FOURCC;
7539 tfS3tcDtx1RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT1;
7540 tfS3tcDtx3RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT3;
7541 tfS3tcDtx5RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT5;
7543 end else if (Format in [tfAlpha8, tfAlpha16]) then begin
7544 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHA;
7545 Header.PixelFormat.dwRGBBitCount := Round(FormatDesc.PixelSize * 8);
7546 Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
7547 end else if (FormatDesc.RedMask = FormatDesc.GreenMask) and (FormatDesc.GreenMask = FormatDesc.BlueMask) then begin
7548 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_LUMINANCE;
7549 Header.PixelFormat.dwRGBBitCount := Round(FormatDesc.PixelSize * 8);
7550 Header.PixelFormat.dwRBitMask := FormatDesc.RedMask;
7551 Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
7553 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_RGB;
7554 Header.PixelFormat.dwRGBBitCount := Round(FormatDesc.PixelSize * 8);
7555 Header.PixelFormat.dwRBitMask := FormatDesc.RedMask;
7556 Header.PixelFormat.dwGBitMask := FormatDesc.GreenMask;
7557 Header.PixelFormat.dwBBitMask := FormatDesc.BlueMask;
7558 Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
7561 if (FormatDesc.HasAlpha) then
7562 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
7564 aStream.Write(DDS_MAGIC, sizeof(DDS_MAGIC));
7565 aStream.Write(Header, SizeOf(Header));
7566 aStream.Write(Data^, FormatDesc.GetSize(Dimension));
7569 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7570 //TglBitmap1D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7571 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7572 procedure TglBitmap1D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
7573 const aWidth: Integer; const aHeight: Integer);
7578 if (aHeight > 1) then begin
7579 Size := TFormatDescriptor.Get(aFormat).GetSize(aWidth, 1);
7580 GetMem(pTemp, Size);
7582 Move(aData^, pTemp^, Size);
7591 inherited SetDataPointer(pTemp, aFormat, aWidth);
7594 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7595 function TglBitmap1D.FlipHorz: Boolean;
7598 pTempDest, pDest, pSource: PByte;
7600 result := inherited FlipHorz;
7601 if Assigned(Data) and not TFormatDescriptor.Get(Format).IsCompressed then begin
7603 GetMem(pDest, fRowSize);
7606 Inc(pTempDest, fRowSize);
7607 for Col := 0 to Width-1 do begin
7608 dec(pTempDest, fPixelSize); //dec before, because ptr is behind last byte of data
7609 Move(pSource^, pTempDest^, fPixelSize);
7610 Inc(pSource, fPixelSize);
7612 SetDataPointer(pDest, Format, Width); //be careful, Data could be freed by this method
7615 if Assigned(pDest) then
7622 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7623 procedure TglBitmap1D.UploadData(const aBuildWithGlu: Boolean);
7625 FormatDesc: TFormatDescriptor;
7628 FormatDesc := TFormatDescriptor.Get(Format);
7629 if FormatDesc.IsCompressed then
7630 glCompressedTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.GetSize(Width, 1), Data)
7631 else if aBuildWithGlu then
7632 gluBuild1DMipmaps(Target, FormatDesc.glInternalFormat, Width, FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
7634 glTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
7637 if (FreeDataAfterGenTexture) then
7641 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7642 procedure TglBitmap1D.GenTexture(const aTestTextureSize: Boolean);
7644 BuildWithGlu, TexRec: Boolean;
7647 if Assigned(Data) then begin
7648 // Check Texture Size
7649 if (aTestTextureSize) then begin
7650 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
7652 if (Width > TexSize) then
7653 raise EglBitmapSizeToLarge.Create('TglBitmap1D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
7655 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
7656 (Target = GL_TEXTURE_RECTANGLE);
7657 if not (IsPowerOfTwo(Width) or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
7658 raise EglBitmapNonPowerOfTwo.Create('TglBitmap1D.GenTexture - Rendercontex dosn''t support non power of two texture.');
7662 SetupParameters(BuildWithGlu);
7663 UploadData(BuildWithGlu);
7664 glAreTexturesResident(1, @fID, @fIsResident);
7668 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7669 procedure TglBitmap1D.AfterConstruction;
7672 Target := GL_TEXTURE_1D;
7675 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7676 //TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7677 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7678 function TglBitmap2D.GetScanline(const aIndex: Integer): Pointer;
7680 if (aIndex >= Low(fLines)) and (aIndex <= High(fLines)) then
7681 result := fLines[aIndex]
7686 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7687 procedure TglBitmap2D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
7688 const aWidth: Integer; const aHeight: Integer);
7690 Idx, LineWidth: Integer;
7692 inherited SetDataPointer(aData, aFormat, aWidth, aHeight);
7694 if not TFormatDescriptor.Get(aFormat).IsCompressed then begin
7696 if Assigned(Data) then begin
7697 SetLength(fLines, GetHeight);
7698 LineWidth := Trunc(GetWidth * TFormatDescriptor.Get(Format).PixelSize);
7700 for Idx := 0 to GetHeight-1 do begin
7701 fLines[Idx] := Data;
7702 Inc(fLines[Idx], Idx * LineWidth);
7705 else SetLength(fLines, 0);
7707 SetLength(fLines, 0);
7711 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7712 procedure TglBitmap2D.UploadData(const aTarget: GLenum; const aBuildWithGlu: Boolean);
7714 FormatDesc: TFormatDescriptor;
7716 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
7718 FormatDesc := TFormatDescriptor.Get(Format);
7719 if FormatDesc.IsCompressed then begin
7720 glCompressedTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0, FormatDesc.GetSize(fDimension), Data)
7721 end else if aBuildWithGlu then begin
7722 gluBuild2DMipmaps(aTarget, FormatDesc.Components, Width, Height,
7723 FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
7725 glTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0,
7726 FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
7730 if (FreeDataAfterGenTexture) then
7734 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7735 procedure TglBitmap2D.AfterConstruction;
7738 Target := GL_TEXTURE_2D;
7741 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7742 procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
7745 Size, w, h: Integer;
7746 FormatDesc: TFormatDescriptor;
7748 FormatDesc := TFormatDescriptor.Get(aFormat);
7749 if FormatDesc.IsCompressed then
7750 raise EglBitmapUnsupportedFormat.Create(aFormat);
7752 w := aRight - aLeft;
7753 h := aBottom - aTop;
7754 Size := FormatDesc.GetSize(w, h);
7757 glPixelStorei(GL_PACK_ALIGNMENT, 1);
7758 glReadPixels(aLeft, aTop, w, h, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
7759 SetDataPointer(Temp, aFormat, w, h); //be careful, Data could be freed by this method
7762 if Assigned(Temp) then
7768 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7769 procedure TglBitmap2D.GetDataFromTexture;
7772 TempWidth, TempHeight: Integer;
7773 TempIntFormat: Cardinal;
7774 IntFormat, f: TglBitmapFormat;
7775 FormatDesc: TFormatDescriptor;
7780 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
7781 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
7782 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
7784 IntFormat := tfEmpty;
7785 for f := Low(TglBitmapFormat) to High(TglBitmapFormat) do begin
7786 FormatDesc := TFormatDescriptor.Get(f);
7787 if (FormatDesc.glInternalFormat = TempIntFormat) then begin
7788 IntFormat := FormatDesc.Format;
7793 // Getting data from OpenGL
7794 FormatDesc := TFormatDescriptor.Get(IntFormat);
7795 GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
7797 if FormatDesc.IsCompressed then
7798 glGetCompressedTexImage(Target, 0, Temp)
7800 glGetTexImage(Target, 0, FormatDesc.glInternalFormat, FormatDesc.glDataFormat, Temp);
7801 SetDataPointer(Temp, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
7803 if Assigned(Temp) then
7809 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7810 procedure TglBitmap2D.GenTexture(const aTestTextureSize: Boolean);
7812 BuildWithGlu, PotTex, TexRec: Boolean;
7815 if Assigned(Data) then begin
7816 // Check Texture Size
7817 if (aTestTextureSize) then begin
7818 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
7820 if ((Height > TexSize) or (Width > TexSize)) then
7821 raise EglBitmapSizeToLarge.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
7823 PotTex := IsPowerOfTwo(Height) and IsPowerOfTwo(Width);
7824 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE);
7825 if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
7826 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
7830 SetupParameters(BuildWithGlu);
7831 UploadData(Target, BuildWithGlu);
7832 glAreTexturesResident(1, @fID, @fIsResident);
7836 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7837 function TglBitmap2D.FlipHorz: Boolean;
7840 TempDestData, DestData, SourceData: PByte;
7843 result := inherited FlipHorz;
7844 if Assigned(Data) then begin
7846 ImgSize := Height * fRowSize;
7847 GetMem(DestData, ImgSize);
7849 TempDestData := DestData;
7850 Dec(TempDestData, fRowSize + fPixelSize);
7851 for Row := 0 to Height -1 do begin
7852 Inc(TempDestData, fRowSize * 2);
7853 for Col := 0 to Width -1 do begin
7854 Move(SourceData^, TempDestData^, fPixelSize);
7855 Inc(SourceData, fPixelSize);
7856 Dec(TempDestData, fPixelSize);
7859 SetDataPointer(DestData, Format); //be careful, Data could be freed by this method
7862 if Assigned(DestData) then
7869 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7870 function TglBitmap2D.FlipVert: Boolean;
7873 TempDestData, DestData, SourceData: PByte;
7875 result := inherited FlipVert;
7876 if Assigned(Data) then begin
7878 GetMem(DestData, Height * fRowSize);
7880 TempDestData := DestData;
7881 Inc(TempDestData, Width * (Height -1) * fPixelSize);
7882 for Row := 0 to Height -1 do begin
7883 Move(SourceData^, TempDestData^, fRowSize);
7884 Dec(TempDestData, fRowSize);
7885 Inc(SourceData, fRowSize);
7887 SetDataPointer(DestData, Format); //be careful, Data could be freed by this method
7890 if Assigned(DestData) then
7897 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7898 //TglBitmap2D - ToNormalMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7899 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7901 TMatrixItem = record
7906 PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
7907 TglBitmapToNormalMapRec = Record
7909 Heights: array of Single;
7910 MatrixU : array of TMatrixItem;
7911 MatrixV : array of TMatrixItem;
7915 ONE_OVER_255 = 1 / 255;
7917 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7918 procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
7922 with FuncRec do begin
7924 Source.Data.r * LUMINANCE_WEIGHT_R +
7925 Source.Data.g * LUMINANCE_WEIGHT_G +
7926 Source.Data.b * LUMINANCE_WEIGHT_B;
7927 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255;
7931 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7932 procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
7935 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
7938 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7939 procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
7941 TVec = Array[0..2] of Single;
7948 function GetHeight(X, Y: Integer): Single;
7950 with FuncRec do begin
7951 X := Max(0, Min(Size.X -1, X));
7952 Y := Max(0, Min(Size.Y -1, Y));
7953 result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
7958 with FuncRec do begin
7959 with PglBitmapToNormalMapRec(Args)^ do begin
7961 for Idx := Low(MatrixU) to High(MatrixU) do
7962 du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
7965 for Idx := Low(MatrixU) to High(MatrixU) do
7966 dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
7968 Vec[0] := -du * Scale;
7969 Vec[1] := -dv * Scale;
7974 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
7975 if Len <> 0 then begin
7976 Vec[0] := Vec[0] * Len;
7977 Vec[1] := Vec[1] * Len;
7978 Vec[2] := Vec[2] * Len;
7982 Dest.Data.r := Trunc((Vec[0] + 1) * 127.5);
7983 Dest.Data.g := Trunc((Vec[1] + 1) * 127.5);
7984 Dest.Data.b := Trunc((Vec[2] + 1) * 127.5);
7988 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7989 procedure TglBitmap2D.ToNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
7991 Rec: TglBitmapToNormalMapRec;
7993 procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
7995 if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
7996 Matrix[Index].X := X;
7997 Matrix[Index].Y := Y;
7998 Matrix[Index].W := W;
8003 if TFormatDescriptor.Get(Format).IsCompressed then
8004 raise EglBitmapUnsupportedFormat.Create(Format);
8006 if aScale > 100 then
8008 else if aScale < -100 then
8011 Rec.Scale := aScale;
8013 SetLength(Rec.Heights, Width * Height);
8017 SetLength(Rec.MatrixU, 2);
8018 SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
8019 SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
8021 SetLength(Rec.MatrixV, 2);
8022 SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
8023 SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
8027 SetLength(Rec.MatrixU, 6);
8028 SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
8029 SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
8030 SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
8031 SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
8032 SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
8033 SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
8035 SetLength(Rec.MatrixV, 6);
8036 SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
8037 SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
8038 SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
8039 SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
8040 SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
8041 SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
8045 SetLength(Rec.MatrixU, 6);
8046 SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
8047 SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
8048 SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
8049 SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
8050 SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
8051 SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
8053 SetLength(Rec.MatrixV, 6);
8054 SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
8055 SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
8056 SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
8057 SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
8058 SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
8059 SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
8063 SetLength(Rec.MatrixU, 20);
8064 SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
8065 SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
8066 SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
8067 SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
8068 SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
8069 SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
8070 SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
8071 SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
8072 SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
8073 SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
8074 SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
8075 SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
8076 SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
8077 SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
8078 SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
8079 SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
8080 SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
8081 SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
8082 SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
8083 SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
8085 SetLength(Rec.MatrixV, 20);
8086 SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
8087 SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
8088 SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
8089 SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
8090 SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
8091 SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
8092 SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
8093 SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
8094 SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
8095 SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
8096 SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
8097 SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
8098 SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
8099 SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
8100 SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
8101 SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
8102 SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
8103 SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
8104 SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
8105 SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
8110 if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
8111 AddFunc(glBitmapToNormalMapPrepareAlphaFunc, false, @Rec)
8113 AddFunc(glBitmapToNormalMapPrepareFunc, false, @Rec);
8114 AddFunc(glBitmapToNormalMapFunc, false, @Rec);
8116 SetLength(Rec.Heights, 0);
8120 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8121 //TglBitmapCubeMap////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8122 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8123 procedure TglBitmapCubeMap.GenTexture(const aTestTextureSize: Boolean);
8125 Assert(false, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
8128 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8129 procedure TglBitmapCubeMap.AfterConstruction;
8133 if not (GL_VERSION_1_3 or GL_ARB_texture_cube_map or GL_EXT_texture_cube_map) then
8134 raise EglBitmap.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
8137 Target := GL_TEXTURE_CUBE_MAP;
8138 fGenMode := GL_REFLECTION_MAP;
8141 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8142 procedure TglBitmapCubeMap.GenerateCubeMap(const aCubeTarget: Cardinal; const aTestTextureSize: Boolean);
8144 BuildWithGlu: Boolean;
8147 if (aTestTextureSize) then begin
8148 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @TexSize);
8150 if (Height > TexSize) or (Width > TexSize) then
8151 raise EglBitmapSizeToLarge.Create('TglBitmapCubeMap.GenTexture - The size for the Cubemap is to large. It''s may be not conform with the Hardware.');
8153 if not ((IsPowerOfTwo(Height) and IsPowerOfTwo(Width)) or GL_VERSION_2_0 or GL_ARB_texture_non_power_of_two) then
8154 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenTexture - Cubemaps dosn''t support non power of two texture.');
8159 SetupParameters(BuildWithGlu);
8160 UploadData(aCubeTarget, BuildWithGlu);
8163 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8164 procedure TglBitmapCubeMap.Bind(const aEnableTexCoordsGen: Boolean; const aEnableTextureUnit: Boolean);
8166 inherited Bind (aEnableTextureUnit);
8167 if aEnableTexCoordsGen then begin
8168 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, fGenMode);
8169 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, fGenMode);
8170 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, fGenMode);
8171 glEnable(GL_TEXTURE_GEN_S);
8172 glEnable(GL_TEXTURE_GEN_T);
8173 glEnable(GL_TEXTURE_GEN_R);
8177 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8178 procedure TglBitmapCubeMap.Unbind(const aDisableTexCoordsGen: Boolean; const aDisableTextureUnit: Boolean);
8180 inherited Unbind(aDisableTextureUnit);
8181 if aDisableTexCoordsGen then begin
8182 glDisable(GL_TEXTURE_GEN_S);
8183 glDisable(GL_TEXTURE_GEN_T);
8184 glDisable(GL_TEXTURE_GEN_R);
8188 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8189 //TglBitmapNormalMap//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8190 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8192 TVec = Array[0..2] of Single;
8193 TglBitmapNormalMapGetVectorFunc = procedure (out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8195 PglBitmapNormalMapRec = ^TglBitmapNormalMapRec;
8196 TglBitmapNormalMapRec = record
8198 Func: TglBitmapNormalMapGetVectorFunc;
8201 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8202 procedure glBitmapNormalMapPosX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8204 aVec[0] := aHalfSize;
8205 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8206 aVec[2] := - (aPosition.X + 0.5 - aHalfSize);
8209 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8210 procedure glBitmapNormalMapNegX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8212 aVec[0] := - aHalfSize;
8213 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8214 aVec[2] := aPosition.X + 0.5 - aHalfSize;
8217 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8218 procedure glBitmapNormalMapPosY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8220 aVec[0] := aPosition.X + 0.5 - aHalfSize;
8221 aVec[1] := aHalfSize;
8222 aVec[2] := aPosition.Y + 0.5 - aHalfSize;
8225 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8226 procedure glBitmapNormalMapNegY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8228 aVec[0] := aPosition.X + 0.5 - aHalfSize;
8229 aVec[1] := - aHalfSize;
8230 aVec[2] := - (aPosition.Y + 0.5 - aHalfSize);
8233 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8234 procedure glBitmapNormalMapPosZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8236 aVec[0] := aPosition.X + 0.5 - aHalfSize;
8237 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8238 aVec[2] := aHalfSize;
8241 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8242 procedure glBitmapNormalMapNegZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8244 aVec[0] := - (aPosition.X + 0.5 - aHalfSize);
8245 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8246 aVec[2] := - aHalfSize;
8249 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8250 procedure glBitmapNormalMapFunc(var FuncRec: TglBitmapFunctionRec);
8256 with FuncRec do begin
8257 with PglBitmapNormalMapRec(Args)^ do begin
8258 Func(Vec, Position, HalfSize);
8261 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
8262 if Len <> 0 then begin
8263 Vec[0] := Vec[0] * Len;
8264 Vec[1] := Vec[1] * Len;
8265 Vec[2] := Vec[2] * Len;
8268 // Scale Vector and AddVectro
8269 Vec[0] := Vec[0] * 0.5 + 0.5;
8270 Vec[1] := Vec[1] * 0.5 + 0.5;
8271 Vec[2] := Vec[2] * 0.5 + 0.5;
8276 Dest.Data.arr[i] := Round(Vec[i] * 255);
8280 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8281 procedure TglBitmapNormalMap.AfterConstruction;
8284 fGenMode := GL_NORMAL_MAP;
8287 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8288 procedure TglBitmapNormalMap.GenerateNormalMap(const aSize: Integer; const aTestTextureSize: Boolean);
8290 Rec: TglBitmapNormalMapRec;
8291 SizeRec: TglBitmapPixelPosition;
8293 Rec.HalfSize := aSize div 2;
8294 FreeDataAfterGenTexture := false;
8296 SizeRec.Fields := [ffX, ffY];
8301 Rec.Func := glBitmapNormalMapPosX;
8302 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8, @Rec);
8303 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X, aTestTextureSize);
8306 Rec.Func := glBitmapNormalMapNegX;
8307 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8, @Rec);
8308 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, aTestTextureSize);
8311 Rec.Func := glBitmapNormalMapPosY;
8312 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8, @Rec);
8313 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, aTestTextureSize);
8316 Rec.Func := glBitmapNormalMapNegY;
8317 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8, @Rec);
8318 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, aTestTextureSize);
8321 Rec.Func := glBitmapNormalMapPosZ;
8322 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8, @Rec);
8323 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, aTestTextureSize);
8326 Rec.Func := glBitmapNormalMapNegZ;
8327 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8, @Rec);
8328 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, aTestTextureSize);
8333 glBitmapSetDefaultFormat (tfEmpty);
8334 glBitmapSetDefaultMipmap (mmMipmap);
8335 glBitmapSetDefaultFilter (GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
8336 glBitmapSetDefaultWrap (GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
8337 glBitmapSetDefaultSwizzle(GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA);
8339 glBitmapSetDefaultFreeDataAfterGenTexture(true);
8340 glBitmapSetDefaultDeleteTextureOnFree (true);
8342 TFormatDescriptor.Init;
8344 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
8345 OpenGLInitialized := false;
8346 InitOpenGLCS := TCriticalSection.Create;
8350 TFormatDescriptor.Finalize;
8352 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
8353 FreeAndNil(InitOpenGLCS);