1 {***********************************************************
2 glBitmap by Steffen Xonna aka Lossy eX (2003-2008)
3 http://www.opengl24.de/index.php?cat=header&file=glbitmap
5 modified by Delphi OpenGL Community (http://delphigl.com/) (2013)
7 ------------------------------------------------------------
8 The contents of this file are used with permission, subject to
9 the Mozilla Public License Version 1.1 (the "License"); you may
10 not use this file except in compliance with the License. You may
11 obtain a copy of the License at
12 http://www.mozilla.org/MPL/MPL-1.1.html
13 ------------------------------------------------------------
15 ------------------------------------------------------------
18 - refactoring of the complete library
20 - The define GLB_DELPHI dosn't check versions anymore. If you say you are using delphi
21 then it's your problem if that isn't true. This prevents the unit for incompatibility
22 with newer versions of Delphi.
23 - Problems with D2009+ resolved (Thanks noeska and all i forgot)
24 - GetPixel isn't set if you are loading textures inside the constructor (Thanks Wilson)
26 - AddAlphaFromglBitmap used the custom pointer instead the imagedatapointer (Thanks Wilson)
27 - Additional Datapointer for functioninterface now has the name CustomData
29 - AssigneAlphaToBitmap overwrites his own palette (Thanks Wilson)
30 - If you load an texture from an file the property Filename will be set to the name of the file
31 - Three new properties to attach custom data to the Texture objects
32 - CustomName (free for use string)
33 - CustomNameW (free for use widestring)
34 - CustomDataPointer (free for use pointer to attach other objects or complex structures)
36 - RLE TGAs loaded much faster
38 - fixed some problem with reading RLE TGAs.
40 - function clone now only copys data if it's assigned and now it also copies the ID
41 - it seems that lazarus dont like comments in comments.
43 - It's possible to set the id of the texture
44 - define GLB_NO_NATIVE_GL deactivated by default
46 - Now supports the following libraries
50 - Linux compatibillity via free pascal compatibility (delphi sources optional)
51 - BMPs now loaded manuel
53 - Property DataPtr now has the name Data
54 - Functions are more flexible between RGB(A) and BGR(A). RGB can be saved as Bitmap and will be saved as BGR
55 - Unused Depth removed
56 - Function FreeData to freeing image data added
58 - ImageID flag of TGAs was ignored. (Thanks Zwoetzen)
60 - Function SetBorderColor implemented (only used by opengl if wrap is set to GL_CLAMP_TO_BORDER)
61 - Function AddAlphaFromValue implemented to use an fixed Value as Alphachannel
62 - Function ReadOpenGLExtension is now only intern
64 - pngimage now disabled by default like all other versions.
66 - Setting up an anisotropic filter of 0 isnt allowed by nvidia (Thanks Ogridi)
68 - Fixed some Problem with Delphi 5
69 - Now uses the newest version of pngimage. Makes saving pngs much easier.
71 - Property IsCompressed and Size removed. Not really supported by Spec (Thanks Ogridi)
73 - Internal Format ifDepth8 added
74 - function GrabScreen now supports all uncompressed formats
76 - AddAlphaFromglBitmap implemented
78 - LoadFromResource and LoadFromResourceId now needs an Instance and an ResourceType (for ID)
80 - Width, Height and Depth internal changed to TglBitmapPixelPosition.
81 property Width, Height, Depth are still existing and new property Dimension are avail
83 - Added native OpenGL Support. Breaking the dglOpenGL "barrier".
85 - Added function GrabScreen to class TglBitmap2D
87 - Added support to Save images
88 - Added function Clone to Clone Instance
90 - Functions now works with Cardinals for each channel. Up to 32 Bits per channel.
92 - Several speed optimizations
94 - Internal structure change. Loading of TGA, PNG and DDS improved.
95 Data, format and size will now set directly with SetDataPtr.
96 - AddFunc now works with all Types of Images and Formats
97 - Some Funtions moved to Baseclass TglBitmap
99 - Added Support to decompress DXT3 and DXT5 compressed Images.
100 - Added Mapping to convert data from one format into an other.
102 - Added method ConvertTo in Class TglBitmap2D. Method allows to convert every
103 supported Input format (supported by GetPixel) into any uncompresed Format
104 - Added Support to decompress DXT1 compressed Images.
105 - SwapColors replaced by ConvertTo
107 - Added Support for compressed DDSs
108 - Added new internal formats (DXT1, DXT3, DXT5)
110 - Parameter Components renamed to InternalFormat
112 - Some AllocMem replaced with GetMem (little speed change)
113 - better exception handling. Better protection from memory leaks.
115 - Added support for Direct Draw Surfaces (.DDS) (uncompressed images only)
116 - Added new internal formats (RGB8, RGBA8, RGBA4, RGB5A1, RGB10A2, R5G6B5)
118 - Added support for Grayscale textures
119 - Added internal formats (Alpha, Luminance, LuminanceAlpha, BGR8, BGRA8)
121 - Added support for GL_VERSION_2_0
122 - Added support for GL_EXT_texture_filter_anisotropic
124 - Function FillWithColor fills the Image with one Color
125 - Function LoadNormalMap added
127 - ToNormalMap allows to Create an NormalMap from the Alphachannel
128 - ToNormalMap now supports Sobel (nmSobel) function.
130 - support for RLE Compressed RGB TGAs added
132 - Class TglBitmapNormalMap added to support Normalmap generation
133 - Added function ToNormalMap in class TglBitmap2D to genereate normal maps from textures.
134 3 Filters are supported. (4 Samples, 3x3 and 5x5)
136 - Method LoadCubeMapClass removed
137 - LoadCubeMap returnvalue is now the Texture paramter. Such as LoadTextures
138 - virtual abstract method GenTexture in class TglBitmap now is protected
140 - now support DescriptionFlag in LoadTga. Allows vertical flipped images to be loaded as normal
142 - little enhancement for IsPowerOfTwo
143 - TglBitmap1D.GenTexture now tests NPOT Textures
145 - some little name changes. All properties or function with Texture in name are
146 now without texture in name. We have allways texture so we dosn't name it.
148 - GenTexture now tests if texture is NPOT and NPOT-Texture are supported or
149 TextureTarget is GL_TEXTURE_RECTANGLE. Else it raised an exception.
151 - added support for GL_ARB_texture_rectangle, GL_EXT_texture_rectangle and GL_NV_texture_rectangle
153 - Function Unbind added
154 - call of SetFilter or SetTextureWrap if TextureID exists results in setting properties to opengl texture.
156 - class TglBitmapCubeMap added (allows to Create Cubemaps)
158 - Added Support for PNG Images. (http://pngdelphi.sourceforge.net/)
159 To Enable png's use the define pngimage
161 - New Functioninterface added
162 - Function GetPixel added
164 - Property BuildMipMaps renamed to MipMap
166 - property Name removed.
167 - BuildMipMaps is now a set of 3 values. None, GluBuildMipmaps and SGIS_generate_mipmap
169 - property name added. Only used in glForms!
171 - property FreeDataAfterGenTexture is now available as default (default = true)
172 - BuildMipmaps now implemented in TglBitmap1D (i've forgotten it)
173 - function MoveMemory replaced with function Move (little speed change)
174 - several calculations stored in variables (little speed change)
176 - property BuildMipsMaps added (default = true)
177 if BuildMipMaps isn't set GenTextures uses glTexImage[12]D else it use gluBuild[12]dMipmaps
178 - property FreeDataAfterGenTexture added (default = true)
179 if FreeDataAfterGenTexture is set the texturedata were deleted after the texture was generated.
180 - parameter DisableOtherTextureUnits of Bind removed
181 - parameter FreeDataAfterGeneration of GenTextures removed
183 - TglBitmap dosn't delete data if class was destroyed (fixed)
185 - Bind now enables TextureUnits (by params)
186 - GenTextures can leave data (by param)
187 - LoadTextures now optimal
189 - Performance optimization in AddFunc
190 - procedure Bind moved to subclasses
191 - Added new Class TglBitmap1D to support real OpenGL 1D Textures
193 - Texturefilter and texturewrap now also as defaults
194 Minfilter = GL_LINEAR_MIPMAP_LINEAR
195 Magfilter = GL_LINEAR
196 Wrap(str) = GL_CLAMP_TO_EDGE
197 - Added new format tfCompressed to create a compressed texture.
198 - propertys IsCompressed, TextureSize and IsResident added
199 IsCompressed and TextureSize only contains data from level 0
201 - Added function AddFunc to add PerPixelEffects to Image
202 - LoadFromFunc now based on AddFunc
203 - Invert now based on AddFunc
204 - SwapColors now based on AddFunc
206 - Added function FlipHorz
208 - Added function LaodFromFunc to create images with function
209 - Added function FlipVert
210 - Added internal format RGB(A) if GL_EXT_bgra or OpenGL 1.2 isn't supported
212 - Added Alphafunctions to calculate alpha per function
213 - Added Alpha from ColorKey using alphafunctions
215 - First full functionally Version of glBitmap
216 - Support for 24Bit and 32Bit TGA Pictures added
218 - begin of programming
219 ***********************************************************}
222 // Please uncomment the defines below to configure the glBitmap to your preferences.
223 // If you have configured the unit you can uncomment the warning above.
224 {$MESSAGE error 'Hey. I''m the glBitmap.pas and i need to be configured. My master tell me your preferences! ;)'}
226 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
227 // Preferences ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
228 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
229 // activate to enable build-in OpenGL support with statically linked methods
230 // use dglOpenGL.pas if not enabled
231 {.$DEFINE GLB_NATIVE_OGL_STATIC}
233 // activate to enable build-in OpenGL support with dynamically linked methods
234 // use dglOpenGL.pas if not enabled
235 {.$DEFINE GLB_NATIVE_OGL_DYNAMIC}
238 // activate to enable the support for SDL_surfaces
241 // activate to enable the support for Delphi (including support for Delphi's (not Lazarus') TBitmap)
242 {.$DEFINE GLB_DELPHI}
244 // activate to enable the support for TLazIntfImage from Lazarus
245 {.$DEFINE GLB_LAZARUS}
249 // activate to enable the support of SDL_image to load files. (READ ONLY)
250 // If you enable SDL_image all other libraries will be ignored!
251 {.$DEFINE GLB_SDL_IMAGE}
255 // activate to enable Lazarus TPortableNetworkGraphic support
256 // if you enable this pngImage and libPNG will be ignored
257 {.$DEFINE GLB_LAZ_PNG}
259 // activate to enable png support with the unit pngimage -> http://pngdelphi.sourceforge.net/
260 // if you enable pngimage the libPNG will be ignored
261 {.$DEFINE GLB_PNGIMAGE}
263 // activate to use the libPNG -> http://www.libpng.org/
264 // You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libpng
265 {.$DEFINE GLB_LIB_PNG}
269 // activate to enable Lazarus TJPEGImage support
270 // if you enable this delphi jpegs and libJPEG will be ignored
271 {.$DEFINE GLB_LAZ_JPEG}
273 // if you enable delphi jpegs the libJPEG will be ignored
274 {.$DEFINE GLB_DELPHI_JPEG}
276 // activate to use the libJPEG -> http://www.ijg.org/
277 // You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libjpeg
278 {.$DEFINE GLB_LIB_JPEG}
281 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
282 // PRIVATE: do not change anything! //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
283 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
299 {$IF DEFINED(WIN32) or DEFINED(WIN64) or DEFINED(WINDOWS)}
301 {$ELSEIF DEFINED(LINUX)}
305 // native OpenGL Support
306 {$IF DEFINED(GLB_NATIVE_OGL_STATIC) OR DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
307 {$DEFINE GLB_NATIVE_OGL}
310 // checking define combinations
312 {$IFDEF GLB_SDL_IMAGE}
314 {$MESSAGE warn 'SDL_image won''t work without SDL. SDL will be activated.'}
319 {$MESSAGE warn 'The Lazarus TPortableNetworkGraphics will be ignored because you are using SDL_image.'}
323 {$IFDEF GLB_PNGIMAGE}
324 {$MESSAGE warn 'The unit pngimage will be ignored because you are using SDL_image.'}
325 {$undef GLB_PNGIMAGE}
328 {$IFDEF GLB_LAZ_JPEG}
329 {$MESSAGE warn 'The Lazarus TJPEGImage will be ignored because you are using SDL_image.'}
330 {$undef GLB_LAZ_JPEG}
333 {$IFDEF GLB_DELPHI_JPEG}
334 {$MESSAGE warn 'The unit JPEG will be ignored because you are using SDL_image.'}
335 {$undef GLB_DELPHI_JPEG}
339 {$MESSAGE warn 'The library libPNG will be ignored because you are using SDL_image.'}
343 {$IFDEF GLB_LIB_JPEG}
344 {$MESSAGE warn 'The library libJPEG will be ignored because you are using SDL_image.'}
345 {$undef GLB_LIB_JPEG}
348 {$DEFINE GLB_SUPPORT_PNG_READ}
349 {$DEFINE GLB_SUPPORT_JPEG_READ}
352 // Lazarus TPortableNetworkGraphic
354 {$IFNDEF GLB_LAZARUS}
355 {$MESSAGE warn 'Lazarus TPortableNetworkGraphic won''t work without Lazarus. Lazarus will be activated.'}
356 {$DEFINE GLB_LAZARUS}
359 {$IFDEF GLB_PNGIMAGE}
360 {$MESSAGE warn 'The pngimage will be ignored if you are using Lazarus TPortableNetworkGraphic.'}
361 {$undef GLB_PNGIMAGE}
365 {$MESSAGE warn 'The library libPNG will be ignored if you are using Lazarus TPortableNetworkGraphic.'}
369 {$DEFINE GLB_SUPPORT_PNG_READ}
370 {$DEFINE GLB_SUPPORT_PNG_WRITE}
374 {$IFDEF GLB_PNGIMAGE}
376 {$MESSAGE warn 'The library libPNG will be ignored if you are using pngimage.'}
380 {$DEFINE GLB_SUPPORT_PNG_READ}
381 {$DEFINE GLB_SUPPORT_PNG_WRITE}
386 {$DEFINE GLB_SUPPORT_PNG_READ}
387 {$DEFINE GLB_SUPPORT_PNG_WRITE}
390 // Lazarus TJPEGImage
391 {$IFDEF GLB_LAZ_JPEG}
392 {$IFNDEF GLB_LAZARUS}
393 {$MESSAGE warn 'Lazarus TJPEGImage won''t work without Lazarus. Lazarus will be activated.'}
394 {$DEFINE GLB_LAZARUS}
397 {$IFDEF GLB_DELPHI_JPEG}
398 {$MESSAGE warn 'The Delphi JPEGImage will be ignored if you are using the Lazarus TJPEGImage.'}
399 {$undef GLB_DELPHI_JPEG}
402 {$IFDEF GLB_LIB_JPEG}
403 {$MESSAGE warn 'The library libJPEG will be ignored if you are using the Lazarus TJPEGImage.'}
404 {$undef GLB_LIB_JPEG}
407 {$DEFINE GLB_SUPPORT_JPEG_READ}
408 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
412 {$IFDEF GLB_DELPHI_JPEG}
413 {$IFDEF GLB_LIB_JPEG}
414 {$MESSAGE warn 'The library libJPEG will be ignored if you are using the unit JPEG.'}
415 {$undef GLB_LIB_JPEG}
418 {$DEFINE GLB_SUPPORT_JPEG_READ}
419 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
423 {$IFDEF GLB_LIB_JPEG}
424 {$DEFINE GLB_SUPPORT_JPEG_READ}
425 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
429 {$IF DEFINED(GLB_NATIVE_OGL_STATIC) AND DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
430 {$MESSAGE warn 'GLB_NATIVE_OGL_STATIC will be ignored because you enabled GLB_NATIVE_OGL_DYNAMIC'}
444 {$IFNDEF GLB_NATIVE_OGL} dglOpenGL, {$ENDIF}
445 {$IF DEFINED(GLB_WIN) AND
446 (DEFINED(GLB_NATIVE_OGL) OR
447 DEFINED(GLB_DELPHI))} windows, {$IFEND}
449 {$IFDEF GLB_SDL} SDL, {$ENDIF}
450 {$IFDEF GLB_LAZARUS} IntfGraphics, GraphType, Graphics, {$ENDIF}
451 {$IFDEF GLB_DELPHI} Dialogs, Graphics, Types, {$ENDIF}
453 {$IFDEF GLB_SDL_IMAGE} SDL_image, {$ENDIF}
454 {$IFDEF GLB_PNGIMAGE} pngimage, {$ENDIF}
455 {$IFDEF GLB_LIB_PNG} libPNG, {$ENDIF}
456 {$IFDEF GLB_DELPHI_JPEG} JPEG, {$ENDIF}
457 {$IFDEF GLB_LIB_JPEG} libJPEG, {$ENDIF}
461 {$IFDEF GLB_NATIVE_OGL}
470 GL_EXTENSIONS = $1F03;
472 GL_TEXTURE_1D = $0DE0;
473 GL_TEXTURE_2D = $0DE1;
474 GL_TEXTURE_RECTANGLE = $84F5;
476 GL_NORMAL_MAP = $8511;
477 GL_TEXTURE_CUBE_MAP = $8513;
478 GL_REFLECTION_MAP = $8512;
479 GL_TEXTURE_CUBE_MAP_POSITIVE_X = $8515;
480 GL_TEXTURE_CUBE_MAP_NEGATIVE_X = $8516;
481 GL_TEXTURE_CUBE_MAP_POSITIVE_Y = $8517;
482 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = $8518;
483 GL_TEXTURE_CUBE_MAP_POSITIVE_Z = $8519;
484 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = $851A;
486 GL_TEXTURE_WIDTH = $1000;
487 GL_TEXTURE_HEIGHT = $1001;
488 GL_TEXTURE_INTERNAL_FORMAT = $1003;
489 GL_TEXTURE_SWIZZLE_RGBA = $8E46;
496 GL_TEXTURE_GEN_S = $0C60;
497 GL_TEXTURE_GEN_T = $0C61;
498 GL_TEXTURE_GEN_R = $0C62;
499 GL_TEXTURE_GEN_Q = $0C63;
511 GL_LUMINANCE = $1909;
512 GL_LUMINANCE4 = $803F;
513 GL_LUMINANCE8 = $8040;
514 GL_LUMINANCE12 = $8041;
515 GL_LUMINANCE16 = $8042;
517 GL_LUMINANCE_ALPHA = $190A;
518 GL_LUMINANCE4_ALPHA4 = $8043;
519 GL_LUMINANCE6_ALPHA2 = $8044;
520 GL_LUMINANCE8_ALPHA8 = $8045;
521 GL_LUMINANCE12_ALPHA4 = $8046;
522 GL_LUMINANCE12_ALPHA12 = $8047;
523 GL_LUMINANCE16_ALPHA16 = $8048;
546 GL_DEPTH_COMPONENT = $1902;
547 GL_DEPTH_COMPONENT16 = $81A5;
548 GL_DEPTH_COMPONENT24 = $81A6;
549 GL_DEPTH_COMPONENT32 = $81A7;
551 GL_COMPRESSED_RGB = $84ED;
552 GL_COMPRESSED_RGBA = $84EE;
553 GL_COMPRESSED_RGB_S3TC_DXT1_EXT = $83F0;
554 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = $83F1;
555 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = $83F2;
556 GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = $83F3;
558 GL_UNSIGNED_BYTE = $1401;
559 GL_UNSIGNED_BYTE_3_3_2 = $8032;
560 GL_UNSIGNED_BYTE_2_3_3_REV = $8362;
562 GL_UNSIGNED_SHORT = $1403;
563 GL_UNSIGNED_SHORT_5_6_5 = $8363;
564 GL_UNSIGNED_SHORT_4_4_4_4 = $8033;
565 GL_UNSIGNED_SHORT_5_5_5_1 = $8034;
566 GL_UNSIGNED_SHORT_5_6_5_REV = $8364;
567 GL_UNSIGNED_SHORT_4_4_4_4_REV = $8365;
568 GL_UNSIGNED_SHORT_1_5_5_5_REV = $8366;
570 GL_UNSIGNED_INT = $1405;
571 GL_UNSIGNED_INT_8_8_8_8 = $8035;
572 GL_UNSIGNED_INT_10_10_10_2 = $8036;
573 GL_UNSIGNED_INT_8_8_8_8_REV = $8367;
574 GL_UNSIGNED_INT_2_10_10_10_REV = $8368;
577 GL_TEXTURE_MAG_FILTER = $2800;
578 GL_TEXTURE_MIN_FILTER = $2801;
580 GL_NEAREST_MIPMAP_NEAREST = $2700;
581 GL_NEAREST_MIPMAP_LINEAR = $2702;
583 GL_LINEAR_MIPMAP_NEAREST = $2701;
584 GL_LINEAR_MIPMAP_LINEAR = $2703;
587 GL_TEXTURE_WRAP_S = $2802;
588 GL_TEXTURE_WRAP_T = $2803;
589 GL_TEXTURE_WRAP_R = $8072;
592 GL_CLAMP_TO_EDGE = $812F;
593 GL_CLAMP_TO_BORDER = $812D;
594 GL_MIRRORED_REPEAT = $8370;
597 GL_GENERATE_MIPMAP = $8191;
598 GL_TEXTURE_BORDER_COLOR = $1004;
599 GL_MAX_TEXTURE_SIZE = $0D33;
600 GL_PACK_ALIGNMENT = $0D05;
601 GL_UNPACK_ALIGNMENT = $0CF5;
603 GL_TEXTURE_MAX_ANISOTROPY_EXT = $84FE;
604 GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = $84FF;
605 GL_MAX_CUBE_MAP_TEXTURE_SIZE = $851C;
606 GL_TEXTURE_GEN_MODE = $2500;
608 {$IF DEFINED(GLB_WIN)}
609 libglu = 'glu32.dll';
610 libopengl = 'opengl32.dll';
611 {$ELSEIF DEFINED(GLB_LINUX)}
612 libglu = 'libGLU.so.1';
613 libopengl = 'libGL.so.1';
617 GLboolean = BYTEBOOL;
625 PGLboolean = ^GLboolean;
630 TglCompressedTexImage1D = procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
631 TglCompressedTexImage2D = procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
632 TglGetCompressedTexImage = procedure(target: GLenum; level: GLint; img: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
634 {$IF DEFINED(GLB_WIN)}
635 TwglGetProcAddress = function (ProcName: PAnsiChar): Pointer; stdcall;
636 {$ELSEIF DEFINED(GLB_LINUX)}
637 TglXGetProcAddress = function(ProcName: PAnsiChar): Pointer; cdecl;
638 TglXGetProcAddressARB = function(const name: PAnsiChar): pointer; cdecl;
641 {$IF DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
642 TglEnable = procedure(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
643 TglDisable = procedure(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
645 TglGetString = function(name: GLenum): PAnsiChar; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
646 TglGetIntegerv = procedure(pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
648 TglTexParameteri = procedure(target: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
649 TglTexParameteriv = procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
650 TglTexParameterfv = procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
651 TglGetTexParameteriv = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
652 TglGetTexParameterfv = procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
653 TglGetTexLevelParameteriv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
654 TglGetTexLevelParameterfv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
656 TglTexGeni = procedure(coord: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
657 TglGenTextures = procedure(n: GLsizei; textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
658 TglBindTexture = procedure(target: GLenum; texture: GLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
659 TglDeleteTextures = procedure(n: GLsizei; const textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
661 TglAreTexturesResident = function(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
662 TglReadPixels = procedure(x: GLint; y: GLint; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
663 TglPixelStorei = procedure(pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
665 TglTexImage1D = procedure(target: GLenum; level: GLint; internalformat: GLint; width: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
666 TglTexImage2D = procedure(target: GLenum; level: GLint; internalformat: GLint; width: GLsizei; height: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
667 TglGetTexImage = procedure(target: GLenum; level: GLint; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
669 TgluBuild1DMipmaps = function(target: GLEnum; components, width: GLint; format, atype: GLEnum; const data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
670 TgluBuild2DMipmaps = function(target: GLEnum; components, width, height: GLint; format, atype: GLEnum; const Data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
672 {$ELSEIF DEFINED(GLB_NATIVE_OGL_STATIC)}
673 procedure glEnable(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
674 procedure glDisable(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
676 function glGetString(name: GLenum): PAnsiChar; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
677 procedure glGetIntegerv(pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
679 procedure glTexParameteri(target: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
680 procedure glTexParameteriv(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
681 procedure glTexParameterfv(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
682 procedure glGetTexParameteriv(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
683 procedure glGetTexParameterfv(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
684 procedure glGetTexLevelParameteriv(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
685 procedure glGetTexLevelParameterfv(target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
687 procedure glTexGeni(coord: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
688 procedure glGenTextures(n: GLsizei; textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
689 procedure glBindTexture(target: GLenum; texture: GLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
690 procedure glDeleteTextures(n: GLsizei; const textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
692 function glAreTexturesResident(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
693 procedure glReadPixels(x: GLint; y: GLint; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
694 procedure glPixelStorei(pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
696 procedure glTexImage1D(target: GLenum; level: GLint; internalformat: GLint; width: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
697 procedure glTexImage2D(target: GLenum; level: GLint; internalformat: GLint; width: GLsizei; height: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
698 procedure glGetTexImage(target: GLenum; level: GLint; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
700 function gluBuild1DMipmaps(target: GLEnum; components, width: GLint; format, atype: GLEnum; const data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libglu;
701 function gluBuild2DMipmaps(target: GLEnum; components, width, height: GLint; format, atype: GLEnum; const Data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libglu;
711 GL_SGIS_generate_mipmap,
713 GL_ARB_texture_border_clamp,
714 GL_ARB_texture_mirrored_repeat,
715 GL_ARB_texture_rectangle,
716 GL_ARB_texture_non_power_of_two,
717 GL_ARB_texture_swizzle,
718 GL_ARB_texture_cube_map,
720 GL_IBM_texture_mirrored_repeat,
722 GL_NV_texture_rectangle,
724 GL_EXT_texture_edge_clamp,
725 GL_EXT_texture_rectangle,
726 GL_EXT_texture_swizzle,
727 GL_EXT_texture_cube_map,
728 GL_EXT_texture_filter_anisotropic: Boolean;
730 glCompressedTexImage1D: TglCompressedTexImage1D;
731 glCompressedTexImage2D: TglCompressedTexImage2D;
732 glGetCompressedTexImage: TglGetCompressedTexImage;
734 {$IF DEFINED(GLB_WIN)}
735 wglGetProcAddress: TwglGetProcAddress;
736 {$ELSEIF DEFINED(GLB_LINUX)}
737 glXGetProcAddress: TglXGetProcAddress;
738 glXGetProcAddressARB: TglXGetProcAddress;
741 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
743 glDisable: TglDisable;
745 glGetString: TglGetString;
746 glGetIntegerv: TglGetIntegerv;
748 glTexParameteri: TglTexParameteri;
749 glTexParameteriv: TglTexParameteriv;
750 glTexParameterfv: TglTexParameterfv;
751 glGetTexParameteriv: TglGetTexParameteriv;
752 glGetTexParameterfv: TglGetTexParameterfv;
753 glGetTexLevelParameteriv: TglGetTexLevelParameteriv;
754 glGetTexLevelParameterfv: TglGetTexLevelParameterfv;
756 glTexGeni: TglTexGeni;
757 glGenTextures: TglGenTextures;
758 glBindTexture: TglBindTexture;
759 glDeleteTextures: TglDeleteTextures;
761 glAreTexturesResident: TglAreTexturesResident;
762 glReadPixels: TglReadPixels;
763 glPixelStorei: TglPixelStorei;
765 glTexImage1D: TglTexImage1D;
766 glTexImage2D: TglTexImage2D;
767 glGetTexImage: TglGetTexImage;
769 gluBuild1DMipmaps: TgluBuild1DMipmaps;
770 gluBuild2DMipmaps: TgluBuild2DMipmaps;
775 ////////////////////////////////////////////////////////////////////////////////////////////////////
776 // the name of formats is composed of the following constituents:
777 // - multiple chanals:
778 // - channel (e.g. R, G, B, A or Alpha, Luminance or X (reserved)
779 // - width of the chanel in bit (4, 8, 16, ...)
780 // - data type (e.g. ub, us, ui)
781 // - number of data types
785 tfEmpty = 0, //must be smallest value!
787 tfAlpha4ub1, // 1 x unsigned byte
788 tfAlpha8ub1, // 1 x unsigned byte
789 tfAlpha16us1, // 1 x unsigned short
791 tfLuminance4ub1, // 1 x unsigned byte
792 tfLuminance8ub1, // 1 x unsigned byte
793 tfLuminance16us1, // 1 x unsigned short
795 tfLuminance4Alpha4ub2, // 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
796 tfLuminance6Alpha2ub2, // 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
797 tfLuminance8Alpha8ub2, // 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
798 tfLuminance12Alpha4us2, // 1 x unsigned short (lum), 1 x unsigned short (alpha)
799 tfLuminance16Alpha16us2, // 1 x unsigned short (lum), 1 x unsigned short (alpha)
801 tfR3G3B2ub1, // 1 x unsigned byte (3bit red, 3bit green, 2bit blue)
802 tfRGBX4us1, // 1 x unsigned short (4bit red, 4bit green, 4bit blue, 4bit reserverd)
803 tfXRGB4us1, // 1 x unsigned short (4bit reserved, 4bit red, 4bit green, 4bit blue)
804 tfR5G6B5us1, // 1 x unsigned short (5bit red, 6bit green, 5bit blue)
805 tfRGB5X1us1, // 1 x unsigned short (5bit red, 5bit green, 5bit blue, 1bit reserved)
806 tfX1RGB5us1, // 1 x unsigned short (1bit reserved, 5bit red, 5bit green, 5bit blue)
807 tfRGB8ub3, // 1 x unsigned byte (red), 1 x unsigned byte (green), 1 x unsigned byte (blue)
808 tfRGBX8ui1, // 1 x unsigned int (8bit red, 8bit green, 8bit blue, 8bit reserved)
809 tfXRGB8ui1, // 1 x unsigned int (8bit reserved, 8bit red, 8bit green, 8bit blue)
810 tfRGB10X2ui1, // 1 x unsigned int (10bit red, 10bit green, 10bit blue, 2bit reserved)
811 tfX2RGB10ui1, // 1 x unsigned int (2bit reserved, 10bit red, 10bit green, 10bit blue)
812 tfRGB16us3, // 1 x unsigned short (red), 1 x unsigned short (green), 1 x unsigned short (blue)
814 tfRGBA4us1, // 1 x unsigned short (4bit red, 4bit green, 4bit blue, 4bit alpha)
815 tfARGB4us1, // 1 x unsigned short (4bit alpha, 4bit red, 4bit green, 4bit blue)
816 tfRGB5A1us1, // 1 x unsigned short (5bit red, 5bit green, 5bit blue, 1bit alpha)
817 tfA1RGB5us1, // 1 x unsigned short (1bit alpha, 5bit red, 5bit green, 5bit blue)
818 tfRGBA8ui1, // 1 x unsigned int (8bit red, 8bit green, 8bit blue, 8 bit alpha)
819 tfARGB8ui1, // 1 x unsigned int (8 bit alpha, 8bit red, 8bit green, 8bit blue)
820 tfRGBA8ub4, // 1 x unsigned byte (red), 1 x unsigned byte (green), 1 x unsigned byte (blue), 1 x unsigned byte (alpha)
821 tfRGB10A2ui1, // 1 x unsigned int (10bit red, 10bit green, 10bit blue, 2bit alpha)
822 tfA2RGB10ui1, // 1 x unsigned int (2bit alpha, 10bit red, 10bit green, 10bit blue)
823 tfRGBA16us4, // 1 x unsigned short (red), 1 x unsigned short (green), 1 x unsigned short (blue), 1 x unsigned short (alpha)
825 tfBGRX4us1, // 1 x unsigned short (4bit blue, 4bit green, 4bit red, 4bit reserved)
826 tfXBGR4us1, // 1 x unsigned short (4bit reserved, 4bit blue, 4bit green, 4bit red)
827 tfB5G6R5us1, // 1 x unsigned short (5bit blue, 6bit green, 5bit red)
828 tfBGR5X1us1, // 1 x unsigned short (5bit blue, 5bit green, 5bit red, 1bit reserved)
829 tfX1BGR5us1, // 1 x unsigned short (1bit reserved, 5bit blue, 5bit green, 5bit red)
830 tfBGR8ub3, // 1 x unsigned byte (blue), 1 x unsigned byte (green), 1 x unsigned byte (red)
831 tfBGRX8ui1, // 1 x unsigned int (8bit blue, 8bit green, 8bit red, 8bit reserved)
832 tfXBGR8ui1, // 1 x unsigned int (8bit reserved, 8bit blue, 8bit green, 8bit red)
833 tfBGR10X2ui1, // 1 x unsigned int (10bit blue, 10bit green, 10bit red, 2bit reserved)
834 tfX2BGR10ui1, // 1 x unsigned int (2bit reserved, 10bit blue, 10bit green, 10bit red)
835 tfBGR16us3, // 1 x unsigned short (blue), 1 x unsigned short (green), 1 x unsigned short (red)
837 tfBGRA4us1, // 1 x unsigned short (4bit blue, 4bit green, 4bit red, 4bit alpha)
838 tfABGR4us1, // 1 x unsigned short (4bit alpha, 4bit blue, 4bit green, 4bit red)
839 tfBGR5A1us1, // 1 x unsigned short (5bit blue, 5bit green, 5bit red, 1bit alpha)
840 tfA1BGR5us1, // 1 x unsigned short (1bit alpha, 5bit blue, 5bit green, 5bit red)
841 tfBGRA8ui1, // 1 x unsigned int (8bit blue, 8bit green, 8bit red, 8bit alpha)
842 tfABGR8ui1, // 1 x unsigned int (8bit alpha, 8bit blue, 8bit green, 8bit red)
843 tfBGRA8ub4, // 1 x unsigned byte (blue), 1 x unsigned byte (green), 1 x unsigned byte (red), 1 x unsigned byte (alpha)
844 tfBGR10A2ui1, // 1 x unsigned int (10bit blue, 10bit green, 10bit red, 2bit alpha)
845 tfA2BGR10ui1, // 1 x unsigned int (2bit alpha, 10bit blue, 10bit green, 10bit red)
846 tfBGRA16us4, // 1 x unsigned short (blue), 1 x unsigned short (green), 1 x unsigned short (red), 1 x unsigned short (alpha)
848 tfDepth16us1, // 1 x unsigned short (depth)
849 tfDepth24ui1, // 1 x unsigned int (depth)
850 tfDepth32ui1, // 1 x unsigned int (depth)
857 TglBitmapFileType = (
858 {$IFDEF GLB_SUPPORT_PNG_WRITE} ftPNG, {$ENDIF}
859 {$IFDEF GLB_SUPPORT_JPEG_WRITE}ftJPEG, {$ENDIF}
864 TglBitmapFileTypes = set of TglBitmapFileType;
871 TglBitmapNormalMapFunc = (
877 ////////////////////////////////////////////////////////////////////////////////////////////////////
878 EglBitmap = class(Exception);
879 EglBitmapNotSupported = class(Exception);
880 EglBitmapSizeToLarge = class(EglBitmap);
881 EglBitmapNonPowerOfTwo = class(EglBitmap);
882 EglBitmapUnsupportedFormat = class(EglBitmap)
884 constructor Create(const aFormat: TglBitmapFormat); overload;
885 constructor Create(const aMsg: String; const aFormat: TglBitmapFormat); overload;
888 ////////////////////////////////////////////////////////////////////////////////////////////////////
889 TglBitmapRec4ui = packed record
891 0: (r, g, b, a: Cardinal);
892 1: (arr: array[0..3] of Cardinal);
895 TglBitmapRec4ub = packed record
897 0: (r, g, b, a: Byte);
898 1: (arr: array[0..3] of Byte);
901 TglBitmapRec4ul = packed record
903 0: (r, g, b, a: QWord);
904 1: (arr: array[0..3] of QWord);
907 TglBitmapFormatDescriptor = class(TObject)
910 fBytesPerPixel: Single;
911 fChannelCount: Integer;
912 fMask: TglBitmapRec4ul;
913 fRange: TglBitmapRec4ui;
915 function GetHasRed: Boolean;
916 function GetHasGreen: Boolean;
917 function GetHasBlue: Boolean;
918 function GetHasAlpha: Boolean;
919 function GetHasColor: Boolean;
920 function GetIsGrayscale: Boolean;
922 fFormat: TglBitmapFormat;
923 fWithAlpha: TglBitmapFormat;
924 fWithoutAlpha: TglBitmapFormat;
925 fOpenGLFormat: TglBitmapFormat;
926 fRGBInverted: TglBitmapFormat;
927 fUncompressed: TglBitmapFormat;
929 fBitsPerPixel: Integer;
930 fIsCompressed: Boolean;
932 fPrecision: TglBitmapRec4ub;
933 fShift: TglBitmapRec4ub;
936 fglInternalFormat: GLenum;
937 fglDataFormat: GLenum;
939 procedure SetValues; virtual;
940 procedure CalcValues;
942 property Format: TglBitmapFormat read fFormat;
943 property ChannelCount: Integer read fChannelCount;
944 property IsCompressed: Boolean read fIsCompressed;
945 property BitsPerPixel: Integer read fBitsPerPixel;
946 property BytesPerPixel: Single read fBytesPerPixel;
948 property Precision: TglBitmapRec4ub read fPrecision;
949 property Shift: TglBitmapRec4ub read fShift;
950 property Range: TglBitmapRec4ui read fRange;
951 property Mask: TglBitmapRec4ul read fMask;
953 property RGBInverted: TglBitmapFormat read fRGBInverted;
954 property WithAlpha: TglBitmapFormat read fWithAlpha;
955 property WithoutAlpha: TglBitmapFormat read fWithAlpha;
956 property OpenGLFormat: TglBitmapFormat read fOpenGLFormat;
957 property Uncompressed: TglBitmapFormat read fUncompressed;
959 property glFormat: GLenum read fglFormat;
960 property glInternalFormat: GLenum read fglInternalFormat;
961 property glDataFormat: GLenum read fglDataFormat;
963 property HasRed: Boolean read GetHasRed;
964 property HasGreen: Boolean read GetHasGreen;
965 property HasBlue: Boolean read GetHasBlue;
966 property HasAlpha: Boolean read GetHasAlpha;
967 property HasColor: Boolean read GetHasColor;
968 property IsGrayscale: Boolean read GetIsGrayscale;
972 class function GetByFormat(const aInternalFormat: GLenum): TglBitmapFormatDescriptor;
975 ////////////////////////////////////////////////////////////////////////////////////////////////////
976 TglBitmapPixelData = packed record
977 Data: TglBitmapRec4ui;
978 Range: TglBitmapRec4ui;
979 Format: TglBitmapFormat;
981 PglBitmapPixelData = ^TglBitmapPixelData;
983 TglBitmapPixelPositionFields = set of (ffX, ffY);
984 TglBitmapPixelPosition = record
985 Fields : TglBitmapPixelPositionFields;
990 ////////////////////////////////////////////////////////////////////////////////////////////////////
992 TglBitmapFunctionRec = record
994 Size: TglBitmapPixelPosition;
995 Position: TglBitmapPixelPosition;
996 Source: TglBitmapPixelData;
997 Dest: TglBitmapPixelData;
1000 TglBitmapFunction = procedure(var FuncRec: TglBitmapFunctionRec);
1002 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1005 function GetFormatDesc: TglBitmapFormatDescriptor;
1009 fAnisotropic: Integer;
1010 fDeleteTextureOnFree: Boolean;
1011 fFreeDataOnDestroy: Boolean;
1012 fFreeDataAfterGenTexture: Boolean;
1014 fIsResident: GLboolean;
1015 fBorderColor: array[0..3] of Single;
1017 fDimension: TglBitmapPixelPosition;
1018 fMipMap: TglBitmapMipMap;
1019 fFormat: TglBitmapFormat;
1022 fPixelSize: Integer;
1035 fSwizzle: array[0..3] of GLenum;
1039 fCustomName: String;
1040 fCustomNameW: WideString;
1041 fCustomData: Pointer;
1044 function GetWidth: Integer; virtual;
1045 function GetHeight: Integer; virtual;
1047 function GetFileWidth: Integer; virtual;
1048 function GetFileHeight: Integer; virtual;
1051 procedure SetCustomData(const aValue: Pointer);
1052 procedure SetCustomName(const aValue: String);
1053 procedure SetCustomNameW(const aValue: WideString);
1054 procedure SetFreeDataOnDestroy(const aValue: Boolean);
1055 procedure SetDeleteTextureOnFree(const aValue: Boolean);
1056 procedure SetFormat(const aValue: TglBitmapFormat);
1057 procedure SetFreeDataAfterGenTexture(const aValue: Boolean);
1058 procedure SetID(const aValue: Cardinal);
1059 procedure SetMipMap(const aValue: TglBitmapMipMap);
1060 procedure SetTarget(const aValue: Cardinal);
1061 procedure SetAnisotropic(const aValue: Integer);
1064 procedure SetupParameters(out aBuildWithGlu: Boolean);
1065 procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
1066 const aWidth: Integer = -1; const aHeight: Integer = -1); virtual; //be careful, aData could be freed by this method
1067 procedure GenTexture(const aTestTextureSize: Boolean = true); virtual; abstract;
1069 function FlipHorz: Boolean; virtual;
1070 function FlipVert: Boolean; virtual;
1072 property Width: Integer read GetWidth;
1073 property Height: Integer read GetHeight;
1075 property FileWidth: Integer read GetFileWidth;
1076 property FileHeight: Integer read GetFileHeight;
1079 property ID: Cardinal read fID write SetID;
1080 property Target: Cardinal read fTarget write SetTarget;
1081 property Format: TglBitmapFormat read fFormat write SetFormat;
1082 property MipMap: TglBitmapMipMap read fMipMap write SetMipMap;
1083 property Anisotropic: Integer read fAnisotropic write SetAnisotropic;
1085 property FormatDesc: TglBitmapFormatDescriptor read GetFormatDesc;
1087 property Filename: String read fFilename;
1088 property CustomName: String read fCustomName write SetCustomName;
1089 property CustomNameW: WideString read fCustomNameW write SetCustomNameW;
1090 property CustomData: Pointer read fCustomData write SetCustomData;
1092 property DeleteTextureOnFree: Boolean read fDeleteTextureOnFree write SetDeleteTextureOnFree;
1093 property FreeDataOnDestroy: Boolean read fFreeDataOnDestroy write SetFreeDataOnDestroy;
1094 property FreeDataAfterGenTexture: Boolean read fFreeDataAfterGenTexture write SetFreeDataAfterGenTexture;
1096 property Dimension: TglBitmapPixelPosition read fDimension;
1097 property Data: PByte read fData;
1098 property IsResident: GLboolean read fIsResident;
1100 procedure AfterConstruction; override;
1101 procedure BeforeDestruction; override;
1103 procedure PrepareResType(var aResource: String; var aResType: PChar);
1106 procedure LoadFromFile(const aFilename: String);
1107 procedure LoadFromStream(const aStream: TStream); virtual;
1108 procedure LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
1109 const aFormat: TglBitmapFormat; const aArgs: Pointer = nil);
1110 procedure LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil);
1111 procedure LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
1114 procedure SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
1115 procedure SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType); virtual;
1118 function AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer = nil): Boolean; overload;
1119 function AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
1120 const aFormat: TglBitmapFormat; const aArgs: Pointer = nil): Boolean; overload;
1124 function AssignToSurface(out aSurface: PSDL_Surface): Boolean;
1125 function AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
1126 function AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
1127 function AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil;
1128 const aArgs: Pointer = nil): Boolean;
1132 function AssignToBitmap(const aBitmap: TBitmap): Boolean;
1133 function AssignFromBitmap(const aBitmap: TBitmap): Boolean;
1134 function AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
1135 function AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction = nil;
1136 const aArgs: Pointer = nil): Boolean;
1139 {$IFDEF GLB_LAZARUS}
1140 function AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
1141 function AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
1142 function AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
1143 function AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction = nil;
1144 const aArgs: Pointer = nil): Boolean;
1147 function AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil;
1148 const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1149 function AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
1150 const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1152 function AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer = nil): Boolean; virtual;
1153 function AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1154 function AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1155 function AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1157 function AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte = 0): Boolean;
1158 function AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal = 0): Boolean;
1159 function AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single = 0): Boolean;
1161 function AddAlphaFromValue(const aAlpha: Byte): Boolean;
1162 function AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
1163 function AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
1165 function RemoveAlpha: Boolean; virtual;
1168 function Clone: TglBitmap;
1169 function ConvertTo(const aFormat: TglBitmapFormat): Boolean; virtual;
1170 procedure Invert(const aUseRGB: Boolean = true; const aUseAlpha: Boolean = false);
1171 procedure SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
1175 procedure FillWithColor(const aRed, aGreen, aBlue: Byte; const aAlpha: Byte = 255);
1176 procedure FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal = $FFFFFFFF);
1177 procedure FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha : Single = 1);
1180 procedure SetFilter(const aMin, aMag: GLenum);
1182 const S: GLenum = GL_CLAMP_TO_EDGE;
1183 const T: GLenum = GL_CLAMP_TO_EDGE;
1184 const R: GLenum = GL_CLAMP_TO_EDGE);
1185 procedure SetSwizzle(const r, g, b, a: GLenum);
1187 procedure Bind(const aEnableTextureUnit: Boolean = true); virtual;
1188 procedure Unbind(const aDisableTextureUnit: Boolean = true); virtual;
1191 constructor Create; overload;
1192 constructor Create(const aFileName: String); overload;
1193 constructor Create(const aStream: TStream); overload;
1194 constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; aData: PByte = nil); overload;
1195 constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer = nil); overload;
1196 constructor Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil); overload;
1197 constructor Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar); overload;
1199 {$IFDEF GLB_SUPPORT_PNG_READ} function LoadPNG(const aStream: TStream): Boolean; virtual; {$ENDIF}
1200 {$ifdef GLB_SUPPORT_PNG_WRITE} procedure SavePNG(const aStream: TStream); virtual; {$ENDIF}
1202 {$IFDEF GLB_SUPPORT_JPEG_READ} function LoadJPEG(const aStream: TStream): Boolean; virtual; {$ENDIF}
1203 {$IFDEF GLB_SUPPORT_JPEG_WRITE} procedure SaveJPEG(const aStream: TStream); virtual; {$ENDIF}
1205 function LoadRAW(const aStream: TStream): Boolean;
1206 procedure SaveRAW(const aStream: TStream);
1208 function LoadBMP(const aStream: TStream): Boolean;
1209 procedure SaveBMP(const aStream: TStream);
1211 function LoadTGA(const aStream: TStream): Boolean;
1212 procedure SaveTGA(const aStream: TStream);
1214 function LoadDDS(const aStream: TStream): Boolean;
1215 procedure SaveDDS(const aStream: TStream);
1218 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1219 TglBitmap1D = class(TglBitmap)
1221 procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
1222 const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
1223 procedure UploadData(const aBuildWithGlu: Boolean);
1226 procedure AfterConstruction; override;
1227 function FlipHorz: Boolean; override;
1228 procedure GenTexture(const aTestTextureSize: Boolean = true); override;
1231 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1232 TglBitmap2D = class(TglBitmap)
1234 fLines: array of PByte;
1235 function GetScanline(const aIndex: Integer): Pointer;
1236 procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
1237 const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
1238 procedure UploadData(const aTarget: GLenum; const aBuildWithGlu: Boolean);
1242 property Scanline[const aIndex: Integer]: Pointer read GetScanline;
1244 procedure AfterConstruction; override;
1246 procedure GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
1247 procedure GetDataFromTexture;
1248 procedure GenTexture(const aTestTextureSize: Boolean = true); override;
1250 function FlipHorz: Boolean; override;
1251 function FlipVert: Boolean; override;
1253 procedure ToNormalMap(const aFunc: TglBitmapNormalMapFunc = nm3x3;
1254 const aScale: Single = 2; const aUseAlpha: Boolean = false);
1257 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1258 TglBitmapCubeMap = class(TglBitmap2D)
1261 procedure GenTexture(const aTestTextureSize: Boolean = true); reintroduce;
1263 procedure AfterConstruction; override;
1264 procedure GenerateCubeMap(const aCubeTarget: Cardinal; const aTestTextureSize: Boolean = true);
1265 procedure Bind(const aEnableTexCoordsGen: Boolean = true; const aEnableTextureUnit: Boolean = true); reintroduce; virtual;
1266 procedure Unbind(const aDisableTexCoordsGen: Boolean = true; const aDisableTextureUnit: Boolean = true); reintroduce; virtual;
1269 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1270 TglBitmapNormalMap = class(TglBitmapCubeMap)
1272 procedure AfterConstruction; override;
1273 procedure GenerateNormalMap(const aSize: Integer = 32; const aTestTextureSize: Boolean = true);
1277 NULL_SIZE: TglBitmapPixelPosition = (Fields: []; X: 0; Y: 0);
1279 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
1280 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
1281 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
1282 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
1283 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
1284 procedure glBitmapSetDefaultWrap(
1285 const S: Cardinal = GL_CLAMP_TO_EDGE;
1286 const T: Cardinal = GL_CLAMP_TO_EDGE;
1287 const R: Cardinal = GL_CLAMP_TO_EDGE);
1289 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
1290 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
1291 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
1292 function glBitmapGetDefaultFormat: TglBitmapFormat;
1293 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
1294 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
1296 function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
1297 function glBitmapRec4ub(const r, g, b, a: Byte): TglBitmapRec4ub;
1298 function glBitmapRec4ui(const r, g, b, a: Cardinal): TglBitmapRec4ui;
1299 function glBitmapRec4ul(const r, g, b, a: QWord): TglBitmapRec4ul;
1300 function glBitmapRec4ubCompare(const r1, r2: TglBitmapRec4ub): Boolean;
1301 function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean;
1303 function glBitmapCreateTestTexture(const aFormat: TglBitmapFormat): TglBitmap2D;
1306 glBitmapDefaultDeleteTextureOnFree: Boolean;
1307 glBitmapDefaultFreeDataAfterGenTextures: Boolean;
1308 glBitmapDefaultFormat: TglBitmapFormat;
1309 glBitmapDefaultMipmap: TglBitmapMipMap;
1310 glBitmapDefaultFilterMin: Cardinal;
1311 glBitmapDefaultFilterMag: Cardinal;
1312 glBitmapDefaultWrapS: Cardinal;
1313 glBitmapDefaultWrapT: Cardinal;
1314 glBitmapDefaultWrapR: Cardinal;
1315 glDefaultSwizzle: array[0..3] of GLenum;
1318 function CreateGrayPalette: HPALETTE;
1324 Math, syncobjs, typinfo
1325 {$IF DEFINED(GLB_SUPPORT_JPEG_READ) AND DEFINED(GLB_LAZ_JPEG)}, FPReadJPEG{$IFEND};
1329 QWord = System.UInt64;
1336 ////////////////////////////////////////////////////////////////////////////////////////////////////
1337 TFormatDescriptor = class(TglBitmapFormatDescriptor)
1339 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); virtual; abstract;
1340 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract;
1342 function GetSize(const aSize: TglBitmapPixelPosition): Integer; overload; virtual;
1343 function GetSize(const aWidth, aHeight: Integer): Integer; overload; virtual;
1345 function CreateMappingData: Pointer; virtual;
1346 procedure FreeMappingData(var aMappingData: Pointer); virtual;
1348 function IsEmpty: Boolean; virtual;
1349 function MaskMatch(const aMask: TglBitmapRec4ul): Boolean; virtual;
1351 procedure PreparePixel(out aPixel: TglBitmapPixelData); virtual;
1353 constructor Create; virtual;
1355 class procedure Init;
1356 class function Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
1357 class function GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
1358 class function GetFromMask(const aMask: TglBitmapRec4ul; const aBitCount: Integer = 0): TFormatDescriptor;
1359 class function GetFromPrecShift(const aPrec, aShift: TglBitmapRec4ub; const aBitCount: Integer): TFormatDescriptor;
1360 class procedure Clear;
1361 class procedure Finalize;
1363 TFormatDescriptorClass = class of TFormatDescriptor;
1365 TfdEmpty = class(TFormatDescriptor);
1367 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1368 TfdAlphaUB1 = class(TFormatDescriptor) //1* unsigned byte
1369 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1370 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1373 TfdLuminanceUB1 = class(TFormatDescriptor) //1* unsigned byte
1374 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1375 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1378 TfdUniversalUB1 = class(TFormatDescriptor) //1* unsigned byte
1379 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1380 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1383 TfdLuminanceAlphaUB2 = class(TfdLuminanceUB1) //2* unsigned byte
1384 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1385 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1388 TfdRGBub3 = class(TFormatDescriptor) //3* unsigned byte
1389 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1390 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1393 TfdBGRub3 = class(TFormatDescriptor) //3* unsigned byte (inverse)
1394 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1395 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1398 TfdRGBAub4 = class(TfdRGBub3) //3* unsigned byte
1399 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1400 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1403 TfdBGRAub4 = class(TfdBGRub3) //3* unsigned byte (inverse)
1404 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1405 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1408 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1409 TfdAlphaUS1 = class(TFormatDescriptor) //1* unsigned short
1410 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1411 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1414 TfdLuminanceUS1 = class(TFormatDescriptor) //1* unsigned short
1415 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1416 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1419 TfdUniversalUS1 = class(TFormatDescriptor) //1* unsigned short
1420 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1421 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1424 TfdDepthUS1 = class(TFormatDescriptor) //1* unsigned short
1425 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1426 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1429 TfdLuminanceAlphaUS2 = class(TfdLuminanceUS1) //2* unsigned short
1430 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1431 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1434 TfdRGBus3 = class(TFormatDescriptor) //3* unsigned short
1435 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1436 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1439 TfdBGRus3 = class(TFormatDescriptor) //3* unsigned short (inverse)
1440 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1441 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1444 TfdRGBAus4 = class(TfdRGBus3) //4* unsigned short
1445 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1446 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1449 TfdARGBus4 = class(TfdRGBus3) //4* unsigned short
1450 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1451 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1454 TfdBGRAus4 = class(TfdBGRus3) //4* unsigned short (inverse)
1455 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1456 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1459 TfdABGRus4 = class(TfdBGRus3) //4* unsigned short (inverse)
1460 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1461 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1464 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1465 TfdUniversalUI1 = class(TFormatDescriptor) //1* unsigned int
1466 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1467 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1470 TfdDepthUI1 = class(TFormatDescriptor) //1* unsigned int
1471 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1472 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1475 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1476 TfdAlpha4ub1 = class(TfdAlphaUB1)
1477 procedure SetValues; override;
1480 TfdAlpha8ub1 = class(TfdAlphaUB1)
1481 procedure SetValues; override;
1484 TfdAlpha16us1 = class(TfdAlphaUS1)
1485 procedure SetValues; override;
1488 TfdLuminance4ub1 = class(TfdLuminanceUB1)
1489 procedure SetValues; override;
1492 TfdLuminance8ub1 = class(TfdLuminanceUB1)
1493 procedure SetValues; override;
1496 TfdLuminance16us1 = class(TfdLuminanceUS1)
1497 procedure SetValues; override;
1500 TfdLuminance4Alpha4ub2 = class(TfdLuminanceAlphaUB2)
1501 procedure SetValues; override;
1504 TfdLuminance6Alpha2ub2 = class(TfdLuminanceAlphaUB2)
1505 procedure SetValues; override;
1508 TfdLuminance8Alpha8ub2 = class(TfdLuminanceAlphaUB2)
1509 procedure SetValues; override;
1512 TfdLuminance12Alpha4us2 = class(TfdLuminanceAlphaUS2)
1513 procedure SetValues; override;
1516 TfdLuminance16Alpha16us2 = class(TfdLuminanceAlphaUS2)
1517 procedure SetValues; override;
1520 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1521 TfdR3G3B2ub1 = class(TfdUniversalUB1)
1522 procedure SetValues; override;
1525 TfdRGBX4us1 = class(TfdUniversalUS1)
1526 procedure SetValues; override;
1529 TfdXRGB4us1 = class(TfdUniversalUS1)
1530 procedure SetValues; override;
1533 TfdR5G6B5us1 = class(TfdUniversalUS1)
1534 procedure SetValues; override;
1537 TfdRGB5X1us1 = class(TfdUniversalUS1)
1538 procedure SetValues; override;
1541 TfdX1RGB5us1 = class(TfdUniversalUS1)
1542 procedure SetValues; override;
1545 TfdRGB8ub3 = class(TfdRGBub3)
1546 procedure SetValues; override;
1549 TfdRGBX8ui1 = class(TfdUniversalUI1)
1550 procedure SetValues; override;
1553 TfdXRGB8ui1 = class(TfdUniversalUI1)
1554 procedure SetValues; override;
1557 TfdRGB10X2ui1 = class(TfdUniversalUI1)
1558 procedure SetValues; override;
1561 TfdX2RGB10ui1 = class(TfdUniversalUI1)
1562 procedure SetValues; override;
1565 TfdRGB16us3 = class(TfdRGBus3)
1566 procedure SetValues; override;
1569 TfdRGBA4us1 = class(TfdUniversalUS1)
1570 procedure SetValues; override;
1573 TfdARGB4us1 = class(TfdUniversalUS1)
1574 procedure SetValues; override;
1577 TfdRGB5A1us1 = class(TfdUniversalUS1)
1578 procedure SetValues; override;
1581 TfdA1RGB5us1 = class(TfdUniversalUS1)
1582 procedure SetValues; override;
1585 TfdRGBA8ui1 = class(TfdUniversalUI1)
1586 procedure SetValues; override;
1589 TfdARGB8ui1 = class(TfdUniversalUI1)
1590 procedure SetValues; override;
1593 TfdRGBA8ub4 = class(TfdRGBAub4)
1594 procedure SetValues; override;
1597 TfdRGB10A2ui1 = class(TfdUniversalUI1)
1598 procedure SetValues; override;
1601 TfdA2RGB10ui1 = class(TfdUniversalUI1)
1602 procedure SetValues; override;
1605 TfdRGBA16us4 = class(TfdRGBAus4)
1606 procedure SetValues; override;
1609 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1610 TfdBGRX4us1 = class(TfdUniversalUS1)
1611 procedure SetValues; override;
1614 TfdXBGR4us1 = class(TfdUniversalUS1)
1615 procedure SetValues; override;
1618 TfdB5G6R5us1 = class(TfdUniversalUS1)
1619 procedure SetValues; override;
1622 TfdBGR5X1us1 = class(TfdUniversalUS1)
1623 procedure SetValues; override;
1626 TfdX1BGR5us1 = class(TfdUniversalUS1)
1627 procedure SetValues; override;
1630 TfdBGR8ub3 = class(TfdBGRub3)
1631 procedure SetValues; override;
1634 TfdBGRX8ui1 = class(TfdUniversalUI1)
1635 procedure SetValues; override;
1638 TfdXBGR8ui1 = class(TfdUniversalUI1)
1639 procedure SetValues; override;
1642 TfdBGR10X2ui1 = class(TfdUniversalUI1)
1643 procedure SetValues; override;
1646 TfdX2BGR10ui1 = class(TfdUniversalUI1)
1647 procedure SetValues; override;
1650 TfdBGR16us3 = class(TfdBGRus3)
1651 procedure SetValues; override;
1654 TfdBGRA4us1 = class(TfdUniversalUS1)
1655 procedure SetValues; override;
1658 TfdABGR4us1 = class(TfdUniversalUS1)
1659 procedure SetValues; override;
1662 TfdBGR5A1us1 = class(TfdUniversalUS1)
1663 procedure SetValues; override;
1666 TfdA1BGR5us1 = class(TfdUniversalUS1)
1667 procedure SetValues; override;
1670 TfdBGRA8ui1 = class(TfdUniversalUI1)
1671 procedure SetValues; override;
1674 TfdABGR8ui1 = class(TfdUniversalUI1)
1675 procedure SetValues; override;
1678 TfdBGRA8ub4 = class(TfdBGRAub4)
1679 procedure SetValues; override;
1682 TfdBGR10A2ui1 = class(TfdUniversalUI1)
1683 procedure SetValues; override;
1686 TfdA2BGR10ui1 = class(TfdUniversalUI1)
1687 procedure SetValues; override;
1690 TfdBGRA16us4 = class(TfdBGRAus4)
1691 procedure SetValues; override;
1694 TfdDepth16us1 = class(TfdDepthUS1)
1695 procedure SetValues; override;
1698 TfdDepth24ui1 = class(TfdDepthUI1)
1699 procedure SetValues; override;
1702 TfdDepth32ui1 = class(TfdDepthUI1)
1703 procedure SetValues; override;
1706 TfdS3tcDtx1RGBA = class(TFormatDescriptor)
1707 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1708 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1709 procedure SetValues; override;
1712 TfdS3tcDtx3RGBA = class(TFormatDescriptor)
1713 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1714 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1715 procedure SetValues; override;
1718 TfdS3tcDtx5RGBA = class(TFormatDescriptor)
1719 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1720 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1721 procedure SetValues; override;
1724 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1725 TbmpBitfieldFormat = class(TFormatDescriptor)
1727 procedure SetValues(const aBPP: Integer; aMask: TglBitmapRec4ul); overload;
1728 procedure SetValues(const aBBP: Integer; const aPrec, aShift: TglBitmapRec4ub); overload;
1729 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1730 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1733 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1734 TbmpColorTableEnty = packed record
1737 TbmpColorTable = array of TbmpColorTableEnty;
1738 TbmpColorTableFormat = class(TFormatDescriptor)
1740 fBitsPerPixel: Integer;
1741 fColorTable: TbmpColorTable;
1743 procedure SetValues; override; overload;
1745 property ColorTable: TbmpColorTable read fColorTable write fColorTable;
1746 property BitsPerPixel: Integer read fBitsPerPixel write fBitsPerPixel;
1748 procedure SetValues(const aFormat: TglBitmapFormat; const aBPP: Integer; const aPrec, aShift: TglBitmapRec4ub); overload;
1749 procedure CalcValues;
1750 procedure CreateColorTable;
1752 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1753 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1754 destructor Destroy; override;
1758 LUMINANCE_WEIGHT_R = 0.30;
1759 LUMINANCE_WEIGHT_G = 0.59;
1760 LUMINANCE_WEIGHT_B = 0.11;
1762 ALPHA_WEIGHT_R = 0.30;
1763 ALPHA_WEIGHT_G = 0.59;
1764 ALPHA_WEIGHT_B = 0.11;
1766 DEPTH_WEIGHT_R = 0.333333333;
1767 DEPTH_WEIGHT_G = 0.333333333;
1768 DEPTH_WEIGHT_B = 0.333333333;
1770 FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
1781 TfdLuminance4Alpha4ub2,
1782 TfdLuminance6Alpha2ub2,
1783 TfdLuminance8Alpha8ub2,
1784 TfdLuminance12Alpha4us2,
1785 TfdLuminance16Alpha16us2,
1844 FormatDescriptorCS: TCriticalSection;
1845 FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
1847 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1848 constructor EglBitmapUnsupportedFormat.Create(const aFormat: TglBitmapFormat);
1850 inherited Create('unsupported format: ' + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1853 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1854 constructor EglBitmapUnsupportedFormat.Create(const aMsg: String; const aFormat: TglBitmapFormat);
1856 inherited Create(aMsg + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1859 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1860 function glBitmapPosition(X: Integer; Y: Integer): TglBitmapPixelPosition;
1862 result.Fields := [];
1865 result.Fields := result.Fields + [ffX];
1867 result.Fields := result.Fields + [ffY];
1869 result.X := Max(0, X);
1870 result.Y := Max(0, Y);
1873 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1874 function glBitmapRec4ub(const r, g, b, a: Byte): TglBitmapRec4ub;
1882 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1883 function glBitmapRec4ui(const r, g, b, a: Cardinal): TglBitmapRec4ui;
1891 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1892 function glBitmapRec4ul(const r, g, b, a: QWord): TglBitmapRec4ul;
1900 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1901 function glBitmapRec4ubCompare(const r1, r2: TglBitmapRec4ub): Boolean;
1906 for i := 0 to high(r1.arr) do
1907 if (r1.arr[i] <> r2.arr[i]) then
1912 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1913 function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean;
1918 for i := 0 to high(r1.arr) do
1919 if (r1.arr[i] <> r2.arr[i]) then
1924 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1925 function glBitmapCreateTestTexture(const aFormat: TglBitmapFormat): TglBitmap2D;
1927 desc: TFormatDescriptor;
1931 px: TglBitmapPixelData;
1934 desc := TFormatDescriptor.Get(aFormat);
1935 if (desc.IsCompressed) or (desc.glFormat = 0) then
1938 p := GetMem(ceil(25 * desc.BytesPerPixel)); // 5 x 5 pixel
1939 md := desc.CreateMappingData;
1942 desc.PreparePixel(px);
1944 for x := 0 to 4 do begin
1945 px.Data := glBitmapRec4ui(0, 0, 0, 0);
1946 for i := 0 to 3 do begin
1947 if ((y < 3) and (y = i)) or
1948 ((y = 3) and (i < 3)) or
1949 ((y = 4) and (i = 3))
1951 px.Data.arr[i] := Trunc(px.Range.arr[i] / 4 * x)
1952 else if ((y < 4) and (i = 3)) or
1953 ((y = 4) and (i < 3))
1955 px.Data.arr[i] := px.Range.arr[i]
1957 px.Data.arr[i] := 0; //px.Range.arr[i];
1959 desc.Map(px, tmp, md);
1962 desc.FreeMappingData(md);
1965 result := TglBitmap2D.Create(glBitmapPosition(5, 5), aFormat, p);
1966 result.FreeDataOnDestroy := true;
1967 result.FreeDataAfterGenTexture := false;
1968 result.SetFilter(GL_NEAREST, GL_NEAREST);
1971 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1972 function glBitmapShiftRec(const r, g, b, a: Byte): TglBitmapRec4ub;
1980 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1981 function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
1987 tfAlpha4ub1, tfAlpha8ub1,
1988 tfLuminance4ub1, tfLuminance8ub1, tfR3G3B2ub1,
1991 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
1992 tfRGBX4us1, tfXRGB4us1, tfRGB5X1us1, tfX1RGB5us1, tfR5G6B5us1, tfRGB5A1us1, tfA1RGB5us1, tfRGBA4us1, tfARGB4us1,
1993 tfBGRX4us1, tfXBGR4us1, tfBGR5X1us1, tfX1BGR5us1, tfB5G6R5us1, tfBGR5A1us1, tfA1BGR5us1, tfBGRA4us1, tfABGR4us1,
1996 tfBGR8ub3, tfRGB8ub3,
1999 tfRGBX8ui1, tfXRGB8ui1, tfRGB10X2ui1, tfX2RGB10ui1, tfRGBA8ui1, tfARGB8ui1, tfRGBA8ub4, tfRGB10A2ui1, tfA2RGB10ui1,
2000 tfBGRX8ui1, tfXBGR8ui1, tfBGR10X2ui1, tfX2BGR10ui1, tfBGRA8ui1, tfABGR8ui1, tfBGRA8ub4, tfBGR10A2ui1, tfA2BGR10ui1])
2002 result := result + [ ftBMP ];
2006 tfAlpha4ub1, tfAlpha8ub1, tfLuminance4ub1, tfLuminance8ub1,
2009 tfAlpha16us1, tfLuminance16us1,
2010 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
2011 tfX1RGB5us1, tfARGB4us1, tfA1RGB5us1, tfDepth16us1,
2017 tfX2RGB10ui1, tfARGB8ui1, tfBGRA8ub4, tfA2RGB10ui1,
2018 tfDepth24ui1, tfDepth32ui1])
2020 result := result + [ftTGA];
2022 if not (aFormat in [tfEmpty, tfRGB16us3, tfBGR16us3]) then
2023 result := result + [ftDDS];
2025 {$IFDEF GLB_SUPPORT_PNG_WRITE}
2027 tfAlpha8ub1, tfLuminance8ub1, tfLuminance8Alpha8ub2,
2028 tfRGB8ub3, tfRGBA8ui1,
2029 tfBGR8ub3, tfBGRA8ui1] then
2030 result := result + [ftPNG];
2033 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
2034 if aFormat in [tfAlpha8ub1, tfLuminance8ub1, tfRGB8ub3, tfBGR8ub3] then
2035 result := result + [ftJPEG];
2039 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2040 function IsPowerOfTwo(aNumber: Integer): Boolean;
2042 while (aNumber and 1) = 0 do
2043 aNumber := aNumber shr 1;
2044 result := aNumber = 1;
2047 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2048 function GetTopMostBit(aBitSet: QWord): Integer;
2051 while aBitSet > 0 do begin
2053 aBitSet := aBitSet shr 1;
2057 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2058 function CountSetBits(aBitSet: QWord): Integer;
2061 while aBitSet > 0 do begin
2062 if (aBitSet and 1) = 1 then
2064 aBitSet := aBitSet shr 1;
2068 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2069 function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
2072 LUMINANCE_WEIGHT_R * aPixel.Data.r +
2073 LUMINANCE_WEIGHT_G * aPixel.Data.g +
2074 LUMINANCE_WEIGHT_B * aPixel.Data.b);
2077 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2078 function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
2081 DEPTH_WEIGHT_R * aPixel.Data.r +
2082 DEPTH_WEIGHT_G * aPixel.Data.g +
2083 DEPTH_WEIGHT_B * aPixel.Data.b);
2086 {$IFDEF GLB_NATIVE_OGL}
2087 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2088 //OpenGLInitialization///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2089 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2091 GL_LibHandle: Pointer = nil;
2093 function glbGetProcAddress(aProcName: PAnsiChar; aLibHandle: Pointer = nil; const aRaiseOnErr: Boolean = true): Pointer;
2095 if not Assigned(aLibHandle) then
2096 aLibHandle := GL_LibHandle;
2098 {$IF DEFINED(GLB_WIN)}
2099 result := GetProcAddress({%H-}HMODULE(aLibHandle), aProcName);
2100 if Assigned(result) then
2103 if Assigned(wglGetProcAddress) then
2104 result := wglGetProcAddress(aProcName);
2105 {$ELSEIF DEFINED(GLB_LINUX)}
2106 if Assigned(glXGetProcAddress) then begin
2107 result := glXGetProcAddress(aProcName);
2108 if Assigned(result) then
2112 if Assigned(glXGetProcAddressARB) then begin
2113 result := glXGetProcAddressARB(aProcName);
2114 if Assigned(result) then
2118 result := dlsym(aLibHandle, aProcName);
2120 if not Assigned(result) and aRaiseOnErr then
2121 raise EglBitmap.Create('unable to load procedure form library: ' + aProcName);
2124 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
2126 GLU_LibHandle: Pointer = nil;
2127 OpenGLInitialized: Boolean;
2128 InitOpenGLCS: TCriticalSection;
2130 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2131 procedure glbInitOpenGL;
2133 ////////////////////////////////////////////////////////////////////////////////
2134 function glbLoadLibrary(const aName: PChar): Pointer;
2136 {$IF DEFINED(GLB_WIN)}
2137 result := {%H-}Pointer(LoadLibrary(aName));
2138 {$ELSEIF DEFINED(GLB_LINUX)}
2139 result := dlopen(Name, RTLD_LAZY);
2145 ////////////////////////////////////////////////////////////////////////////////
2146 function glbFreeLibrary(const aLibHandle: Pointer): Boolean;
2149 if not Assigned(aLibHandle) then
2152 {$IF DEFINED(GLB_WIN)}
2153 Result := FreeLibrary({%H-}HINST(aLibHandle));
2154 {$ELSEIF DEFINED(GLB_LINUX)}
2155 Result := dlclose(aLibHandle) = 0;
2160 if Assigned(GL_LibHandle) then
2161 glbFreeLibrary(GL_LibHandle);
2163 if Assigned(GLU_LibHandle) then
2164 glbFreeLibrary(GLU_LibHandle);
2166 GL_LibHandle := glbLoadLibrary(libopengl);
2167 if not Assigned(GL_LibHandle) then
2168 raise EglBitmap.Create('unable to load library: ' + libopengl);
2170 GLU_LibHandle := glbLoadLibrary(libglu);
2171 if not Assigned(GLU_LibHandle) then
2172 raise EglBitmap.Create('unable to load library: ' + libglu);
2174 {$IF DEFINED(GLB_WIN)}
2175 wglGetProcAddress := glbGetProcAddress('wglGetProcAddress');
2176 {$ELSEIF DEFINED(GLB_LINUX)}
2177 glXGetProcAddress := glbGetProcAddress('glXGetProcAddress');
2178 glXGetProcAddressARB := glbGetProcAddress('glXGetProcAddressARB');
2181 glEnable := glbGetProcAddress('glEnable');
2182 glDisable := glbGetProcAddress('glDisable');
2183 glGetString := glbGetProcAddress('glGetString');
2184 glGetIntegerv := glbGetProcAddress('glGetIntegerv');
2185 glTexParameteri := glbGetProcAddress('glTexParameteri');
2186 glTexParameteriv := glbGetProcAddress('glTexParameteriv');
2187 glTexParameterfv := glbGetProcAddress('glTexParameterfv');
2188 glGetTexParameteriv := glbGetProcAddress('glGetTexParameteriv');
2189 glGetTexParameterfv := glbGetProcAddress('glGetTexParameterfv');
2190 glGetTexLevelParameteriv := glbGetProcAddress('glGetTexLevelParameteriv');
2191 glGetTexLevelParameterfv := glbGetProcAddress('glGetTexLevelParameterfv');
2192 glTexGeni := glbGetProcAddress('glTexGeni');
2193 glGenTextures := glbGetProcAddress('glGenTextures');
2194 glBindTexture := glbGetProcAddress('glBindTexture');
2195 glDeleteTextures := glbGetProcAddress('glDeleteTextures');
2196 glAreTexturesResident := glbGetProcAddress('glAreTexturesResident');
2197 glReadPixels := glbGetProcAddress('glReadPixels');
2198 glPixelStorei := glbGetProcAddress('glPixelStorei');
2199 glTexImage1D := glbGetProcAddress('glTexImage1D');
2200 glTexImage2D := glbGetProcAddress('glTexImage2D');
2201 glGetTexImage := glbGetProcAddress('glGetTexImage');
2203 gluBuild1DMipmaps := glbGetProcAddress('gluBuild1DMipmaps', GLU_LibHandle);
2204 gluBuild2DMipmaps := glbGetProcAddress('gluBuild2DMipmaps', GLU_LibHandle);
2208 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2209 procedure glbReadOpenGLExtensions;
2212 MajorVersion, MinorVersion: Integer;
2214 ///////////////////////////////////////////////////////////////////////////////////////////
2215 procedure TrimVersionString(aBuffer: AnsiString; out aMajor, aMinor: Integer);
2222 Separator := Pos(AnsiString('.'), aBuffer);
2223 if (Separator > 1) and (Separator < Length(aBuffer)) and
2224 (aBuffer[Separator - 1] in ['0'..'9']) and
2225 (aBuffer[Separator + 1] in ['0'..'9']) then begin
2228 while (Separator > 0) and (aBuffer[Separator] in ['0'..'9']) do
2231 Delete(aBuffer, 1, Separator);
2232 Separator := Pos(AnsiString('.'), aBuffer) + 1;
2234 while (Separator <= Length(aBuffer)) and (AnsiChar(aBuffer[Separator]) in ['0'..'9']) do
2237 Delete(aBuffer, Separator, 255);
2238 Separator := Pos(AnsiString('.'), aBuffer);
2240 aMajor := StrToInt(Copy(String(aBuffer), 1, Separator - 1));
2241 aMinor := StrToInt(Copy(String(aBuffer), Separator + 1, 1));
2245 ///////////////////////////////////////////////////////////////////////////////////////////
2246 function CheckExtension(const Extension: AnsiString): Boolean;
2250 ExtPos := Pos(Extension, Buffer);
2251 result := ExtPos > 0;
2253 result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
2256 ///////////////////////////////////////////////////////////////////////////////////////////
2257 function CheckVersion(const aMajor, aMinor: Integer): Boolean;
2259 result := (MajorVersion > aMajor) or ((MajorVersion = aMajor) and (MinorVersion >= aMinor));
2263 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
2266 if not OpenGLInitialized then begin
2268 OpenGLInitialized := true;
2276 Buffer := glGetString(GL_VERSION);
2277 TrimVersionString(Buffer, MajorVersion, MinorVersion);
2279 GL_VERSION_1_2 := CheckVersion(1, 2);
2280 GL_VERSION_1_3 := CheckVersion(1, 3);
2281 GL_VERSION_1_4 := CheckVersion(1, 4);
2282 GL_VERSION_2_0 := CheckVersion(2, 0);
2283 GL_VERSION_3_3 := CheckVersion(3, 3);
2286 Buffer := glGetString(GL_EXTENSIONS);
2287 GL_ARB_texture_border_clamp := CheckExtension('GL_ARB_texture_border_clamp');
2288 GL_ARB_texture_non_power_of_two := CheckExtension('GL_ARB_texture_non_power_of_two');
2289 GL_ARB_texture_swizzle := CheckExtension('GL_ARB_texture_swizzle');
2290 GL_ARB_texture_cube_map := CheckExtension('GL_ARB_texture_cube_map');
2291 GL_ARB_texture_rectangle := CheckExtension('GL_ARB_texture_rectangle');
2292 GL_ARB_texture_mirrored_repeat := CheckExtension('GL_ARB_texture_mirrored_repeat');
2293 GL_EXT_texture_edge_clamp := CheckExtension('GL_EXT_texture_edge_clamp');
2294 GL_EXT_texture_filter_anisotropic := CheckExtension('GL_EXT_texture_filter_anisotropic');
2295 GL_EXT_texture_rectangle := CheckExtension('GL_EXT_texture_rectangle');
2296 GL_EXT_texture_swizzle := CheckExtension('GL_EXT_texture_swizzle');
2297 GL_EXT_texture_cube_map := CheckExtension('GL_EXT_texture_cube_map');
2298 GL_NV_texture_rectangle := CheckExtension('GL_NV_texture_rectangle');
2299 GL_IBM_texture_mirrored_repeat := CheckExtension('GL_IBM_texture_mirrored_repeat');
2300 GL_SGIS_generate_mipmap := CheckExtension('GL_SGIS_generate_mipmap');
2302 if GL_VERSION_1_3 then begin
2303 glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1D');
2304 glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2D');
2305 glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImage');
2307 glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1DARB', nil, false);
2308 glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2DARB', nil, false);
2309 glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImageARB', nil, false);
2314 {$IFDEF GLB_SDL_IMAGE}
2315 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2316 // SDL Image Helper /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2317 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2318 function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
2320 result := TStream(context^.unknown.data1).Seek(offset, whence);
2323 function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
2325 result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
2328 function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
2330 result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
2333 function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
2338 function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
2340 result := SDL_AllocRW;
2342 if result = nil then
2343 raise EglBitmap.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
2345 result^.seek := glBitmapRWseek;
2346 result^.read := glBitmapRWread;
2347 result^.write := glBitmapRWwrite;
2348 result^.close := glBitmapRWclose;
2349 result^.unknown.data1 := Stream;
2353 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2354 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
2356 glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
2359 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2360 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
2362 glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
2365 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2366 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
2368 glBitmapDefaultMipmap := aValue;
2371 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2372 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
2374 glBitmapDefaultFormat := aFormat;
2377 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2378 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
2380 glBitmapDefaultFilterMin := aMin;
2381 glBitmapDefaultFilterMag := aMag;
2384 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2385 procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
2387 glBitmapDefaultWrapS := S;
2388 glBitmapDefaultWrapT := T;
2389 glBitmapDefaultWrapR := R;
2392 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2393 procedure glBitmapSetDefaultSwizzle(const r: GLenum = GL_RED; g: GLenum = GL_GREEN; b: GLenum = GL_BLUE; a: GLenum = GL_ALPHA);
2395 glDefaultSwizzle[0] := r;
2396 glDefaultSwizzle[1] := g;
2397 glDefaultSwizzle[2] := b;
2398 glDefaultSwizzle[3] := a;
2401 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2402 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
2404 result := glBitmapDefaultDeleteTextureOnFree;
2407 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2408 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
2410 result := glBitmapDefaultFreeDataAfterGenTextures;
2413 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2414 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
2416 result := glBitmapDefaultMipmap;
2419 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2420 function glBitmapGetDefaultFormat: TglBitmapFormat;
2422 result := glBitmapDefaultFormat;
2425 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2426 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
2428 aMin := glBitmapDefaultFilterMin;
2429 aMag := glBitmapDefaultFilterMag;
2432 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2433 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
2435 S := glBitmapDefaultWrapS;
2436 T := glBitmapDefaultWrapT;
2437 R := glBitmapDefaultWrapR;
2440 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2441 procedure glBitmapGetDefaultSwizzle(var r, g, b, a: GLenum);
2443 r := glDefaultSwizzle[0];
2444 g := glDefaultSwizzle[1];
2445 b := glDefaultSwizzle[2];
2446 a := glDefaultSwizzle[3];
2449 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2450 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2451 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2452 function TFormatDescriptor.GetSize(const aSize: TglBitmapPixelPosition): Integer;
2456 if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
2457 w := Max(1, aSize.X);
2458 h := Max(1, aSize.Y);
2459 result := GetSize(w, h);
2464 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2465 function TFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer;
2468 if (aWidth <= 0) or (aHeight <= 0) then
2470 result := Ceil(aWidth * aHeight * BytesPerPixel);
2473 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2474 function TFormatDescriptor.CreateMappingData: Pointer;
2479 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2480 procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
2485 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2486 function TFormatDescriptor.IsEmpty: Boolean;
2488 result := (fFormat = tfEmpty);
2491 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2492 function TFormatDescriptor.MaskMatch(const aMask: TglBitmapRec4ul): Boolean;
2498 if (aMask.r = 0) and (aMask.g = 0) and (aMask.b = 0) and (aMask.a = 0) then
2499 raise EglBitmap.Create('FormatCheckFormat - All Masks are 0');
2502 if (aMask.arr[i] <> m.arr[i]) then
2507 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2508 procedure TFormatDescriptor.PreparePixel(out aPixel: TglBitmapPixelData);
2510 FillChar(aPixel{%H-}, SizeOf(aPixel), 0);
2511 aPixel.Data := Range;
2512 aPixel.Format := fFormat;
2513 aPixel.Range := Range;
2516 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2517 constructor TFormatDescriptor.Create;
2522 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2523 //TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2524 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2525 procedure TfdAlphaUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2527 aData^ := aPixel.Data.a;
2531 procedure TfdAlphaUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2536 aPixel.Data.a := aData^;
2540 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2541 //TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2542 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2543 procedure TfdLuminanceUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2545 aData^ := LuminanceWeight(aPixel);
2549 procedure TfdLuminanceUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2551 aPixel.Data.r := aData^;
2552 aPixel.Data.g := aData^;
2553 aPixel.Data.b := aData^;
2558 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2559 //TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2560 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2561 procedure TfdUniversalUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2567 if (Range.arr[i] > 0) then
2568 aData^ := aData^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2572 procedure TfdUniversalUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2577 aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and Range.arr[i];
2581 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2582 //TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2583 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2584 procedure TfdLuminanceAlphaUB2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2586 inherited Map(aPixel, aData, aMapData);
2587 aData^ := aPixel.Data.a;
2591 procedure TfdLuminanceAlphaUB2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2593 inherited Unmap(aData, aPixel, aMapData);
2594 aPixel.Data.a := aData^;
2598 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2599 //TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2600 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2601 procedure TfdRGBub3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2603 aData^ := aPixel.Data.r;
2605 aData^ := aPixel.Data.g;
2607 aData^ := aPixel.Data.b;
2611 procedure TfdRGBub3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2613 aPixel.Data.r := aData^;
2615 aPixel.Data.g := aData^;
2617 aPixel.Data.b := aData^;
2622 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2623 //TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2624 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2625 procedure TfdBGRub3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2627 aData^ := aPixel.Data.b;
2629 aData^ := aPixel.Data.g;
2631 aData^ := aPixel.Data.r;
2635 procedure TfdBGRub3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2637 aPixel.Data.b := aData^;
2639 aPixel.Data.g := aData^;
2641 aPixel.Data.r := aData^;
2646 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2647 //TfdRGBA_UB4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2648 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2649 procedure TfdRGBAub4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2651 inherited Map(aPixel, aData, aMapData);
2652 aData^ := aPixel.Data.a;
2656 procedure TfdRGBAub4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2658 inherited Unmap(aData, aPixel, aMapData);
2659 aPixel.Data.a := aData^;
2663 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2664 //TfdBGRA_UB4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2665 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2666 procedure TfdBGRAub4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2668 inherited Map(aPixel, aData, aMapData);
2669 aData^ := aPixel.Data.a;
2673 procedure TfdBGRAub4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2675 inherited Unmap(aData, aPixel, aMapData);
2676 aPixel.Data.a := aData^;
2680 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2681 //TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2682 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2683 procedure TfdAlphaUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2685 PWord(aData)^ := aPixel.Data.a;
2689 procedure TfdAlphaUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2694 aPixel.Data.a := PWord(aData)^;
2698 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2699 //TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2700 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2701 procedure TfdLuminanceUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2703 PWord(aData)^ := LuminanceWeight(aPixel);
2707 procedure TfdLuminanceUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2709 aPixel.Data.r := PWord(aData)^;
2710 aPixel.Data.g := PWord(aData)^;
2711 aPixel.Data.b := PWord(aData)^;
2716 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2717 //TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2718 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2719 procedure TfdUniversalUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2725 if (Range.arr[i] > 0) then
2726 PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2730 procedure TfdUniversalUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2735 aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and Range.arr[i];
2739 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2740 //TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2741 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2742 procedure TfdDepthUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2744 PWord(aData)^ := DepthWeight(aPixel);
2748 procedure TfdDepthUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2750 aPixel.Data.r := PWord(aData)^;
2751 aPixel.Data.g := PWord(aData)^;
2752 aPixel.Data.b := PWord(aData)^;
2753 aPixel.Data.a := PWord(aData)^;;
2757 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2758 //TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2759 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2760 procedure TfdLuminanceAlphaUS2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2762 inherited Map(aPixel, aData, aMapData);
2763 PWord(aData)^ := aPixel.Data.a;
2767 procedure TfdLuminanceAlphaUS2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2769 inherited Unmap(aData, aPixel, aMapData);
2770 aPixel.Data.a := PWord(aData)^;
2774 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2775 //TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2776 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2777 procedure TfdRGBus3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2779 PWord(aData)^ := aPixel.Data.r;
2781 PWord(aData)^ := aPixel.Data.g;
2783 PWord(aData)^ := aPixel.Data.b;
2787 procedure TfdRGBus3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2789 aPixel.Data.r := PWord(aData)^;
2791 aPixel.Data.g := PWord(aData)^;
2793 aPixel.Data.b := PWord(aData)^;
2798 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2799 //TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2800 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2801 procedure TfdBGRus3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2803 PWord(aData)^ := aPixel.Data.b;
2805 PWord(aData)^ := aPixel.Data.g;
2807 PWord(aData)^ := aPixel.Data.r;
2811 procedure TfdBGRus3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2813 aPixel.Data.b := PWord(aData)^;
2815 aPixel.Data.g := PWord(aData)^;
2817 aPixel.Data.r := PWord(aData)^;
2822 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2823 //TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2824 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2825 procedure TfdRGBAus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2827 inherited Map(aPixel, aData, aMapData);
2828 PWord(aData)^ := aPixel.Data.a;
2832 procedure TfdRGBAus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2834 inherited Unmap(aData, aPixel, aMapData);
2835 aPixel.Data.a := PWord(aData)^;
2839 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2840 //TfdARGB_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2841 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2842 procedure TfdARGBus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2844 PWord(aData)^ := aPixel.Data.a;
2846 inherited Map(aPixel, aData, aMapData);
2849 procedure TfdARGBus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2851 aPixel.Data.a := PWord(aData)^;
2853 inherited Unmap(aData, aPixel, aMapData);
2856 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2857 //TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2858 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2859 procedure TfdBGRAus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2861 inherited Map(aPixel, aData, aMapData);
2862 PWord(aData)^ := aPixel.Data.a;
2866 procedure TfdBGRAus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2868 inherited Unmap(aData, aPixel, aMapData);
2869 aPixel.Data.a := PWord(aData)^;
2873 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2874 //TfdABGR_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2875 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2876 procedure TfdABGRus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2878 PWord(aData)^ := aPixel.Data.a;
2880 inherited Map(aPixel, aData, aMapData);
2883 procedure TfdABGRus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2885 aPixel.Data.a := PWord(aData)^;
2887 inherited Unmap(aData, aPixel, aMapData);
2890 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2891 //TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2892 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2893 procedure TfdUniversalUI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2897 PCardinal(aData)^ := 0;
2899 if (Range.arr[i] > 0) then
2900 PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2904 procedure TfdUniversalUI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2909 aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and Range.arr[i];
2913 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2914 //TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2915 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2916 procedure TfdDepthUI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2918 PCardinal(aData)^ := DepthWeight(aPixel);
2922 procedure TfdDepthUI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2924 aPixel.Data.r := PCardinal(aData)^;
2925 aPixel.Data.g := PCardinal(aData)^;
2926 aPixel.Data.b := PCardinal(aData)^;
2927 aPixel.Data.a := PCardinal(aData)^;
2931 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2932 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2933 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2934 procedure TfdAlpha4ub1.SetValues;
2936 inherited SetValues;
2938 fFormat := tfAlpha4ub1;
2939 fWithAlpha := tfAlpha4ub1;
2940 fOpenGLFormat := tfAlpha4ub1;
2941 fPrecision := glBitmapRec4ub(0, 0, 0, 8);
2942 fShift := glBitmapRec4ub(0, 0, 0, 0);
2943 fglFormat := GL_ALPHA;
2944 fglInternalFormat := GL_ALPHA4;
2945 fglDataFormat := GL_UNSIGNED_BYTE;
2948 procedure TfdAlpha8ub1.SetValues;
2950 inherited SetValues;
2952 fFormat := tfAlpha8ub1;
2953 fWithAlpha := tfAlpha8ub1;
2954 fOpenGLFormat := tfAlpha8ub1;
2955 fPrecision := glBitmapRec4ub(0, 0, 0, 8);
2956 fShift := glBitmapRec4ub(0, 0, 0, 0);
2957 fglFormat := GL_ALPHA;
2958 fglInternalFormat := GL_ALPHA8;
2959 fglDataFormat := GL_UNSIGNED_BYTE;
2962 procedure TfdAlpha16us1.SetValues;
2964 inherited SetValues;
2965 fBitsPerPixel := 16;
2966 fFormat := tfAlpha16us1;
2967 fWithAlpha := tfAlpha16us1;
2968 fOpenGLFormat := tfAlpha16us1;
2969 fPrecision := glBitmapRec4ub(0, 0, 0, 16);
2970 fShift := glBitmapRec4ub(0, 0, 0, 0);
2971 fglFormat := GL_ALPHA;
2972 fglInternalFormat := GL_ALPHA16;
2973 fglDataFormat := GL_UNSIGNED_SHORT;
2976 procedure TfdLuminance4ub1.SetValues;
2978 inherited SetValues;
2980 fFormat := tfLuminance4ub1;
2981 fWithAlpha := tfLuminance4Alpha4ub2;
2982 fWithoutAlpha := tfLuminance4ub1;
2983 fOpenGLFormat := tfLuminance4ub1;
2984 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
2985 fShift := glBitmapRec4ub(0, 0, 0, 0);
2986 fglFormat := GL_LUMINANCE;
2987 fglInternalFormat := GL_LUMINANCE4;
2988 fglDataFormat := GL_UNSIGNED_BYTE;
2991 procedure TfdLuminance8ub1.SetValues;
2993 inherited SetValues;
2995 fFormat := tfLuminance8ub1;
2996 fWithAlpha := tfLuminance8Alpha8ub2;
2997 fWithoutAlpha := tfLuminance8ub1;
2998 fOpenGLFormat := tfLuminance8ub1;
2999 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
3000 fShift := glBitmapRec4ub(0, 0, 0, 0);
3001 fglFormat := GL_LUMINANCE;
3002 fglInternalFormat := GL_LUMINANCE8;
3003 fglDataFormat := GL_UNSIGNED_BYTE;
3006 procedure TfdLuminance16us1.SetValues;
3008 inherited SetValues;
3009 fBitsPerPixel := 16;
3010 fFormat := tfLuminance16us1;
3011 fWithAlpha := tfLuminance16Alpha16us2;
3012 fWithoutAlpha := tfLuminance16us1;
3013 fOpenGLFormat := tfLuminance16us1;
3014 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
3015 fShift := glBitmapRec4ub( 0, 0, 0, 0);
3016 fglFormat := GL_LUMINANCE;
3017 fglInternalFormat := GL_LUMINANCE16;
3018 fglDataFormat := GL_UNSIGNED_SHORT;
3021 procedure TfdLuminance4Alpha4ub2.SetValues;
3023 inherited SetValues;
3024 fBitsPerPixel := 16;
3025 fFormat := tfLuminance4Alpha4ub2;
3026 fWithAlpha := tfLuminance4Alpha4ub2;
3027 fWithoutAlpha := tfLuminance4ub1;
3028 fOpenGLFormat := tfLuminance4Alpha4ub2;
3029 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
3030 fShift := glBitmapRec4ub(0, 0, 0, 8);
3031 fglFormat := GL_LUMINANCE_ALPHA;
3032 fglInternalFormat := GL_LUMINANCE4_ALPHA4;
3033 fglDataFormat := GL_UNSIGNED_BYTE;
3036 procedure TfdLuminance6Alpha2ub2.SetValues;
3038 inherited SetValues;
3039 fBitsPerPixel := 16;
3040 fFormat := tfLuminance6Alpha2ub2;
3041 fWithAlpha := tfLuminance6Alpha2ub2;
3042 fWithoutAlpha := tfLuminance8ub1;
3043 fOpenGLFormat := tfLuminance6Alpha2ub2;
3044 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
3045 fShift := glBitmapRec4ub(0, 0, 0, 8);
3046 fglFormat := GL_LUMINANCE_ALPHA;
3047 fglInternalFormat := GL_LUMINANCE6_ALPHA2;
3048 fglDataFormat := GL_UNSIGNED_BYTE;
3051 procedure TfdLuminance8Alpha8ub2.SetValues;
3053 inherited SetValues;
3054 fBitsPerPixel := 16;
3055 fFormat := tfLuminance8Alpha8ub2;
3056 fWithAlpha := tfLuminance8Alpha8ub2;
3057 fWithoutAlpha := tfLuminance8ub1;
3058 fOpenGLFormat := tfLuminance8Alpha8ub2;
3059 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
3060 fShift := glBitmapRec4ub(0, 0, 0, 8);
3061 fglFormat := GL_LUMINANCE_ALPHA;
3062 fglInternalFormat := GL_LUMINANCE8_ALPHA8;
3063 fglDataFormat := GL_UNSIGNED_BYTE;
3066 procedure TfdLuminance12Alpha4us2.SetValues;
3068 inherited SetValues;
3069 fBitsPerPixel := 32;
3070 fFormat := tfLuminance12Alpha4us2;
3071 fWithAlpha := tfLuminance12Alpha4us2;
3072 fWithoutAlpha := tfLuminance16us1;
3073 fOpenGLFormat := tfLuminance12Alpha4us2;
3074 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3075 fShift := glBitmapRec4ub( 0, 0, 0, 16);
3076 fglFormat := GL_LUMINANCE_ALPHA;
3077 fglInternalFormat := GL_LUMINANCE12_ALPHA4;
3078 fglDataFormat := GL_UNSIGNED_SHORT;
3081 procedure TfdLuminance16Alpha16us2.SetValues;
3083 inherited SetValues;
3084 fBitsPerPixel := 32;
3085 fFormat := tfLuminance16Alpha16us2;
3086 fWithAlpha := tfLuminance16Alpha16us2;
3087 fWithoutAlpha := tfLuminance16us1;
3088 fOpenGLFormat := tfLuminance16Alpha16us2;
3089 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3090 fShift := glBitmapRec4ub( 0, 0, 0, 16);
3091 fglFormat := GL_LUMINANCE_ALPHA;
3092 fglInternalFormat := GL_LUMINANCE16_ALPHA16;
3093 fglDataFormat := GL_UNSIGNED_SHORT;
3096 procedure TfdR3G3B2ub1.SetValues;
3098 inherited SetValues;
3100 fFormat := tfR3G3B2ub1;
3101 fWithAlpha := tfRGBA4us1;
3102 fWithoutAlpha := tfR3G3B2ub1;
3103 fOpenGLFormat := tfR3G3B2ub1;
3104 fRGBInverted := tfEmpty;
3105 fPrecision := glBitmapRec4ub(3, 3, 2, 0);
3106 fShift := glBitmapRec4ub(5, 2, 0, 0);
3107 fglFormat := GL_RGB;
3108 fglInternalFormat := GL_R3_G3_B2;
3109 fglDataFormat := GL_UNSIGNED_BYTE_3_3_2;
3112 procedure TfdRGBX4us1.SetValues;
3114 inherited SetValues;
3115 fBitsPerPixel := 16;
3116 fFormat := tfRGBX4us1;
3117 fWithAlpha := tfRGBA4us1;
3118 fWithoutAlpha := tfRGBX4us1;
3119 fOpenGLFormat := tfRGBX4us1;
3120 fRGBInverted := tfBGRX4us1;
3121 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
3122 fShift := glBitmapRec4ub(12, 8, 4, 0);
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;
3128 procedure TfdXRGB4us1.SetValues;
3130 inherited SetValues;
3131 fBitsPerPixel := 16;
3132 fFormat := tfXRGB4us1;
3133 fWithAlpha := tfARGB4us1;
3134 fWithoutAlpha := tfXRGB4us1;
3135 fOpenGLFormat := tfXRGB4us1;
3136 fRGBInverted := tfXBGR4us1;
3137 fPrecision := glBitmapRec4ub(4, 4, 4, 0);
3138 fShift := glBitmapRec4ub(8, 4, 0, 0);
3139 fglFormat := GL_BGRA;
3140 fglInternalFormat := GL_RGB4;
3141 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3144 procedure TfdR5G6B5us1.SetValues;
3146 inherited SetValues;
3147 fBitsPerPixel := 16;
3148 fFormat := tfR5G6B5us1;
3149 fWithAlpha := tfRGB5A1us1;
3150 fWithoutAlpha := tfR5G6B5us1;
3151 fOpenGLFormat := tfR5G6B5us1;
3152 fRGBInverted := tfB5G6R5us1;
3153 fPrecision := glBitmapRec4ub( 5, 6, 5, 0);
3154 fShift := glBitmapRec4ub(11, 5, 0, 0);
3155 fglFormat := GL_RGB;
3156 fglInternalFormat := GL_RGB565;
3157 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5;
3160 procedure TfdRGB5X1us1.SetValues;
3162 inherited SetValues;
3163 fBitsPerPixel := 16;
3164 fFormat := tfRGB5X1us1;
3165 fWithAlpha := tfRGB5A1us1;
3166 fWithoutAlpha := tfRGB5X1us1;
3167 fOpenGLFormat := tfRGB5X1us1;
3168 fRGBInverted := tfBGR5X1us1;
3169 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3170 fShift := glBitmapRec4ub(11, 6, 1, 0);
3171 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3172 fglInternalFormat := GL_RGB5;
3173 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3176 procedure TfdX1RGB5us1.SetValues;
3178 inherited SetValues;
3179 fBitsPerPixel := 16;
3180 fFormat := tfX1RGB5us1;
3181 fWithAlpha := tfA1RGB5us1;
3182 fWithoutAlpha := tfX1RGB5us1;
3183 fOpenGLFormat := tfX1RGB5us1;
3184 fRGBInverted := tfX1BGR5us1;
3185 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3186 fShift := glBitmapRec4ub(10, 5, 0, 0);
3187 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3188 fglInternalFormat := GL_RGB5;
3189 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3192 procedure TfdRGB8ub3.SetValues;
3194 inherited SetValues;
3195 fBitsPerPixel := 24;
3196 fFormat := tfRGB8ub3;
3197 fWithAlpha := tfRGBA8ub4;
3198 fWithoutAlpha := tfRGB8ub3;
3199 fOpenGLFormat := tfRGB8ub3;
3200 fRGBInverted := tfBGR8ub3;
3201 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
3202 fShift := glBitmapRec4ub(0, 8, 16, 0);
3203 fglFormat := GL_RGB;
3204 fglInternalFormat := GL_RGB8;
3205 fglDataFormat := GL_UNSIGNED_BYTE;
3208 procedure TfdRGBX8ui1.SetValues;
3210 inherited SetValues;
3211 fBitsPerPixel := 32;
3212 fFormat := tfRGBX8ui1;
3213 fWithAlpha := tfRGBA8ui1;
3214 fWithoutAlpha := tfRGBX8ui1;
3215 fOpenGLFormat := tfRGB8ub3;
3216 fRGBInverted := tfBGRX8ui1;
3217 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3218 fShift := glBitmapRec4ub(24, 16, 8, 0);
3219 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3220 fglInternalFormat := GL_RGB8;
3221 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3224 procedure TfdXRGB8ui1.SetValues;
3226 inherited SetValues;
3227 fBitsPerPixel := 32;
3228 fFormat := tfXRGB8ui1;
3229 fWithAlpha := tfXRGB8ui1;
3230 fWithoutAlpha := tfXRGB8ui1;
3231 fOpenGLFormat := tfRGB8ub3;
3232 fRGBInverted := tfXBGR8ui1;
3233 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3234 fShift := glBitmapRec4ub(16, 8, 0, 0);
3235 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3236 fglInternalFormat := GL_RGB8;
3237 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3240 procedure TfdRGB10X2ui1.SetValues;
3242 inherited SetValues;
3243 fBitsPerPixel := 32;
3244 fFormat := tfRGB10X2ui1;
3245 fWithAlpha := tfRGB10A2ui1;
3246 fWithoutAlpha := tfRGB10X2ui1;
3247 fOpenGLFormat := tfRGB10X2ui1;
3248 fRGBInverted := tfBGR10X2ui1;
3249 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3250 fShift := glBitmapRec4ub(22, 12, 2, 0);
3251 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3252 fglInternalFormat := GL_RGB10;
3253 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3256 procedure TfdX2RGB10ui1.SetValues;
3258 inherited SetValues;
3259 fBitsPerPixel := 32;
3260 fFormat := tfX2RGB10ui1;
3261 fWithAlpha := tfA2RGB10ui1;
3262 fWithoutAlpha := tfX2RGB10ui1;
3263 fOpenGLFormat := tfX2RGB10ui1;
3264 fRGBInverted := tfX2BGR10ui1;
3265 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3266 fShift := glBitmapRec4ub(20, 10, 0, 0);
3267 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3268 fglInternalFormat := GL_RGB10;
3269 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3272 procedure TfdRGB16us3.SetValues;
3274 inherited SetValues;
3275 fBitsPerPixel := 48;
3276 fFormat := tfRGB16us3;
3277 fWithAlpha := tfRGBA16us4;
3278 fWithoutAlpha := tfRGB16us3;
3279 fOpenGLFormat := tfRGB16us3;
3280 fRGBInverted := tfBGR16us3;
3281 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
3282 fShift := glBitmapRec4ub( 0, 16, 32, 0);
3283 fglFormat := GL_RGB;
3284 fglInternalFormat := GL_RGB16;
3285 fglDataFormat := GL_UNSIGNED_SHORT;
3288 procedure TfdRGBA4us1.SetValues;
3290 inherited SetValues;
3291 fBitsPerPixel := 16;
3292 fFormat := tfRGBA4us1;
3293 fWithAlpha := tfRGBA4us1;
3294 fWithoutAlpha := tfRGBX4us1;
3295 fOpenGLFormat := tfRGBA4us1;
3296 fRGBInverted := tfBGRA4us1;
3297 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3298 fShift := glBitmapRec4ub(12, 8, 4, 0);
3299 fglFormat := GL_RGBA;
3300 fglInternalFormat := GL_RGBA4;
3301 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3304 procedure TfdARGB4us1.SetValues;
3306 inherited SetValues;
3307 fBitsPerPixel := 16;
3308 fFormat := tfARGB4us1;
3309 fWithAlpha := tfARGB4us1;
3310 fWithoutAlpha := tfXRGB4us1;
3311 fOpenGLFormat := tfARGB4us1;
3312 fRGBInverted := tfABGR4us1;
3313 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3314 fShift := glBitmapRec4ub( 8, 4, 0, 12);
3315 fglFormat := GL_BGRA;
3316 fglInternalFormat := GL_RGBA4;
3317 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3320 procedure TfdRGB5A1us1.SetValues;
3322 inherited SetValues;
3323 fBitsPerPixel := 16;
3324 fFormat := tfRGB5A1us1;
3325 fWithAlpha := tfRGB5A1us1;
3326 fWithoutAlpha := tfRGB5X1us1;
3327 fOpenGLFormat := tfRGB5A1us1;
3328 fRGBInverted := tfBGR5A1us1;
3329 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3330 fShift := glBitmapRec4ub(11, 6, 1, 0);
3331 fglFormat := GL_RGBA;
3332 fglInternalFormat := GL_RGB5_A1;
3333 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3336 procedure TfdA1RGB5us1.SetValues;
3338 inherited SetValues;
3339 fBitsPerPixel := 16;
3340 fFormat := tfA1RGB5us1;
3341 fWithAlpha := tfA1RGB5us1;
3342 fWithoutAlpha := tfX1RGB5us1;
3343 fOpenGLFormat := tfA1RGB5us1;
3344 fRGBInverted := tfA1BGR5us1;
3345 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3346 fShift := glBitmapRec4ub(10, 5, 0, 15);
3347 fglFormat := GL_BGRA;
3348 fglInternalFormat := GL_RGB5_A1;
3349 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3352 procedure TfdRGBA8ui1.SetValues;
3354 inherited SetValues;
3355 fBitsPerPixel := 32;
3356 fFormat := tfRGBA8ui1;
3357 fWithAlpha := tfRGBA8ui1;
3358 fWithoutAlpha := tfRGBX8ui1;
3359 fOpenGLFormat := tfRGBA8ui1;
3360 fRGBInverted := tfBGRA8ui1;
3361 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3362 fShift := glBitmapRec4ub(24, 16, 8, 0);
3363 fglFormat := GL_RGBA;
3364 fglInternalFormat := GL_RGBA8;
3365 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3368 procedure TfdARGB8ui1.SetValues;
3370 inherited SetValues;
3371 fBitsPerPixel := 32;
3372 fFormat := tfARGB8ui1;
3373 fWithAlpha := tfARGB8ui1;
3374 fWithoutAlpha := tfXRGB8ui1;
3375 fOpenGLFormat := tfARGB8ui1;
3376 fRGBInverted := tfABGR8ui1;
3377 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3378 fShift := glBitmapRec4ub(16, 8, 0, 24);
3379 fglFormat := GL_BGRA;
3380 fglInternalFormat := GL_RGBA8;
3381 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3384 procedure TfdRGBA8ub4.SetValues;
3386 inherited SetValues;
3387 fBitsPerPixel := 32;
3388 fFormat := tfRGBA8ub4;
3389 fWithAlpha := tfRGBA8ub4;
3390 fWithoutAlpha := tfRGB8ub3;
3391 fOpenGLFormat := tfRGBA8ub4;
3392 fRGBInverted := tfBGRA8ub4;
3393 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3394 fShift := glBitmapRec4ub( 0, 8, 16, 24);
3395 fglFormat := GL_RGBA;
3396 fglInternalFormat := GL_RGBA8;
3397 fglDataFormat := GL_UNSIGNED_BYTE;
3400 procedure TfdRGB10A2ui1.SetValues;
3402 inherited SetValues;
3403 fBitsPerPixel := 32;
3404 fFormat := tfRGB10A2ui1;
3405 fWithAlpha := tfRGB10A2ui1;
3406 fWithoutAlpha := tfRGB10X2ui1;
3407 fOpenGLFormat := tfRGB10A2ui1;
3408 fRGBInverted := tfBGR10A2ui1;
3409 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3410 fShift := glBitmapRec4ub(22, 12, 2, 0);
3411 fglFormat := GL_RGBA;
3412 fglInternalFormat := GL_RGB10_A2;
3413 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3416 procedure TfdA2RGB10ui1.SetValues;
3418 inherited SetValues;
3419 fBitsPerPixel := 32;
3420 fFormat := tfA2RGB10ui1;
3421 fWithAlpha := tfA2RGB10ui1;
3422 fWithoutAlpha := tfX2RGB10ui1;
3423 fOpenGLFormat := tfA2RGB10ui1;
3424 fRGBInverted := tfA2BGR10ui1;
3425 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3426 fShift := glBitmapRec4ub(20, 10, 0, 30);
3427 fglFormat := GL_BGRA;
3428 fglInternalFormat := GL_RGB10_A2;
3429 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3432 procedure TfdRGBA16us4.SetValues;
3434 inherited SetValues;
3435 fBitsPerPixel := 64;
3436 fFormat := tfRGBA16us4;
3437 fWithAlpha := tfRGBA16us4;
3438 fWithoutAlpha := tfRGB16us3;
3439 fOpenGLFormat := tfRGBA16us4;
3440 fRGBInverted := tfBGRA16us4;
3441 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3442 fShift := glBitmapRec4ub( 0, 16, 32, 48);
3443 fglFormat := GL_RGBA;
3444 fglInternalFormat := GL_RGBA16;
3445 fglDataFormat := GL_UNSIGNED_SHORT;
3448 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3449 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3450 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3451 procedure TfdBGRX4us1.SetValues;
3453 inherited SetValues;
3454 fBitsPerPixel := 16;
3455 fFormat := tfBGRX4us1;
3456 fWithAlpha := tfBGRA4us1;
3457 fWithoutAlpha := tfBGRX4us1;
3458 fOpenGLFormat := tfBGRX4us1;
3459 fRGBInverted := tfRGBX4us1;
3460 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
3461 fShift := glBitmapRec4ub( 4, 8, 12, 0);
3462 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3463 fglInternalFormat := GL_RGB4;
3464 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3467 procedure TfdXBGR4us1.SetValues;
3469 inherited SetValues;
3470 fBitsPerPixel := 16;
3471 fFormat := tfXBGR4us1;
3472 fWithAlpha := tfABGR4us1;
3473 fWithoutAlpha := tfXBGR4us1;
3474 fOpenGLFormat := tfXBGR4us1;
3475 fRGBInverted := tfXRGB4us1;
3476 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
3477 fShift := glBitmapRec4ub( 0, 4, 8, 0);
3478 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3479 fglInternalFormat := GL_RGB4;
3480 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3483 procedure TfdB5G6R5us1.SetValues;
3485 inherited SetValues;
3486 fBitsPerPixel := 16;
3487 fFormat := tfB5G6R5us1;
3488 fWithAlpha := tfBGR5A1us1;
3489 fWithoutAlpha := tfB5G6R5us1;
3490 fOpenGLFormat := tfB5G6R5us1;
3491 fRGBInverted := tfR5G6B5us1;
3492 fPrecision := glBitmapRec4ub( 5, 6, 5, 0);
3493 fShift := glBitmapRec4ub( 0, 5, 11, 0);
3494 fglFormat := GL_RGB;
3495 fglInternalFormat := GL_RGB565;
3496 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5_REV;
3499 procedure TfdBGR5X1us1.SetValues;
3501 inherited SetValues;
3502 fBitsPerPixel := 16;
3503 fFormat := tfBGR5X1us1;
3504 fWithAlpha := tfBGR5A1us1;
3505 fWithoutAlpha := tfBGR5X1us1;
3506 fOpenGLFormat := tfBGR5X1us1;
3507 fRGBInverted := tfRGB5X1us1;
3508 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3509 fShift := glBitmapRec4ub( 1, 6, 11, 0);
3510 fglFormat := GL_BGRA;
3511 fglInternalFormat := GL_RGB5;
3512 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3515 procedure TfdX1BGR5us1.SetValues;
3517 inherited SetValues;
3518 fBitsPerPixel := 16;
3519 fFormat := tfX1BGR5us1;
3520 fWithAlpha := tfA1BGR5us1;
3521 fWithoutAlpha := tfX1BGR5us1;
3522 fOpenGLFormat := tfX1BGR5us1;
3523 fRGBInverted := tfX1RGB5us1;
3524 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3525 fShift := glBitmapRec4ub( 0, 5, 10, 0);
3526 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3527 fglInternalFormat := GL_RGB5;
3528 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3531 procedure TfdBGR8ub3.SetValues;
3533 inherited SetValues;
3534 fBitsPerPixel := 24;
3535 fFormat := tfBGR8ub3;
3536 fWithAlpha := tfBGRA8ub4;
3537 fWithoutAlpha := tfBGR8ub3;
3538 fOpenGLFormat := tfBGR8ub3;
3539 fRGBInverted := tfRGB8ub3;
3540 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3541 fShift := glBitmapRec4ub(16, 8, 0, 0);
3542 fglFormat := GL_BGR;
3543 fglInternalFormat := GL_RGB8;
3544 fglDataFormat := GL_UNSIGNED_BYTE;
3547 procedure TfdBGRX8ui1.SetValues;
3549 inherited SetValues;
3550 fBitsPerPixel := 32;
3551 fFormat := tfBGRX8ui1;
3552 fWithAlpha := tfBGRA8ui1;
3553 fWithoutAlpha := tfBGRX8ui1;
3554 fOpenGLFormat := tfBGRX8ui1;
3555 fRGBInverted := tfRGBX8ui1;
3556 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3557 fShift := glBitmapRec4ub( 8, 16, 24, 0);
3558 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3559 fglInternalFormat := GL_RGB8;
3560 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3563 procedure TfdXBGR8ui1.SetValues;
3565 inherited SetValues;
3566 fBitsPerPixel := 32;
3567 fFormat := tfXBGR8ui1;
3568 fWithAlpha := tfABGR8ui1;
3569 fWithoutAlpha := tfXBGR8ui1;
3570 fOpenGLFormat := tfXBGR8ui1;
3571 fRGBInverted := tfXRGB8ui1;
3572 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3573 fShift := glBitmapRec4ub( 0, 8, 16, 0);
3574 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3575 fglInternalFormat := GL_RGB8;
3576 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3579 procedure TfdBGR10X2ui1.SetValues;
3581 inherited SetValues;
3582 fBitsPerPixel := 32;
3583 fFormat := tfBGR10X2ui1;
3584 fWithAlpha := tfBGR10A2ui1;
3585 fWithoutAlpha := tfBGR10X2ui1;
3586 fOpenGLFormat := tfBGR10X2ui1;
3587 fRGBInverted := tfRGB10X2ui1;
3588 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3589 fShift := glBitmapRec4ub( 2, 12, 22, 0);
3590 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3591 fglInternalFormat := GL_RGB10;
3592 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3595 procedure TfdX2BGR10ui1.SetValues;
3597 inherited SetValues;
3598 fBitsPerPixel := 32;
3599 fFormat := tfX2BGR10ui1;
3600 fWithAlpha := tfA2BGR10ui1;
3601 fWithoutAlpha := tfX2BGR10ui1;
3602 fOpenGLFormat := tfX2BGR10ui1;
3603 fRGBInverted := tfX2RGB10ui1;
3604 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3605 fShift := glBitmapRec4ub( 0, 10, 20, 0);
3606 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3607 fglInternalFormat := GL_RGB10;
3608 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3611 procedure TfdBGR16us3.SetValues;
3613 inherited SetValues;
3614 fBitsPerPixel := 48;
3615 fFormat := tfBGR16us3;
3616 fWithAlpha := tfBGRA16us4;
3617 fWithoutAlpha := tfBGR16us3;
3618 fOpenGLFormat := tfBGR16us3;
3619 fRGBInverted := tfRGB16us3;
3620 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
3621 fShift := glBitmapRec4ub(32, 16, 0, 0);
3622 fglFormat := GL_BGR;
3623 fglInternalFormat := GL_RGB16;
3624 fglDataFormat := GL_UNSIGNED_SHORT;
3627 procedure TfdBGRA4us1.SetValues;
3629 inherited SetValues;
3630 fBitsPerPixel := 16;
3631 fFormat := tfBGRA4us1;
3632 fWithAlpha := tfBGRA4us1;
3633 fWithoutAlpha := tfBGRX4us1;
3634 fOpenGLFormat := tfBGRA4us1;
3635 fRGBInverted := tfRGBA4us1;
3636 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3637 fShift := glBitmapRec4ub( 4, 8, 12, 0);
3638 fglFormat := GL_BGRA;
3639 fglInternalFormat := GL_RGBA4;
3640 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3643 procedure TfdABGR4us1.SetValues;
3645 inherited SetValues;
3646 fBitsPerPixel := 16;
3647 fFormat := tfABGR4us1;
3648 fWithAlpha := tfABGR4us1;
3649 fWithoutAlpha := tfXBGR4us1;
3650 fOpenGLFormat := tfABGR4us1;
3651 fRGBInverted := tfARGB4us1;
3652 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3653 fShift := glBitmapRec4ub( 0, 4, 8, 12);
3654 fglFormat := GL_RGBA;
3655 fglInternalFormat := GL_RGBA4;
3656 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3659 procedure TfdBGR5A1us1.SetValues;
3661 inherited SetValues;
3662 fBitsPerPixel := 16;
3663 fFormat := tfBGR5A1us1;
3664 fWithAlpha := tfBGR5A1us1;
3665 fWithoutAlpha := tfBGR5X1us1;
3666 fOpenGLFormat := tfBGR5A1us1;
3667 fRGBInverted := tfRGB5A1us1;
3668 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3669 fShift := glBitmapRec4ub( 1, 6, 11, 0);
3670 fglFormat := GL_BGRA;
3671 fglInternalFormat := GL_RGB5_A1;
3672 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3675 procedure TfdA1BGR5us1.SetValues;
3677 inherited SetValues;
3678 fBitsPerPixel := 16;
3679 fFormat := tfA1BGR5us1;
3680 fWithAlpha := tfA1BGR5us1;
3681 fWithoutAlpha := tfX1BGR5us1;
3682 fOpenGLFormat := tfA1BGR5us1;
3683 fRGBInverted := tfA1RGB5us1;
3684 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3685 fShift := glBitmapRec4ub( 0, 5, 10, 15);
3686 fglFormat := GL_RGBA;
3687 fglInternalFormat := GL_RGB5_A1;
3688 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3691 procedure TfdBGRA8ui1.SetValues;
3693 inherited SetValues;
3694 fBitsPerPixel := 32;
3695 fFormat := tfBGRA8ui1;
3696 fWithAlpha := tfBGRA8ui1;
3697 fWithoutAlpha := tfBGRX8ui1;
3698 fOpenGLFormat := tfBGRA8ui1;
3699 fRGBInverted := tfRGBA8ui1;
3700 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3701 fShift := glBitmapRec4ub( 8, 16, 24, 0);
3702 fglFormat := GL_BGRA;
3703 fglInternalFormat := GL_RGBA8;
3704 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3707 procedure TfdABGR8ui1.SetValues;
3709 inherited SetValues;
3710 fBitsPerPixel := 32;
3711 fFormat := tfABGR8ui1;
3712 fWithAlpha := tfABGR8ui1;
3713 fWithoutAlpha := tfXBGR8ui1;
3714 fOpenGLFormat := tfABGR8ui1;
3715 fRGBInverted := tfARGB8ui1;
3716 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3717 fShift := glBitmapRec4ub( 0, 8, 16, 24);
3718 fglFormat := GL_RGBA;
3719 fglInternalFormat := GL_RGBA8;
3720 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3723 procedure TfdBGRA8ub4.SetValues;
3725 inherited SetValues;
3726 fBitsPerPixel := 32;
3727 fFormat := tfBGRA8ub4;
3728 fWithAlpha := tfBGRA8ub4;
3729 fWithoutAlpha := tfBGR8ub3;
3730 fOpenGLFormat := tfBGRA8ub4;
3731 fRGBInverted := tfRGBA8ub4;
3732 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3733 fShift := glBitmapRec4ub(16, 8, 0, 24);
3734 fglFormat := GL_BGRA;
3735 fglInternalFormat := GL_RGBA8;
3736 fglDataFormat := GL_UNSIGNED_BYTE;
3739 procedure TfdBGR10A2ui1.SetValues;
3741 inherited SetValues;
3742 fBitsPerPixel := 32;
3743 fFormat := tfBGR10A2ui1;
3744 fWithAlpha := tfBGR10A2ui1;
3745 fWithoutAlpha := tfBGR10X2ui1;
3746 fOpenGLFormat := tfBGR10A2ui1;
3747 fRGBInverted := tfRGB10A2ui1;
3748 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3749 fShift := glBitmapRec4ub( 2, 12, 22, 0);
3750 fglFormat := GL_BGRA;
3751 fglInternalFormat := GL_RGB10_A2;
3752 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3755 procedure TfdA2BGR10ui1.SetValues;
3757 inherited SetValues;
3758 fBitsPerPixel := 32;
3759 fFormat := tfA2BGR10ui1;
3760 fWithAlpha := tfA2BGR10ui1;
3761 fWithoutAlpha := tfX2BGR10ui1;
3762 fOpenGLFormat := tfA2BGR10ui1;
3763 fRGBInverted := tfA2RGB10ui1;
3764 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3765 fShift := glBitmapRec4ub( 0, 10, 20, 30);
3766 fglFormat := GL_RGBA;
3767 fglInternalFormat := GL_RGB10_A2;
3768 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3771 procedure TfdBGRA16us4.SetValues;
3773 inherited SetValues;
3774 fBitsPerPixel := 64;
3775 fFormat := tfBGRA16us4;
3776 fWithAlpha := tfBGRA16us4;
3777 fWithoutAlpha := tfBGR16us3;
3778 fOpenGLFormat := tfBGRA16us4;
3779 fRGBInverted := tfRGBA16us4;
3780 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3781 fShift := glBitmapRec4ub(32, 16, 0, 48);
3782 fglFormat := GL_BGRA;
3783 fglInternalFormat := GL_RGBA16;
3784 fglDataFormat := GL_UNSIGNED_SHORT;
3787 procedure TfdDepth16us1.SetValues;
3789 inherited SetValues;
3790 fBitsPerPixel := 16;
3791 fFormat := tfDepth16us1;
3792 fWithoutAlpha := tfDepth16us1;
3793 fOpenGLFormat := tfDepth16us1;
3794 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3795 fShift := glBitmapRec4ub( 0, 0, 0, 0);
3796 fglFormat := GL_DEPTH_COMPONENT;
3797 fglInternalFormat := GL_DEPTH_COMPONENT16;
3798 fglDataFormat := GL_UNSIGNED_SHORT;
3801 procedure TfdDepth24ui1.SetValues;
3803 inherited SetValues;
3804 fBitsPerPixel := 32;
3805 fFormat := tfDepth24ui1;
3806 fWithoutAlpha := tfDepth24ui1;
3807 fOpenGLFormat := tfDepth24ui1;
3808 fPrecision := glBitmapRec4ub(32, 32, 32, 32);
3809 fShift := glBitmapRec4ub( 0, 0, 0, 0);
3810 fglFormat := GL_DEPTH_COMPONENT;
3811 fglInternalFormat := GL_DEPTH_COMPONENT24;
3812 fglDataFormat := GL_UNSIGNED_INT;
3815 procedure TfdDepth32ui1.SetValues;
3817 inherited SetValues;
3818 fBitsPerPixel := 32;
3819 fFormat := tfDepth32ui1;
3820 fWithoutAlpha := tfDepth32ui1;
3821 fOpenGLFormat := tfDepth32ui1;
3822 fPrecision := glBitmapRec4ub(32, 32, 32, 32);
3823 fShift := glBitmapRec4ub( 0, 0, 0, 0);
3824 fglFormat := GL_DEPTH_COMPONENT;
3825 fglInternalFormat := GL_DEPTH_COMPONENT32;
3826 fglDataFormat := GL_UNSIGNED_INT;
3829 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3830 //TfdS3tcDtx1RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3831 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3832 procedure TfdS3tcDtx1RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3834 raise EglBitmap.Create('mapping for compressed formats is not supported');
3837 procedure TfdS3tcDtx1RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3839 raise EglBitmap.Create('mapping for compressed formats is not supported');
3842 procedure TfdS3tcDtx1RGBA.SetValues;
3844 inherited SetValues;
3845 fFormat := tfS3tcDtx1RGBA;
3846 fWithAlpha := tfS3tcDtx1RGBA;
3847 fOpenGLFormat := tfS3tcDtx1RGBA;
3848 fUncompressed := tfRGB5A1us1;
3850 fIsCompressed := true;
3851 fglFormat := GL_COMPRESSED_RGBA;
3852 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
3853 fglDataFormat := GL_UNSIGNED_BYTE;
3856 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3857 //TfdS3tcDtx3RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3858 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3859 procedure TfdS3tcDtx3RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3861 raise EglBitmap.Create('mapping for compressed formats is not supported');
3864 procedure TfdS3tcDtx3RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3866 raise EglBitmap.Create('mapping for compressed formats is not supported');
3869 procedure TfdS3tcDtx3RGBA.SetValues;
3871 inherited SetValues;
3872 fFormat := tfS3tcDtx3RGBA;
3873 fWithAlpha := tfS3tcDtx3RGBA;
3874 fOpenGLFormat := tfS3tcDtx3RGBA;
3875 fUncompressed := tfRGBA8ub4;
3877 fIsCompressed := true;
3878 fglFormat := GL_COMPRESSED_RGBA;
3879 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
3880 fglDataFormat := GL_UNSIGNED_BYTE;
3883 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3884 //TfdS3tcDtx5RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3885 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3886 procedure TfdS3tcDtx5RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3888 raise EglBitmap.Create('mapping for compressed formats is not supported');
3891 procedure TfdS3tcDtx5RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3893 raise EglBitmap.Create('mapping for compressed formats is not supported');
3896 procedure TfdS3tcDtx5RGBA.SetValues;
3898 inherited SetValues;
3899 fFormat := tfS3tcDtx3RGBA;
3900 fWithAlpha := tfS3tcDtx3RGBA;
3901 fOpenGLFormat := tfS3tcDtx3RGBA;
3902 fUncompressed := tfRGBA8ub4;
3904 fIsCompressed := true;
3905 fglFormat := GL_COMPRESSED_RGBA;
3906 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
3907 fglDataFormat := GL_UNSIGNED_BYTE;
3910 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3911 //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3912 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3913 function TglBitmapFormatDescriptor.GetHasRed: Boolean;
3915 result := (fPrecision.r > 0);
3918 function TglBitmapFormatDescriptor.GetHasGreen: Boolean;
3920 result := (fPrecision.g > 0);
3923 function TglBitmapFormatDescriptor.GetHasBlue: Boolean;
3925 result := (fPrecision.b > 0);
3928 function TglBitmapFormatDescriptor.GetHasAlpha: Boolean;
3930 result := (fPrecision.a > 0);
3933 function TglBitmapFormatDescriptor.GetHasColor: Boolean;
3935 result := HasRed or HasGreen or HasBlue;
3938 function TglBitmapFormatDescriptor.GetIsGrayscale: Boolean;
3940 result := (Mask.r = Mask.g) and (Mask.g = Mask.b) and (Mask.r > 0);
3943 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3944 procedure TglBitmapFormatDescriptor.SetValues;
3947 fWithAlpha := tfEmpty;
3948 fWithoutAlpha := tfEmpty;
3949 fOpenGLFormat := tfEmpty;
3950 fRGBInverted := tfEmpty;
3951 fUncompressed := tfEmpty;
3954 fIsCompressed := false;
3957 fglInternalFormat := 0;
3960 FillChar(fPrecision, 0, SizeOf(fPrecision));
3961 FillChar(fShift, 0, SizeOf(fShift));
3964 procedure TglBitmapFormatDescriptor.CalcValues;
3968 fBytesPerPixel := fBitsPerPixel / 8;
3970 for i := 0 to 3 do begin
3971 if (fPrecision.arr[i] > 0) then
3973 fRange.arr[i] := (1 shl fPrecision.arr[i]) - 1;
3974 fMask.arr[i] := fRange.arr[i] shl fShift.arr[i];
3978 constructor TglBitmapFormatDescriptor.Create;
3985 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3986 class function TglBitmapFormatDescriptor.GetByFormat(const aInternalFormat: GLenum): TglBitmapFormatDescriptor;
3990 for f := Low(TglBitmapFormat) to High(TglBitmapFormat) do begin
3991 result := TFormatDescriptor.Get(f);
3992 if (result.glInternalFormat = aInternalFormat) then
3995 result := TFormatDescriptor.Get(tfEmpty);
3998 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3999 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4000 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4001 class procedure TFormatDescriptor.Init;
4003 if not Assigned(FormatDescriptorCS) then
4004 FormatDescriptorCS := TCriticalSection.Create;
4007 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4008 class function TFormatDescriptor.Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
4010 FormatDescriptorCS.Enter;
4012 result := FormatDescriptors[aFormat];
4013 if not Assigned(result) then begin
4014 result := FORMAT_DESCRIPTOR_CLASSES[aFormat].Create;
4015 FormatDescriptors[aFormat] := result;
4018 FormatDescriptorCS.Leave;
4022 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4023 class function TFormatDescriptor.GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
4025 result := Get(Get(aFormat).WithAlpha);
4028 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4029 class function TFormatDescriptor.GetFromMask(const aMask: TglBitmapRec4ul; const aBitCount: Integer): TFormatDescriptor;
4031 ft: TglBitmapFormat;
4033 // find matching format with OpenGL support
4034 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4036 if (result.MaskMatch(aMask)) and
4037 (result.glFormat <> 0) and
4038 (result.glInternalFormat <> 0) and
4039 ((aBitCount = 0) or (aBitCount = result.BitsPerPixel))
4044 // find matching format without OpenGL Support
4045 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4047 if result.MaskMatch(aMask) and ((aBitCount = 0) or (aBitCount = result.BitsPerPixel)) then
4051 result := TFormatDescriptor.Get(tfEmpty);
4054 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4055 class function TFormatDescriptor.GetFromPrecShift(const aPrec, aShift: TglBitmapRec4ub; const aBitCount: Integer): TFormatDescriptor;
4057 ft: TglBitmapFormat;
4059 // find matching format with OpenGL support
4060 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4062 if glBitmapRec4ubCompare(result.Shift, aShift) and
4063 glBitmapRec4ubCompare(result.Precision, aPrec) and
4064 (result.glFormat <> 0) and
4065 (result.glInternalFormat <> 0) and
4066 ((aBitCount = 0) or (aBitCount = result.BitsPerPixel))
4071 // find matching format without OpenGL Support
4072 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4074 if glBitmapRec4ubCompare(result.Shift, aShift) and
4075 glBitmapRec4ubCompare(result.Precision, aPrec) and
4076 ((aBitCount = 0) or (aBitCount = result.BitsPerPixel)) then
4080 result := TFormatDescriptor.Get(tfEmpty);
4083 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4084 class procedure TFormatDescriptor.Clear;
4088 FormatDescriptorCS.Enter;
4090 for f := low(FormatDescriptors) to high(FormatDescriptors) do
4091 FreeAndNil(FormatDescriptors[f]);
4093 FormatDescriptorCS.Leave;
4097 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4098 class procedure TFormatDescriptor.Finalize;
4101 FreeAndNil(FormatDescriptorCS);
4104 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4105 //TBitfieldFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4106 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4107 procedure TbmpBitfieldFormat.SetValues(const aBPP: Integer; aMask: TglBitmapRec4ul);
4111 for i := 0 to 3 do begin
4113 while (aMask.arr[i] > 0) and (aMask.arr[i] and 1 > 0) do begin
4114 aMask.arr[i] := aMask.arr[i] shr 1;
4117 fPrecision.arr[i] := CountSetBits(aMask.arr[i]);
4122 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4123 procedure TbmpBitfieldFormat.SetValues(const aBBP: Integer; const aPrec, aShift: TglBitmapRec4ub);
4125 fBitsPerPixel := aBBP;
4126 fPrecision := aPrec;
4131 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4132 procedure TbmpBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4137 ((aPixel.Data.r and Range.r) shl Shift.r) or
4138 ((aPixel.Data.g and Range.g) shl Shift.g) or
4139 ((aPixel.Data.b and Range.b) shl Shift.b) or
4140 ((aPixel.Data.a and Range.a) shl Shift.a);
4141 case BitsPerPixel of
4143 16: PWord(aData)^ := data;
4144 32: PCardinal(aData)^ := data;
4145 64: PQWord(aData)^ := data;
4147 raise EglBitmap.CreateFmt('invalid pixel size: %d', [BitsPerPixel]);
4149 inc(aData, Round(BytesPerPixel));
4152 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4153 procedure TbmpBitfieldFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4158 case BitsPerPixel of
4160 16: data := PWord(aData)^;
4161 32: data := PCardinal(aData)^;
4162 64: data := PQWord(aData)^;
4164 raise EglBitmap.CreateFmt('invalid pixel size: %d', [BitsPerPixel]);
4167 aPixel.Data.arr[i] := (data shr fShift.arr[i]) and Range.arr[i];
4168 inc(aData, Round(BytesPerPixel));
4171 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4172 //TColorTableFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4173 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4174 procedure TbmpColorTableFormat.SetValues;
4176 inherited SetValues;
4177 fShift := glBitmapRec4ub(8, 8, 8, 0);
4180 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4181 procedure TbmpColorTableFormat.SetValues(const aFormat: TglBitmapFormat; const aBPP: Integer; const aPrec, aShift: TglBitmapRec4ub);
4184 fBitsPerPixel := aBPP;
4185 fPrecision := aPrec;
4190 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4191 procedure TbmpColorTableFormat.CalcValues;
4193 inherited CalcValues;
4196 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4197 procedure TbmpColorTableFormat.CreateColorTable;
4201 SetLength(fColorTable, 256);
4202 if not HasColor then begin
4204 for i := 0 to High(fColorTable) do begin
4205 fColorTable[i].r := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4206 fColorTable[i].g := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4207 fColorTable[i].b := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4208 fColorTable[i].a := 0;
4212 for i := 0 to High(fColorTable) do begin
4213 fColorTable[i].r := Round(((i shr Shift.r) and Range.r) / Range.r * 255);
4214 fColorTable[i].g := Round(((i shr Shift.g) and Range.g) / Range.g * 255);
4215 fColorTable[i].b := Round(((i shr Shift.b) and Range.b) / Range.b * 255);
4216 fColorTable[i].a := 0;
4221 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4222 procedure TbmpColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4224 if (BitsPerPixel <> 8) then
4225 raise EglBitmapUnsupportedFormat.Create('color table are only supported for 8bit formats');
4226 if not HasColor then
4228 aData^ := aPixel.Data.a
4232 ((aPixel.Data.r and Range.r) shl Shift.r) or
4233 ((aPixel.Data.g and Range.g) shl Shift.g) or
4234 ((aPixel.Data.b and Range.b) shl Shift.b));
4238 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4239 procedure TbmpColorTableFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4241 if (BitsPerPixel <> 8) then
4242 raise EglBitmapUnsupportedFormat.Create('color table are only supported for 8bit formats');
4243 with fColorTable[aData^] do begin
4252 destructor TbmpColorTableFormat.Destroy;
4254 SetLength(fColorTable, 0);
4258 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4259 //TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4260 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4261 procedure glBitmapConvertPixel(var aPixel: TglBitmapPixelData; const aSourceFD, aDestFD: TFormatDescriptor);
4265 for i := 0 to 3 do begin
4266 if (aSourceFD.Range.arr[i] <> aDestFD.Range.arr[i]) then begin
4267 if (aSourceFD.Range.arr[i] > 0) then
4268 aPixel.Data.arr[i] := Round(aPixel.Data.arr[i] / aSourceFD.Range.arr[i] * aDestFD.Range.arr[i])
4270 aPixel.Data.arr[i] := 0;
4275 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4276 procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
4278 with aFuncRec do begin
4279 if (Source.Range.r > 0) then
4280 Dest.Data.r := Source.Data.r;
4281 if (Source.Range.g > 0) then
4282 Dest.Data.g := Source.Data.g;
4283 if (Source.Range.b > 0) then
4284 Dest.Data.b := Source.Data.b;
4285 if (Source.Range.a > 0) then
4286 Dest.Data.a := Source.Data.a;
4290 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4291 procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
4295 with aFuncRec do begin
4297 if (Source.Range.arr[i] > 0) then
4298 Dest.Data.arr[i] := Round(Dest.Range.arr[i] * Source.Data.arr[i] / Source.Range.arr[i]);
4303 TShiftData = packed record
4305 0: (r, g, b, a: SmallInt);
4306 1: (arr: array[0..3] of SmallInt);
4308 PShiftData = ^TShiftData;
4310 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4311 procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
4317 if (Source.Range.arr[i] > 0) then
4318 Dest.Data.arr[i] := Source.Data.arr[i] shr PShiftData(Args)^.arr[i];
4321 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4322 procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
4324 with aFuncRec do begin
4325 Dest.Data := Source.Data;
4326 if ({%H-}PtrUInt(Args) and $1 > 0) then begin
4327 Dest.Data.r := Dest.Data.r xor Dest.Range.r;
4328 Dest.Data.g := Dest.Data.g xor Dest.Range.g;
4329 Dest.Data.b := Dest.Data.b xor Dest.Range.b;
4331 if ({%H-}PtrUInt(Args) and $2 > 0) then begin
4332 Dest.Data.a := Dest.Data.a xor Dest.Range.a;
4337 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4338 procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
4342 with aFuncRec do begin
4344 Dest.Data.arr[i] := PglBitmapPixelData(Args)^.Data.arr[i];
4348 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4349 procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4353 with FuncRec do begin
4354 if (FuncRec.Args = nil) then begin //source has no alpha
4356 Source.Data.r / Source.Range.r * ALPHA_WEIGHT_R +
4357 Source.Data.g / Source.Range.g * ALPHA_WEIGHT_G +
4358 Source.Data.b / Source.Range.b * ALPHA_WEIGHT_B;
4359 Dest.Data.a := Round(Dest.Range.a * Temp);
4361 Dest.Data.a := Round(Source.Data.a / Source.Range.a * Dest.Range.a);
4365 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4366 procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4368 PglBitmapPixelData = ^TglBitmapPixelData;
4370 with FuncRec do begin
4371 Dest.Data.r := Source.Data.r;
4372 Dest.Data.g := Source.Data.g;
4373 Dest.Data.b := Source.Data.b;
4375 with PglBitmapPixelData(Args)^ do
4376 if ((Dest.Data.r <= Data.r) and (Dest.Data.r >= Range.r) and
4377 (Dest.Data.g <= Data.g) and (Dest.Data.g >= Range.g) and
4378 (Dest.Data.b <= Data.b) and (Dest.Data.b >= Range.b)) then
4381 Dest.Data.a := Dest.Range.a;
4385 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4386 procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4388 with FuncRec do begin
4389 Dest.Data.r := Source.Data.r;
4390 Dest.Data.g := Source.Data.g;
4391 Dest.Data.b := Source.Data.b;
4392 Dest.Data.a := PCardinal(Args)^;
4396 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4397 procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
4400 TRGBPix = array [0..2] of byte;
4404 while aWidth > 0 do begin
4405 Temp := PRGBPix(aData)^[0];
4406 PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
4407 PRGBPix(aData)^[2] := Temp;
4417 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4418 //TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4419 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4420 function TglBitmap.GetFormatDesc: TglBitmapFormatDescriptor;
4422 result := TFormatDescriptor.Get(Format);
4425 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4426 function TglBitmap.GetWidth: Integer;
4428 if (ffX in fDimension.Fields) then
4429 result := fDimension.X
4434 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4435 function TglBitmap.GetHeight: Integer;
4437 if (ffY in fDimension.Fields) then
4438 result := fDimension.Y
4443 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4444 function TglBitmap.GetFileWidth: Integer;
4446 result := Max(1, Width);
4449 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4450 function TglBitmap.GetFileHeight: Integer;
4452 result := Max(1, Height);
4455 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4456 procedure TglBitmap.SetCustomData(const aValue: Pointer);
4458 if fCustomData = aValue then
4460 fCustomData := aValue;
4463 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4464 procedure TglBitmap.SetCustomName(const aValue: String);
4466 if fCustomName = aValue then
4468 fCustomName := aValue;
4471 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4472 procedure TglBitmap.SetCustomNameW(const aValue: WideString);
4474 if fCustomNameW = aValue then
4476 fCustomNameW := aValue;
4479 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4480 procedure TglBitmap.SetFreeDataOnDestroy(const aValue: Boolean);
4482 if fFreeDataOnDestroy = aValue then
4484 fFreeDataOnDestroy := aValue;
4487 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4488 procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
4490 if fDeleteTextureOnFree = aValue then
4492 fDeleteTextureOnFree := aValue;
4495 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4496 procedure TglBitmap.SetFormat(const aValue: TglBitmapFormat);
4498 if fFormat = aValue then
4500 if TFormatDescriptor.Get(Format).BitsPerPixel <> TFormatDescriptor.Get(aValue).BitsPerPixel then
4501 raise EglBitmapUnsupportedFormat.Create(Format);
4502 SetDataPointer(fData, aValue, Width, Height); //be careful, Data could be freed by this method
4505 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4506 procedure TglBitmap.SetFreeDataAfterGenTexture(const aValue: Boolean);
4508 if fFreeDataAfterGenTexture = aValue then
4510 fFreeDataAfterGenTexture := aValue;
4513 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4514 procedure TglBitmap.SetID(const aValue: Cardinal);
4516 if fID = aValue then
4521 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4522 procedure TglBitmap.SetMipMap(const aValue: TglBitmapMipMap);
4524 if fMipMap = aValue then
4529 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4530 procedure TglBitmap.SetTarget(const aValue: Cardinal);
4532 if fTarget = aValue then
4537 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4538 procedure TglBitmap.SetAnisotropic(const aValue: Integer);
4540 MaxAnisotropic: Integer;
4542 fAnisotropic := aValue;
4543 if (ID > 0) then begin
4544 if GL_EXT_texture_filter_anisotropic then begin
4545 if fAnisotropic > 0 then begin
4547 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
4548 if aValue > MaxAnisotropic then
4549 fAnisotropic := MaxAnisotropic;
4550 glTexParameteri(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, fAnisotropic);
4558 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4559 procedure TglBitmap.CreateID;
4562 glDeleteTextures(1, @fID);
4563 glGenTextures(1, @fID);
4567 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4568 procedure TglBitmap.SetupParameters(out aBuildWithGlu: Boolean);
4570 // Set Up Parameters
4571 SetWrap(fWrapS, fWrapT, fWrapR);
4572 SetFilter(fFilterMin, fFilterMag);
4573 SetAnisotropic(fAnisotropic);
4574 SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
4576 if (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
4577 SetSwizzle(fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
4579 // Mip Maps Generation Mode
4580 aBuildWithGlu := false;
4581 if (MipMap = mmMipmap) then begin
4582 if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
4583 glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
4585 aBuildWithGlu := true;
4586 end else if (MipMap = mmMipmapGlu) then
4587 aBuildWithGlu := true;
4590 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4591 procedure TglBitmap.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
4592 const aWidth: Integer; const aHeight: Integer);
4596 if (Data <> aData) then begin
4597 if (Assigned(Data)) then
4602 if not Assigned(fData) then begin
4606 FillChar(fDimension, SizeOf(fDimension), 0);
4607 if aWidth <> -1 then begin
4608 fDimension.Fields := fDimension.Fields + [ffX];
4609 fDimension.X := aWidth;
4612 if aHeight <> -1 then begin
4613 fDimension.Fields := fDimension.Fields + [ffY];
4614 fDimension.Y := aHeight;
4617 s := TFormatDescriptor.Get(aFormat).BytesPerPixel;
4619 fPixelSize := Ceil(s);
4620 fRowSize := Ceil(s * aWidth);
4624 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4625 function TglBitmap.FlipHorz: Boolean;
4630 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4631 function TglBitmap.FlipVert: Boolean;
4636 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4637 //TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4638 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4639 procedure TglBitmap.AfterConstruction;
4641 inherited AfterConstruction;
4645 fIsResident := false;
4647 fMipMap := glBitmapDefaultMipmap;
4648 fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
4649 fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
4651 glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
4652 glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
4653 glBitmapGetDefaultSwizzle (fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
4656 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4657 procedure TglBitmap.BeforeDestruction;
4661 if fFreeDataOnDestroy then begin
4663 SetDataPointer(NewData, tfEmpty); //be careful, Data could be freed by this method
4665 if (fID > 0) and fDeleteTextureOnFree then
4666 glDeleteTextures(1, @fID);
4667 inherited BeforeDestruction;
4670 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4671 procedure TglBitmap.PrepareResType(var aResource: String; var aResType: PChar);
4675 if not Assigned(aResType) then begin
4676 TempPos := Pos('.', aResource);
4677 aResType := PChar(UpperCase(Copy(aResource, TempPos + 1, Length(aResource) - TempPos)));
4678 aResource := UpperCase(Copy(aResource, 0, TempPos -1));
4682 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4683 procedure TglBitmap.LoadFromFile(const aFilename: String);
4687 if not FileExists(aFilename) then
4688 raise EglBitmap.Create('file does not exist: ' + aFilename);
4689 fFilename := aFilename;
4690 fs := TFileStream.Create(fFilename, fmOpenRead);
4699 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4700 procedure TglBitmap.LoadFromStream(const aStream: TStream);
4702 {$IFDEF GLB_SUPPORT_PNG_READ}
4703 if not LoadPNG(aStream) then
4705 {$IFDEF GLB_SUPPORT_JPEG_READ}
4706 if not LoadJPEG(aStream) then
4708 if not LoadDDS(aStream) then
4709 if not LoadTGA(aStream) then
4710 if not LoadBMP(aStream) then
4711 if not LoadRAW(aStream) then
4712 raise EglBitmap.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
4715 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4716 procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
4717 const aFormat: TglBitmapFormat; const aArgs: Pointer);
4722 size := TFormatDescriptor.Get(aFormat).GetSize(aSize);
4723 GetMem(tmpData, size);
4725 FillChar(tmpData^, size, #$FF);
4726 SetDataPointer(tmpData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
4728 if Assigned(tmpData) then
4732 AddFunc(Self, aFunc, false, aFormat, aArgs);
4735 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4736 procedure TglBitmap.LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar);
4738 rs: TResourceStream;
4740 PrepareResType(aResource, aResType);
4741 rs := TResourceStream.Create(aInstance, aResource, aResType);
4749 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4750 procedure TglBitmap.LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
4752 rs: TResourceStream;
4754 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
4762 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4763 procedure TglBitmap.SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
4767 fs := TFileStream.Create(aFileName, fmCreate);
4770 SaveToStream(fs, aFileType);
4776 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4777 procedure TglBitmap.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
4780 {$IFDEF GLB_SUPPORT_PNG_WRITE}
4781 ftPNG: SavePNG(aStream);
4783 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
4784 ftJPEG: SaveJPEG(aStream);
4786 ftDDS: SaveDDS(aStream);
4787 ftTGA: SaveTGA(aStream);
4788 ftBMP: SaveBMP(aStream);
4789 ftRAW: SaveRAW(aStream);
4793 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4794 function TglBitmap.AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer): Boolean;
4796 result := AddFunc(Self, aFunc, aCreateTemp, Format, aArgs);
4799 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4800 function TglBitmap.AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
4801 const aFormat: TglBitmapFormat; const aArgs: Pointer): Boolean;
4803 DestData, TmpData, SourceData: pByte;
4804 TempHeight, TempWidth: Integer;
4805 SourceFD, DestFD: TFormatDescriptor;
4806 SourceMD, DestMD: Pointer;
4808 FuncRec: TglBitmapFunctionRec;
4810 Assert(Assigned(Data));
4811 Assert(Assigned(aSource));
4812 Assert(Assigned(aSource.Data));
4815 if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
4816 SourceFD := TFormatDescriptor.Get(aSource.Format);
4817 DestFD := TFormatDescriptor.Get(aFormat);
4819 if (SourceFD.IsCompressed) then
4820 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', SourceFD.Format);
4821 if (DestFD.IsCompressed) then
4822 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', DestFD.Format);
4824 // inkompatible Formats so CreateTemp
4825 if (SourceFD.BitsPerPixel <> DestFD.BitsPerPixel) then
4826 aCreateTemp := true;
4829 TempHeight := Max(1, aSource.Height);
4830 TempWidth := Max(1, aSource.Width);
4832 FuncRec.Sender := Self;
4833 FuncRec.Args := aArgs;
4836 if aCreateTemp then begin
4837 GetMem(TmpData, DestFD.GetSize(TempWidth, TempHeight));
4838 DestData := TmpData;
4843 SourceFD.PreparePixel(FuncRec.Source);
4844 DestFD.PreparePixel (FuncRec.Dest);
4846 SourceMD := SourceFD.CreateMappingData;
4847 DestMD := DestFD.CreateMappingData;
4849 FuncRec.Size := aSource.Dimension;
4850 FuncRec.Position.Fields := FuncRec.Size.Fields;
4853 SourceData := aSource.Data;
4854 FuncRec.Position.Y := 0;
4855 while FuncRec.Position.Y < TempHeight do begin
4856 FuncRec.Position.X := 0;
4857 while FuncRec.Position.X < TempWidth do begin
4858 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
4860 DestFD.Map(FuncRec.Dest, DestData, DestMD);
4861 inc(FuncRec.Position.X);
4863 inc(FuncRec.Position.Y);
4866 // Updating Image or InternalFormat
4868 SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height) //be careful, Data could be freed by this method
4869 else if (aFormat <> fFormat) then
4874 SourceFD.FreeMappingData(SourceMD);
4875 DestFD.FreeMappingData(DestMD);
4878 if aCreateTemp and Assigned(TmpData) then
4886 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4887 function TglBitmap.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
4889 Row, RowSize: Integer;
4890 SourceData, TmpData: PByte;
4892 FormatDesc: TFormatDescriptor;
4894 function GetRowPointer(Row: Integer): pByte;
4896 result := aSurface.pixels;
4897 Inc(result, Row * RowSize);
4903 FormatDesc := TFormatDescriptor.Get(Format);
4904 if FormatDesc.IsCompressed then
4905 raise EglBitmapUnsupportedFormat.Create(Format);
4907 if Assigned(Data) then begin
4908 case Trunc(FormatDesc.PixelSize) of
4914 raise EglBitmapUnsupportedFormat.Create(Format);
4917 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
4918 FormatDesc.RedMask, FormatDesc.GreenMask, FormatDesc.BlueMask, FormatDesc.AlphaMask);
4920 RowSize := FormatDesc.GetSize(FileWidth, 1);
4922 for Row := 0 to FileHeight-1 do begin
4923 TmpData := GetRowPointer(Row);
4924 if Assigned(TmpData) then begin
4925 Move(SourceData^, TmpData^, RowSize);
4926 inc(SourceData, RowSize);
4933 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4934 function TglBitmap.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
4936 pSource, pData, pTempData: PByte;
4937 Row, RowSize, TempWidth, TempHeight: Integer;
4938 IntFormat: TglBitmapFormat;
4939 fd: TFormatDescriptor;
4940 Mask: TglBitmapMask;
4942 function GetRowPointer(Row: Integer): pByte;
4944 result := aSurface^.pixels;
4945 Inc(result, Row * RowSize);
4950 if (Assigned(aSurface)) then begin
4951 with aSurface^.format^ do begin
4956 IntFormat := TFormatDescriptor.GetFromMask(Mask).Format;
4957 if (IntFormat = tfEmpty) then
4958 raise EglBitmap.Create('AssignFromSurface - Invalid Pixelformat.');
4961 fd := TFormatDescriptor.Get(IntFormat);
4962 TempWidth := aSurface^.w;
4963 TempHeight := aSurface^.h;
4964 RowSize := fd.GetSize(TempWidth, 1);
4965 GetMem(pData, TempHeight * RowSize);
4968 for Row := 0 to TempHeight -1 do begin
4969 pSource := GetRowPointer(Row);
4970 if (Assigned(pSource)) then begin
4971 Move(pSource^, pTempData^, RowSize);
4972 Inc(pTempData, RowSize);
4975 SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
4978 if Assigned(pData) then
4985 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4986 function TglBitmap.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
4988 Row, Col, AlphaInterleave: Integer;
4989 pSource, pDest: PByte;
4991 function GetRowPointer(Row: Integer): pByte;
4993 result := aSurface.pixels;
4994 Inc(result, Row * Width);
4999 if Assigned(Data) then begin
5000 if Format in [tfAlpha8ub1, tfLuminance8Alpha8ub2, tfBGRA8ub4, tfRGBA8ub4] then begin
5001 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
5003 AlphaInterleave := 0;
5005 tfLuminance8Alpha8ub2:
5006 AlphaInterleave := 1;
5007 tfBGRA8ub4, tfRGBA8ub4:
5008 AlphaInterleave := 3;
5012 for Row := 0 to Height -1 do begin
5013 pDest := GetRowPointer(Row);
5014 if Assigned(pDest) then begin
5015 for Col := 0 to Width -1 do begin
5016 Inc(pSource, AlphaInterleave);
5028 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5029 function TglBitmap.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
5033 bmp := TglBitmap2D.Create;
5035 bmp.AssignFromSurface(aSurface);
5036 result := AddAlphaFromGlBitmap(bmp, aFunc, aArgs);
5044 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5045 function CreateGrayPalette: HPALETTE;
5050 GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
5052 Pal.palVersion := $300;
5053 Pal.palNumEntries := 256;
5055 for Idx := 0 to Pal.palNumEntries - 1 do begin
5056 Pal.palPalEntry[Idx].peRed := Idx;
5057 Pal.palPalEntry[Idx].peGreen := Idx;
5058 Pal.palPalEntry[Idx].peBlue := Idx;
5059 Pal.palPalEntry[Idx].peFlags := 0;
5061 Result := CreatePalette(Pal^);
5065 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5066 function TglBitmap.AssignToBitmap(const aBitmap: TBitmap): Boolean;
5069 pSource, pData: PByte;
5072 if Assigned(Data) then begin
5073 if Assigned(aBitmap) then begin
5074 aBitmap.Width := Width;
5075 aBitmap.Height := Height;
5078 tfAlpha8ub1, tfLuminance8ub1: begin
5079 aBitmap.PixelFormat := pf8bit;
5080 aBitmap.Palette := CreateGrayPalette;
5083 aBitmap.PixelFormat := pf15bit;
5085 aBitmap.PixelFormat := pf16bit;
5086 tfRGB8ub3, tfBGR8ub3:
5087 aBitmap.PixelFormat := pf24bit;
5088 tfRGBA8ub4, tfBGRA8ub4:
5089 aBitmap.PixelFormat := pf32bit;
5091 raise EglBitmap.Create('AssignToBitmap - Invalid Pixelformat.');
5095 for Row := 0 to FileHeight -1 do begin
5096 pData := aBitmap.Scanline[Row];
5097 Move(pSource^, pData^, fRowSize);
5098 Inc(pSource, fRowSize);
5099 if (Format in [tfRGB8ub3, tfRGBA8ub4]) then // swap RGB(A) to BGR(A)
5100 SwapRGB(pData, FileWidth, Format = tfRGBA8ub4);
5107 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5108 function TglBitmap.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
5110 pSource, pData, pTempData: PByte;
5111 Row, RowSize, TempWidth, TempHeight: Integer;
5112 IntFormat: TglBitmapFormat;
5116 if (Assigned(aBitmap)) then begin
5117 case aBitmap.PixelFormat of
5119 IntFormat := tfLuminance8ub1;
5121 IntFormat := tfRGB5A1us1;
5123 IntFormat := tfR5G6B5us1;
5125 IntFormat := tfBGR8ub3;
5127 IntFormat := tfBGRA8ub4;
5129 raise EglBitmap.Create('AssignFromBitmap - Invalid Pixelformat.');
5132 TempWidth := aBitmap.Width;
5133 TempHeight := aBitmap.Height;
5134 RowSize := TFormatDescriptor.Get(IntFormat).GetSize(TempWidth, 1);
5135 GetMem(pData, TempHeight * RowSize);
5138 for Row := 0 to TempHeight -1 do begin
5139 pSource := aBitmap.Scanline[Row];
5140 if (Assigned(pSource)) then begin
5141 Move(pSource^, pTempData^, RowSize);
5142 Inc(pTempData, RowSize);
5145 SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
5148 if Assigned(pData) then
5155 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5156 function TglBitmap.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
5158 Row, Col, AlphaInterleave: Integer;
5159 pSource, pDest: PByte;
5163 if Assigned(Data) then begin
5164 if (Format in [tfAlpha8ub1, tfLuminance8Alpha8ub2, tfRGBA8ub4, tfBGRA8ub4]) then begin
5165 if Assigned(aBitmap) then begin
5166 aBitmap.PixelFormat := pf8bit;
5167 aBitmap.Palette := CreateGrayPalette;
5168 aBitmap.Width := Width;
5169 aBitmap.Height := Height;
5172 tfLuminance8Alpha8ub2:
5173 AlphaInterleave := 1;
5174 tfRGBA8ub4, tfBGRA8ub4:
5175 AlphaInterleave := 3;
5177 AlphaInterleave := 0;
5183 for Row := 0 to Height -1 do begin
5184 pDest := aBitmap.Scanline[Row];
5185 if Assigned(pDest) then begin
5186 for Col := 0 to Width -1 do begin
5187 Inc(pSource, AlphaInterleave);
5200 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5201 function TglBitmap.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5205 tex := TglBitmap2D.Create;
5207 tex.AssignFromBitmap(ABitmap);
5208 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5215 {$IFDEF GLB_LAZARUS}
5216 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5217 function TglBitmap.AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
5219 rid: TRawImageDescription;
5220 FormatDesc: TFormatDescriptor;
5222 if not Assigned(Data) then
5223 raise EglBitmap.Create('no pixel data assigned. load data before save');
5226 if not Assigned(aImage) or (Format = tfEmpty) then
5228 FormatDesc := TFormatDescriptor.Get(Format);
5229 if FormatDesc.IsCompressed then
5232 FillChar(rid{%H-}, SizeOf(rid), 0);
5233 if FormatDesc.IsGrayscale then
5234 rid.Format := ricfGray
5236 rid.Format := ricfRGBA;
5239 rid.Height := Height;
5240 rid.Depth := FormatDesc.BitsPerPixel;
5241 rid.BitOrder := riboBitsInOrder;
5242 rid.ByteOrder := riboLSBFirst;
5243 rid.LineOrder := riloTopToBottom;
5244 rid.LineEnd := rileTight;
5245 rid.BitsPerPixel := FormatDesc.BitsPerPixel;
5246 rid.RedPrec := CountSetBits(FormatDesc.Range.r);
5247 rid.GreenPrec := CountSetBits(FormatDesc.Range.g);
5248 rid.BluePrec := CountSetBits(FormatDesc.Range.b);
5249 rid.AlphaPrec := CountSetBits(FormatDesc.Range.a);
5250 rid.RedShift := FormatDesc.Shift.r;
5251 rid.GreenShift := FormatDesc.Shift.g;
5252 rid.BlueShift := FormatDesc.Shift.b;
5253 rid.AlphaShift := FormatDesc.Shift.a;
5255 rid.MaskBitsPerPixel := 0;
5256 rid.PaletteColorCount := 0;
5258 aImage.DataDescription := rid;
5261 if not Assigned(aImage.PixelData) then
5262 raise EglBitmap.Create('error while creating LazIntfImage');
5263 Move(Data^, aImage.PixelData^, FormatDesc.GetSize(Dimension));
5268 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5269 function TglBitmap.AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
5272 FormatDesc: TFormatDescriptor;
5276 Mask: TglBitmapRec4ul;
5278 procedure CopyConvert;
5280 bfFormat: TbmpBitfieldFormat;
5281 pSourceLine, pDestLine: PByte;
5282 pSourceMD, pDestMD: Pointer;
5283 Shift, Prec: TglBitmapRec4ub;
5285 pixel: TglBitmapPixelData;
5287 bfFormat := TbmpBitfieldFormat.Create;
5288 with aImage.DataDescription do begin
5290 Prec.g := GreenPrec;
5292 Prec.a := AlphaPrec;
5293 Shift.r := RedShift;
5294 Shift.g := GreenShift;
5295 Shift.b := BlueShift;
5296 Shift.a := AlphaShift;
5297 bfFormat.SetValues(BitsPerPixel, Prec, Shift);
5299 pSourceMD := bfFormat.CreateMappingData;
5300 pDestMD := FormatDesc.CreateMappingData;
5302 for y := 0 to aImage.Height-1 do begin
5303 pSourceLine := aImage.PixelData + y {%H-}* aImage.DataDescription.BytesPerLine;
5304 pDestLine := ImageData + y * Round(FormatDesc.BytesPerPixel * aImage.Width);
5305 for x := 0 to aImage.Width-1 do begin
5306 bfFormat.Unmap(pSourceLine, pixel, pSourceMD);
5307 FormatDesc.Map(pixel, pDestLine, pDestMD);
5311 FormatDesc.FreeMappingData(pDestMD);
5312 bfFormat.FreeMappingData(pSourceMD);
5319 if not Assigned(aImage) then
5322 with aImage.DataDescription do begin
5323 Mask.r := (QWord(1 shl RedPrec )-1) shl RedShift;
5324 Mask.g := (QWord(1 shl GreenPrec)-1) shl GreenShift;
5325 Mask.b := (QWord(1 shl BluePrec )-1) shl BlueShift;
5326 Mask.a := (QWord(1 shl AlphaPrec)-1) shl AlphaShift;
5328 FormatDesc := TFormatDescriptor.GetFromMask(Mask);
5329 f := FormatDesc.Format;
5330 if (f = tfEmpty) then
5334 (FormatDesc.BitsPerPixel = aImage.DataDescription.Depth) and
5335 (aImage.DataDescription.BitsPerPixel = aImage.DataDescription.Depth);
5337 ImageSize := FormatDesc.GetSize(aImage.Width, aImage.Height);
5338 ImageData := GetMem(ImageSize);
5341 Move(aImage.PixelData^, ImageData^, ImageSize)
5344 SetDataPointer(ImageData, f, aImage.Width, aImage.Height); //be careful, Data could be freed by this method
5346 if Assigned(ImageData) then
5354 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5355 function TglBitmap.AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
5357 rid: TRawImageDescription;
5358 FormatDesc: TFormatDescriptor;
5359 Pixel: TglBitmapPixelData;
5365 if not Assigned(aImage) or (Format = tfEmpty) then
5367 FormatDesc := TFormatDescriptor.Get(Format);
5368 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
5371 FillChar(rid{%H-}, SizeOf(rid), 0);
5372 rid.Format := ricfGray;
5374 rid.Height := Height;
5375 rid.Depth := CountSetBits(FormatDesc.Range.a);
5376 rid.BitOrder := riboBitsInOrder;
5377 rid.ByteOrder := riboLSBFirst;
5378 rid.LineOrder := riloTopToBottom;
5379 rid.LineEnd := rileTight;
5380 rid.BitsPerPixel := 8 * Ceil(rid.Depth / 8);
5381 rid.RedPrec := CountSetBits(FormatDesc.Range.a);
5386 rid.GreenShift := 0;
5388 rid.AlphaShift := 0;
5390 rid.MaskBitsPerPixel := 0;
5391 rid.PaletteColorCount := 0;
5393 aImage.DataDescription := rid;
5396 srcMD := FormatDesc.CreateMappingData;
5398 FormatDesc.PreparePixel(Pixel);
5400 dst := aImage.PixelData;
5401 for y := 0 to Height-1 do
5402 for x := 0 to Width-1 do begin
5403 FormatDesc.Unmap(src, Pixel, srcMD);
5404 case rid.BitsPerPixel of
5406 dst^ := Pixel.Data.a;
5410 PWord(dst)^ := Pixel.Data.a;
5414 PByteArray(dst)^[0] := PByteArray(@Pixel.Data.a)^[0];
5415 PByteArray(dst)^[1] := PByteArray(@Pixel.Data.a)^[1];
5416 PByteArray(dst)^[2] := PByteArray(@Pixel.Data.a)^[2];
5420 PCardinal(dst)^ := Pixel.Data.a;
5424 raise EglBitmapUnsupportedFormat.Create(Format);
5428 FormatDesc.FreeMappingData(srcMD);
5433 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5434 function TglBitmap.AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5438 tex := TglBitmap2D.Create;
5440 tex.AssignFromLazIntfImage(aImage);
5441 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5448 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5449 function TglBitmap.AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar;
5450 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5452 rs: TResourceStream;
5454 PrepareResType(aResource, aResType);
5455 rs := TResourceStream.Create(aInstance, aResource, aResType);
5457 result := AddAlphaFromStream(rs, aFunc, aArgs);
5463 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5464 function TglBitmap.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
5465 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5467 rs: TResourceStream;
5469 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
5471 result := AddAlphaFromStream(rs, aFunc, aArgs);
5477 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5478 function TglBitmap.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5480 if TFormatDescriptor.Get(Format).IsCompressed then
5481 raise EglBitmapUnsupportedFormat.Create(Format);
5482 result := AddFunc(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs);
5485 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5486 function TglBitmap.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5490 FS := TFileStream.Create(aFileName, fmOpenRead);
5492 result := AddAlphaFromStream(FS, aFunc, aArgs);
5498 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5499 function TglBitmap.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5503 tex := TglBitmap2D.Create(aStream);
5505 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5511 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5512 function TglBitmap.AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5514 DestData, DestData2, SourceData: pByte;
5515 TempHeight, TempWidth: Integer;
5516 SourceFD, DestFD: TFormatDescriptor;
5517 SourceMD, DestMD, DestMD2: Pointer;
5519 FuncRec: TglBitmapFunctionRec;
5523 Assert(Assigned(Data));
5524 Assert(Assigned(aBitmap));
5525 Assert(Assigned(aBitmap.Data));
5527 if ((aBitmap.Width = Width) and (aBitmap.Height = Height)) then begin
5528 result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
5530 SourceFD := TFormatDescriptor.Get(aBitmap.Format);
5531 DestFD := TFormatDescriptor.Get(Format);
5533 if not Assigned(aFunc) then begin
5534 aFunc := glBitmapAlphaFunc;
5535 FuncRec.Args := {%H-}Pointer(SourceFD.HasAlpha);
5537 FuncRec.Args := aArgs;
5540 TempHeight := aBitmap.FileHeight;
5541 TempWidth := aBitmap.FileWidth;
5543 FuncRec.Sender := Self;
5544 FuncRec.Size := Dimension;
5545 FuncRec.Position.Fields := FuncRec.Size.Fields;
5549 SourceData := aBitmap.Data;
5552 SourceFD.PreparePixel(FuncRec.Source);
5553 DestFD.PreparePixel (FuncRec.Dest);
5555 SourceMD := SourceFD.CreateMappingData;
5556 DestMD := DestFD.CreateMappingData;
5557 DestMD2 := DestFD.CreateMappingData;
5559 FuncRec.Position.Y := 0;
5560 while FuncRec.Position.Y < TempHeight do begin
5561 FuncRec.Position.X := 0;
5562 while FuncRec.Position.X < TempWidth do begin
5563 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
5564 DestFD.Unmap (DestData, FuncRec.Dest, DestMD);
5566 DestFD.Map(FuncRec.Dest, DestData2, DestMD2);
5567 inc(FuncRec.Position.X);
5569 inc(FuncRec.Position.Y);
5572 SourceFD.FreeMappingData(SourceMD);
5573 DestFD.FreeMappingData(DestMD);
5574 DestFD.FreeMappingData(DestMD2);
5579 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5580 function TglBitmap.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
5582 result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
5585 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5586 function TglBitmap.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
5588 PixelData: TglBitmapPixelData;
5590 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5591 result := AddAlphaFromColorKeyFloat(
5592 aRed / PixelData.Range.r,
5593 aGreen / PixelData.Range.g,
5594 aBlue / PixelData.Range.b,
5595 aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b)));
5598 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5599 function TglBitmap.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
5601 values: array[0..2] of Single;
5604 PixelData: TglBitmapPixelData;
5606 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5607 with PixelData do begin
5609 values[1] := aGreen;
5612 for i := 0 to 2 do begin
5613 tmp := Trunc(Range.arr[i] * aDeviation);
5614 Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp));
5615 Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp));
5620 result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, @PixelData);
5623 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5624 function TglBitmap.AddAlphaFromValue(const aAlpha: Byte): Boolean;
5626 result := AddAlphaFromValueFloat(aAlpha / $FF);
5629 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5630 function TglBitmap.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
5632 PixelData: TglBitmapPixelData;
5634 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5635 result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
5638 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5639 function TglBitmap.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
5641 PixelData: TglBitmapPixelData;
5643 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5645 Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
5646 result := AddAlphaFromFunc(glBitmapValueAlphaFunc, @PixelData.Data.a);
5649 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5650 function TglBitmap.RemoveAlpha: Boolean;
5652 FormatDesc: TFormatDescriptor;
5655 FormatDesc := TFormatDescriptor.Get(Format);
5656 if Assigned(Data) then begin
5657 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
5658 raise EglBitmapUnsupportedFormat.Create(Format);
5659 result := ConvertTo(FormatDesc.WithoutAlpha);
5663 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5664 function TglBitmap.Clone: TglBitmap;
5671 Temp := (ClassType.Create as TglBitmap);
5673 // copy texture data if assigned
5674 if Assigned(Data) then begin
5675 Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
5676 GetMem(TempPtr, Size);
5678 Move(Data^, TempPtr^, Size);
5679 Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
5681 if Assigned(TempPtr) then
5687 Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
5692 Temp.fTarget := Target;
5693 Temp.fFormat := Format;
5694 Temp.fMipMap := MipMap;
5695 Temp.fAnisotropic := Anisotropic;
5696 Temp.fBorderColor := fBorderColor;
5697 Temp.fDeleteTextureOnFree := DeleteTextureOnFree;
5698 Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
5699 Temp.fFilterMin := fFilterMin;
5700 Temp.fFilterMag := fFilterMag;
5701 Temp.fWrapS := fWrapS;
5702 Temp.fWrapT := fWrapT;
5703 Temp.fWrapR := fWrapR;
5704 Temp.fFilename := fFilename;
5705 Temp.fCustomName := fCustomName;
5706 Temp.fCustomNameW := fCustomNameW;
5707 Temp.fCustomData := fCustomData;
5716 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5717 function TglBitmap.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
5719 SourceFD, DestFD: TFormatDescriptor;
5720 SourcePD, DestPD: TglBitmapPixelData;
5721 ShiftData: TShiftData;
5723 function DataIsIdentical: Boolean;
5725 result := SourceFD.MaskMatch(DestFD.Mask);
5728 function CanCopyDirect: Boolean;
5731 ((SourcePD.Range.r = DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
5732 ((SourcePD.Range.g = DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
5733 ((SourcePD.Range.b = DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
5734 ((SourcePD.Range.a = DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
5737 function CanShift: Boolean;
5740 ((SourcePD.Range.r >= DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
5741 ((SourcePD.Range.g >= DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
5742 ((SourcePD.Range.b >= DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
5743 ((SourcePD.Range.a >= DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
5746 function GetShift(aSource, aDest: Cardinal) : ShortInt;
5749 while (aSource > aDest) and (aSource > 0) do begin
5751 aSource := aSource shr 1;
5756 if (aFormat <> fFormat) and (aFormat <> tfEmpty) then begin
5757 SourceFD := TFormatDescriptor.Get(Format);
5758 DestFD := TFormatDescriptor.Get(aFormat);
5760 if DataIsIdentical then begin
5766 SourceFD.PreparePixel(SourcePD);
5767 DestFD.PreparePixel (DestPD);
5769 if CanCopyDirect then
5770 result := AddFunc(Self, glBitmapConvertCopyFunc, false, aFormat)
5771 else if CanShift then begin
5772 ShiftData.r := GetShift(SourcePD.Range.r, DestPD.Range.r);
5773 ShiftData.g := GetShift(SourcePD.Range.g, DestPD.Range.g);
5774 ShiftData.b := GetShift(SourcePD.Range.b, DestPD.Range.b);
5775 ShiftData.a := GetShift(SourcePD.Range.a, DestPD.Range.a);
5776 result := AddFunc(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, @ShiftData);
5778 result := AddFunc(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
5783 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5784 procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
5786 if aUseRGB or aUseAlpha then
5787 AddFunc(glBitmapInvertFunc, false, {%H-}Pointer(
5788 ((Byte(aUseAlpha) and 1) shl 1) or
5789 (Byte(aUseRGB) and 1) ));
5792 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5793 procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
5795 fBorderColor[0] := aRed;
5796 fBorderColor[1] := aGreen;
5797 fBorderColor[2] := aBlue;
5798 fBorderColor[3] := aAlpha;
5799 if (ID > 0) then begin
5801 glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
5805 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5806 procedure TglBitmap.FreeData;
5811 SetDataPointer(TempPtr, tfEmpty); //be careful, Data could be freed by this method
5814 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5815 procedure TglBitmap.FillWithColor(const aRed, aGreen, aBlue: Byte;
5816 const aAlpha: Byte);
5818 FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
5821 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5822 procedure TglBitmap.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
5824 PixelData: TglBitmapPixelData;
5826 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5828 aRed / PixelData.Range.r,
5829 aGreen / PixelData.Range.g,
5830 aBlue / PixelData.Range.b,
5831 aAlpha / PixelData.Range.a);
5834 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5835 procedure TglBitmap.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
5837 PixelData: TglBitmapPixelData;
5839 TFormatDescriptor.Get(Format).PreparePixel(PixelData);
5840 with PixelData do begin
5841 Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed)));
5842 Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen)));
5843 Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue)));
5844 Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha)));
5846 AddFunc(glBitmapFillWithColorFunc, false, @PixelData);
5849 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5850 procedure TglBitmap.SetFilter(const aMin, aMag: GLenum);
5855 fFilterMin := GL_NEAREST;
5857 fFilterMin := GL_LINEAR;
5858 GL_NEAREST_MIPMAP_NEAREST:
5859 fFilterMin := GL_NEAREST_MIPMAP_NEAREST;
5860 GL_LINEAR_MIPMAP_NEAREST:
5861 fFilterMin := GL_LINEAR_MIPMAP_NEAREST;
5862 GL_NEAREST_MIPMAP_LINEAR:
5863 fFilterMin := GL_NEAREST_MIPMAP_LINEAR;
5864 GL_LINEAR_MIPMAP_LINEAR:
5865 fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
5867 raise EglBitmap.Create('SetFilter - Unknow MIN filter.');
5873 fFilterMag := GL_NEAREST;
5875 fFilterMag := GL_LINEAR;
5877 raise EglBitmap.Create('SetFilter - Unknow MAG filter.');
5881 if (ID > 0) then begin
5883 glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
5885 if (MipMap = mmNone) or (Target = GL_TEXTURE_RECTANGLE) then begin
5887 GL_NEAREST, GL_LINEAR:
5888 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
5889 GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR:
5890 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5891 GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR:
5892 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5895 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
5899 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5900 procedure TglBitmap.SetWrap(const S: GLenum; const T: GLenum; const R: GLenum);
5902 procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
5906 aTarget := GL_CLAMP;
5909 aTarget := GL_REPEAT;
5911 GL_CLAMP_TO_EDGE: begin
5912 if GL_VERSION_1_2 or GL_EXT_texture_edge_clamp then
5913 aTarget := GL_CLAMP_TO_EDGE
5915 aTarget := GL_CLAMP;
5918 GL_CLAMP_TO_BORDER: begin
5919 if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
5920 aTarget := GL_CLAMP_TO_BORDER
5922 aTarget := GL_CLAMP;
5925 GL_MIRRORED_REPEAT: begin
5926 if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
5927 aTarget := GL_MIRRORED_REPEAT
5929 raise EglBitmap.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
5932 raise EglBitmap.Create('SetWrap - Unknow Texturewrap');
5937 CheckAndSetWrap(S, fWrapS);
5938 CheckAndSetWrap(T, fWrapT);
5939 CheckAndSetWrap(R, fWrapR);
5941 if (ID > 0) then begin
5943 glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
5944 glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
5945 glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
5949 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5950 procedure TglBitmap.SetSwizzle(const r, g, b, a: GLenum);
5952 procedure CheckAndSetValue(const aValue: GLenum; const aIndex: Integer);
5954 if (aValue = GL_ZERO) or (aValue = GL_ONE) or (aValue = GL_ALPHA) or
5955 (aValue = GL_RED) or (aValue = GL_GREEN) or (aValue = GL_BLUE) then
5956 fSwizzle[aIndex] := aValue
5958 raise EglBitmap.Create('SetSwizzle - Unknow Swizle Value');
5962 if not (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
5963 raise EglBitmapNotSupported.Create('texture swizzle is not supported');
5964 CheckAndSetValue(r, 0);
5965 CheckAndSetValue(g, 1);
5966 CheckAndSetValue(b, 2);
5967 CheckAndSetValue(a, 3);
5969 if (ID > 0) then begin
5971 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_RGBA, PGLint(@fSwizzle[0]));
5975 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5976 procedure TglBitmap.Bind(const aEnableTextureUnit: Boolean);
5978 if aEnableTextureUnit then
5981 glBindTexture(Target, ID);
5984 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5985 procedure TglBitmap.Unbind(const aDisableTextureUnit: Boolean);
5987 if aDisableTextureUnit then
5989 glBindTexture(Target, 0);
5992 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5993 constructor TglBitmap.Create;
5995 if (ClassType = TglBitmap) then
5996 raise EglBitmap.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
5997 {$IFDEF GLB_NATIVE_OGL}
5998 glbReadOpenGLExtensions;
6001 fFormat := glBitmapGetDefaultFormat;
6002 fFreeDataOnDestroy := true;
6005 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6006 constructor TglBitmap.Create(const aFileName: String);
6009 LoadFromFile(aFileName);
6012 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6013 constructor TglBitmap.Create(const aStream: TStream);
6016 LoadFromStream(aStream);
6019 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6020 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; aData: PByte);
6025 if not Assigned(aData) then begin
6026 ImageSize := TFormatDescriptor.Get(aFormat).GetSize(aSize);
6027 GetMem(aData, ImageSize);
6029 FillChar(aData^, ImageSize, #$FF);
6030 SetDataPointer(aData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
6032 if Assigned(aData) then
6037 SetDataPointer(aData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
6038 fFreeDataOnDestroy := false;
6042 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6043 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer);
6046 LoadFromFunc(aSize, aFunc, aFormat, aArgs);
6049 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6050 constructor TglBitmap.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
6053 LoadFromResource(aInstance, aResource, aResType);
6056 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6057 constructor TglBitmap.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
6060 LoadFromResourceID(aInstance, aResourceID, aResType);
6063 {$IFDEF GLB_SUPPORT_PNG_READ}
6064 {$IF DEFINED(GLB_LAZ_PNG)}
6065 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6066 //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6067 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6068 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6071 PNG_MAGIC: String[MAGIC_LEN] = #$89#$50#$4E#$47#$0D#$0A#$1A#$0A;
6073 reader: TLazReaderPNG;
6074 intf: TLazIntfImage;
6076 magic: String[MAGIC_LEN];
6079 StreamPos := aStream.Position;
6081 SetLength(magic, MAGIC_LEN);
6082 aStream.Read(magic[1], MAGIC_LEN);
6083 aStream.Position := StreamPos;
6084 if (magic <> PNG_MAGIC) then begin
6089 intf := TLazIntfImage.Create(0, 0);
6090 reader := TLazReaderPNG.Create;
6092 reader.UpdateDescription := true;
6093 reader.ImageRead(aStream, intf);
6094 AssignFromLazIntfImage(intf);
6097 aStream.Position := StreamPos;
6106 {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
6107 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6108 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6110 Surface: PSDL_Surface;
6114 RWops := glBitmapCreateRWops(aStream);
6116 if IMG_isPNG(RWops) > 0 then begin
6117 Surface := IMG_LoadPNG_RW(RWops);
6119 AssignFromSurface(Surface);
6122 SDL_FreeSurface(Surface);
6130 {$ELSEIF DEFINED(GLB_LIB_PNG)}
6131 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6132 procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
6134 TStream(png_get_io_ptr(png)).Read(buffer^, size);
6137 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6138 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6141 signature: array [0..7] of byte;
6143 png_info: png_infop;
6145 TempHeight, TempWidth: Integer;
6146 Format: TglBitmapFormat;
6149 png_rows: array of pByte;
6150 Row, LineSize: Integer;
6154 if not init_libPNG then
6155 raise Exception.Create('LoadPNG - unable to initialize libPNG.');
6159 StreamPos := aStream.Position;
6160 aStream.Read(signature{%H-}, 8);
6161 aStream.Position := StreamPos;
6163 if png_check_sig(@signature, 8) <> 0 then begin
6165 png := png_create_read_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
6167 raise EglBitmapException.Create('LoadPng - couldn''t create read struct.');
6170 png_info := png_create_info_struct(png);
6171 if png_info = nil then begin
6172 png_destroy_read_struct(@png, nil, nil);
6173 raise EglBitmapException.Create('LoadPng - couldn''t create info struct.');
6176 // set read callback
6177 png_set_read_fn(png, aStream, glBitmap_libPNG_read_func);
6179 // read informations
6180 png_read_info(png, png_info);
6183 TempHeight := png_get_image_height(png, png_info);
6184 TempWidth := png_get_image_width(png, png_info);
6187 case png_get_color_type(png, png_info) of
6188 PNG_COLOR_TYPE_GRAY:
6189 Format := tfLuminance8ub1;
6190 PNG_COLOR_TYPE_GRAY_ALPHA:
6191 Format := tfLuminance8Alpha8us1;
6193 Format := tfRGB8ub3;
6194 PNG_COLOR_TYPE_RGB_ALPHA:
6195 Format := tfRGBA8ub4;
6197 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6200 // cut upper 8 bit from 16 bit formats
6201 if png_get_bit_depth(png, png_info) > 8 then
6202 png_set_strip_16(png);
6204 // expand bitdepth smaller than 8
6205 if png_get_bit_depth(png, png_info) < 8 then
6206 png_set_expand(png);
6208 // allocating mem for scanlines
6209 LineSize := png_get_rowbytes(png, png_info);
6210 GetMem(png_data, TempHeight * LineSize);
6212 SetLength(png_rows, TempHeight);
6213 for Row := Low(png_rows) to High(png_rows) do begin
6214 png_rows[Row] := png_data;
6215 Inc(png_rows[Row], Row * LineSize);
6218 // read complete image into scanlines
6219 png_read_image(png, @png_rows[0]);
6222 png_read_end(png, png_info);
6224 // destroy read struct
6225 png_destroy_read_struct(@png, @png_info, nil);
6227 SetLength(png_rows, 0);
6230 SetDataPointer(png_data, Format, TempWidth, TempHeight); //be careful, Data could be freed by this method
6234 if Assigned(png_data) then
6244 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
6245 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6246 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6251 Row, Col, PixSize, LineSize: Integer;
6252 NewImage, pSource, pDest, pAlpha: pByte;
6253 PngFormat: TglBitmapFormat;
6254 FormatDesc: TFormatDescriptor;
6257 PngHeader: String[8] = #137#80#78#71#13#10#26#10;
6262 StreamPos := aStream.Position;
6263 aStream.Read(Header[0], SizeOf(Header));
6264 aStream.Position := StreamPos;
6266 {Test if the header matches}
6267 if Header = PngHeader then begin
6268 Png := TPNGObject.Create;
6270 Png.LoadFromStream(aStream);
6272 case Png.Header.ColorType of
6274 PngFormat := tfLuminance8ub1;
6275 COLOR_GRAYSCALEALPHA:
6276 PngFormat := tfLuminance8Alpha8us1;
6278 PngFormat := tfBGR8ub3;
6280 PngFormat := tfBGRA8ub4;
6282 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6285 FormatDesc := TFormatDescriptor.Get(PngFormat);
6286 PixSize := Round(FormatDesc.PixelSize);
6287 LineSize := FormatDesc.GetSize(Png.Header.Width, 1);
6289 GetMem(NewImage, LineSize * Integer(Png.Header.Height));
6293 case Png.Header.ColorType of
6294 COLOR_RGB, COLOR_GRAYSCALE:
6296 for Row := 0 to Png.Height -1 do begin
6297 Move (Png.Scanline[Row]^, pDest^, LineSize);
6298 Inc(pDest, LineSize);
6301 COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA:
6303 PixSize := PixSize -1;
6305 for Row := 0 to Png.Height -1 do begin
6306 pSource := Png.Scanline[Row];
6307 pAlpha := pByte(Png.AlphaScanline[Row]);
6309 for Col := 0 to Png.Width -1 do begin
6310 Move (pSource^, pDest^, PixSize);
6311 Inc(pSource, PixSize);
6312 Inc(pDest, PixSize);
6321 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6324 SetDataPointer(NewImage, PngFormat, Png.Header.Width, Png.Header.Height); //be careful, Data could be freed by this method
6328 if Assigned(NewImage) then
6340 {$IFDEF GLB_SUPPORT_PNG_WRITE}
6341 {$IFDEF GLB_LIB_PNG}
6342 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6343 procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
6345 TStream(png_get_io_ptr(png)).Write(buffer^, size);
6349 {$IF DEFINED(GLB_LAZ_PNG)}
6350 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6351 procedure TglBitmap.SavePNG(const aStream: TStream);
6353 png: TPortableNetworkGraphic;
6354 intf: TLazIntfImage;
6357 png := TPortableNetworkGraphic.Create;
6358 intf := TLazIntfImage.Create(0, 0);
6360 if not AssignToLazIntfImage(intf) then
6361 raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
6362 intf.GetRawImage(raw);
6363 png.LoadFromRawImage(raw, false);
6364 png.SaveToStream(aStream);
6371 {$ELSEIF DEFINED(GLB_LIB_PNG)}
6372 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6373 procedure TglBitmap.SavePNG(const aStream: TStream);
6376 png_info: png_infop;
6377 png_rows: array of pByte;
6381 FormatDesc: TFormatDescriptor;
6383 if not (ftPNG in FormatGetSupportedFiles(Format)) then
6384 raise EglBitmapUnsupportedFormat.Create(Format);
6386 if not init_libPNG then
6387 raise Exception.Create('unable to initialize libPNG.');
6391 tfAlpha8ub1, tfLuminance8ub1:
6392 ColorType := PNG_COLOR_TYPE_GRAY;
6393 tfLuminance8Alpha8us1:
6394 ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
6395 tfBGR8ub3, tfRGB8ub3:
6396 ColorType := PNG_COLOR_TYPE_RGB;
6397 tfBGRA8ub4, tfRGBA8ub4:
6398 ColorType := PNG_COLOR_TYPE_RGBA;
6400 raise EglBitmapUnsupportedFormat.Create(Format);
6403 FormatDesc := TFormatDescriptor.Get(Format);
6404 LineSize := FormatDesc.GetSize(Width, 1);
6406 // creating array for scanline
6407 SetLength(png_rows, Height);
6409 for Row := 0 to Height - 1 do begin
6410 png_rows[Row] := Data;
6411 Inc(png_rows[Row], Row * LineSize)
6415 png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
6417 raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
6420 png_info := png_create_info_struct(png);
6421 if png_info = nil then begin
6422 png_destroy_write_struct(@png, nil);
6423 raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
6426 // set read callback
6427 png_set_write_fn(png, aStream, glBitmap_libPNG_write_func, nil);
6430 png_set_compression_level(png, 6);
6432 if Format in [tfBGR8ub3, tfBGRA8ub4] then
6435 png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
6436 png_write_info(png, png_info);
6437 png_write_image(png, @png_rows[0]);
6438 png_write_end(png, png_info);
6439 png_destroy_write_struct(@png, @png_info);
6441 SetLength(png_rows, 0);
6448 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
6449 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6450 procedure TglBitmap.SavePNG(const aStream: TStream);
6454 pSource, pDest: pByte;
6455 X, Y, PixSize: Integer;
6456 ColorType: Cardinal;
6462 if not (ftPNG in FormatGetSupportedFiles (Format)) then
6463 raise EglBitmapUnsupportedFormat.Create(Format);
6466 tfAlpha8ub1, tfLuminance8ub1: begin
6467 ColorType := COLOR_GRAYSCALE;
6471 tfLuminance8Alpha8us1: begin
6472 ColorType := COLOR_GRAYSCALEALPHA;
6476 tfBGR8ub3, tfRGB8ub3: begin
6477 ColorType := COLOR_RGB;
6481 tfBGRA8ub4, tfRGBA8ub4: begin
6482 ColorType := COLOR_RGBALPHA;
6487 raise EglBitmapUnsupportedFormat.Create(Format);
6490 Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
6494 for Y := 0 to Height -1 do begin
6495 pDest := png.ScanLine[Y];
6496 for X := 0 to Width -1 do begin
6497 Move(pSource^, pDest^, PixSize);
6498 Inc(pDest, PixSize);
6499 Inc(pSource, PixSize);
6501 png.AlphaScanline[Y]^[X] := pSource^;
6506 // convert RGB line to BGR
6507 if Format in [tfRGB8ub3, tfRGBA8ub4] then begin
6508 pTemp := png.ScanLine[Y];
6509 for X := 0 to Width -1 do begin
6510 Temp := pByteArray(pTemp)^[0];
6511 pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
6512 pByteArray(pTemp)^[2] := Temp;
6519 Png.CompressionLevel := 6;
6520 Png.SaveToStream(aStream);
6528 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6529 //JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6530 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6531 {$IFDEF GLB_LIB_JPEG}
6533 glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
6534 glBitmap_libJPEG_source_mgr = record
6535 pub: jpeg_source_mgr;
6538 SrcBuffer: array [1..4096] of byte;
6541 glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
6542 glBitmap_libJPEG_dest_mgr = record
6543 pub: jpeg_destination_mgr;
6545 DestStream: TStream;
6546 DestBuffer: array [1..4096] of byte;
6549 procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
6555 procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
6561 procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
6566 procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
6572 procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
6578 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6579 function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
6581 src: glBitmap_libJPEG_source_mgr_ptr;
6584 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
6586 bytes := src^.SrcStream.Read(src^.SrcBuffer[1], 4096);
6587 if (bytes <= 0) then begin
6588 src^.SrcBuffer[1] := $FF;
6589 src^.SrcBuffer[2] := JPEG_EOI;
6593 src^.pub.next_input_byte := @(src^.SrcBuffer[1]);
6594 src^.pub.bytes_in_buffer := bytes;
6599 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6600 procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
6602 src: glBitmap_libJPEG_source_mgr_ptr;
6604 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
6606 if num_bytes > 0 then begin
6607 // wanted byte isn't in buffer so set stream position and read buffer
6608 if num_bytes > src^.pub.bytes_in_buffer then begin
6609 src^.SrcStream.Position := src^.SrcStream.Position + num_bytes - src^.pub.bytes_in_buffer;
6610 src^.pub.fill_input_buffer(cinfo);
6612 // wanted byte is in buffer so only skip
6613 inc(src^.pub.next_input_byte, num_bytes);
6614 dec(src^.pub.bytes_in_buffer, num_bytes);
6619 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6620 function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
6622 dest: glBitmap_libJPEG_dest_mgr_ptr;
6624 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
6626 if dest^.pub.free_in_buffer < Cardinal(Length(dest^.DestBuffer)) then begin
6627 // write complete buffer
6628 dest^.DestStream.Write(dest^.DestBuffer[1], SizeOf(dest^.DestBuffer));
6631 dest^.pub.next_output_byte := @dest^.DestBuffer[1];
6632 dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
6638 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6639 procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
6642 dest: glBitmap_libJPEG_dest_mgr_ptr;
6644 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
6646 for Idx := Low(dest^.DestBuffer) to High(dest^.DestBuffer) do begin
6647 // check for endblock
6648 if (Idx < High(dest^.DestBuffer)) and (dest^.DestBuffer[Idx] = $FF) and (dest^.DestBuffer[Idx +1] = JPEG_EOI) then begin
6650 dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
6655 dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
6660 {$IFDEF GLB_SUPPORT_JPEG_READ}
6661 {$IF DEFINED(GLB_LAZ_JPEG)}
6662 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6663 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6666 JPEG_MAGIC: String[MAGIC_LEN] = #$FF#$D8;
6668 intf: TLazIntfImage;
6669 reader: TFPReaderJPEG;
6671 magic: String[MAGIC_LEN];
6674 StreamPos := aStream.Position;
6676 SetLength(magic, MAGIC_LEN);
6677 aStream.Read(magic[1], MAGIC_LEN);
6678 aStream.Position := StreamPos;
6679 if (magic <> JPEG_MAGIC) then begin
6684 reader := TFPReaderJPEG.Create;
6685 intf := TLazIntfImage.Create(0, 0);
6687 intf.DataDescription := GetDescriptionFromDevice(0, 0, 0);
6688 reader.ImageRead(aStream, intf);
6689 AssignFromLazIntfImage(intf);
6692 aStream.Position := StreamPos;
6701 {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
6702 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6703 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6705 Surface: PSDL_Surface;
6710 RWops := glBitmapCreateRWops(aStream);
6712 if IMG_isJPG(RWops) > 0 then begin
6713 Surface := IMG_LoadJPG_RW(RWops);
6715 AssignFromSurface(Surface);
6718 SDL_FreeSurface(Surface);
6726 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
6727 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6728 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6731 Temp: array[0..1]of Byte;
6733 jpeg: jpeg_decompress_struct;
6734 jpeg_err: jpeg_error_mgr;
6736 IntFormat: TglBitmapFormat;
6738 TempHeight, TempWidth: Integer;
6743 FormatDesc: TFormatDescriptor;
6747 if not init_libJPEG then
6748 raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
6751 // reading first two bytes to test file and set cursor back to begin
6752 StreamPos := aStream.Position;
6753 aStream.Read({%H-}Temp[0], 2);
6754 aStream.Position := StreamPos;
6756 // if Bitmap then read file.
6757 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
6758 FillChar(jpeg{%H-}, SizeOf(jpeg_decompress_struct), $00);
6759 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
6762 jpeg.err := jpeg_std_error(@jpeg_err);
6763 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
6764 jpeg_err.output_message := glBitmap_libJPEG_output_message;
6766 // decompression struct
6767 jpeg_create_decompress(@jpeg);
6769 // allocation space for streaming methods
6770 jpeg.src := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_source_mgr));
6772 // seeting up custom functions
6773 with glBitmap_libJPEG_source_mgr_ptr(jpeg.src)^ do begin
6774 pub.init_source := glBitmap_libJPEG_init_source;
6775 pub.fill_input_buffer := glBitmap_libJPEG_fill_input_buffer;
6776 pub.skip_input_data := glBitmap_libJPEG_skip_input_data;
6777 pub.resync_to_restart := jpeg_resync_to_restart; // use default method
6778 pub.term_source := glBitmap_libJPEG_term_source;
6780 pub.bytes_in_buffer := 0; // forces fill_input_buffer on first read
6781 pub.next_input_byte := nil; // until buffer loaded
6783 SrcStream := aStream;
6786 // set global decoding state
6787 jpeg.global_state := DSTATE_START;
6789 // read header of jpeg
6790 jpeg_read_header(@jpeg, false);
6792 // setting output parameter
6793 case jpeg.jpeg_color_space of
6796 jpeg.out_color_space := JCS_GRAYSCALE;
6797 IntFormat := tfLuminance8ub1;
6800 jpeg.out_color_space := JCS_RGB;
6801 IntFormat := tfRGB8ub3;
6805 jpeg_start_decompress(@jpeg);
6807 TempHeight := jpeg.output_height;
6808 TempWidth := jpeg.output_width;
6810 FormatDesc := TFormatDescriptor.Get(IntFormat);
6812 // creating new image
6813 GetMem(pImage, FormatDesc.GetSize(TempWidth, TempHeight));
6817 for Row := 0 to TempHeight -1 do begin
6818 jpeg_read_scanlines(@jpeg, @pTemp, 1);
6819 Inc(pTemp, FormatDesc.GetSize(TempWidth, 1));
6822 // finish decompression
6823 jpeg_finish_decompress(@jpeg);
6825 // destroy decompression
6826 jpeg_destroy_decompress(@jpeg);
6828 SetDataPointer(pImage, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
6832 if Assigned(pImage) then
6842 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
6843 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6844 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6849 Temp: array[0..1]of Byte;
6853 // reading first two bytes to test file and set cursor back to begin
6854 StreamPos := aStream.Position;
6855 aStream.Read(Temp[0], 2);
6856 aStream.Position := StreamPos;
6858 // if Bitmap then read file.
6859 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
6860 bmp := TBitmap.Create;
6862 jpg := TJPEGImage.Create;
6864 jpg.LoadFromStream(aStream);
6866 result := AssignFromBitmap(bmp);
6878 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
6879 {$IF DEFINED(GLB_LAZ_JPEG)}
6880 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6881 procedure TglBitmap.SaveJPEG(const aStream: TStream);
6884 intf: TLazIntfImage;
6887 jpeg := TJPEGImage.Create;
6888 intf := TLazIntfImage.Create(0, 0);
6890 if not AssignToLazIntfImage(intf) then
6891 raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
6892 intf.GetRawImage(raw);
6893 jpeg.LoadFromRawImage(raw, false);
6894 jpeg.SaveToStream(aStream);
6901 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
6902 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6903 procedure TglBitmap.SaveJPEG(const aStream: TStream);
6905 jpeg: jpeg_compress_struct;
6906 jpeg_err: jpeg_error_mgr;
6908 pTemp, pTemp2: pByte;
6910 procedure CopyRow(pDest, pSource: pByte);
6914 for X := 0 to Width - 1 do begin
6915 pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
6916 pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
6917 pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
6924 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
6925 raise EglBitmapUnsupportedFormat.Create(Format);
6927 if not init_libJPEG then
6928 raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
6931 FillChar(jpeg{%H-}, SizeOf(jpeg_compress_struct), $00);
6932 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
6935 jpeg.err := jpeg_std_error(@jpeg_err);
6936 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
6937 jpeg_err.output_message := glBitmap_libJPEG_output_message;
6939 // compression struct
6940 jpeg_create_compress(@jpeg);
6942 // allocation space for streaming methods
6943 jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
6945 // seeting up custom functions
6946 with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
6947 pub.init_destination := glBitmap_libJPEG_init_destination;
6948 pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
6949 pub.term_destination := glBitmap_libJPEG_term_destination;
6951 pub.next_output_byte := @DestBuffer[1];
6952 pub.free_in_buffer := Length(DestBuffer);
6954 DestStream := aStream;
6957 // very important state
6958 jpeg.global_state := CSTATE_START;
6959 jpeg.image_width := Width;
6960 jpeg.image_height := Height;
6962 tfAlpha8ub1, tfLuminance8ub1: begin
6963 jpeg.input_components := 1;
6964 jpeg.in_color_space := JCS_GRAYSCALE;
6966 tfRGB8ub3, tfBGR8ub3: begin
6967 jpeg.input_components := 3;
6968 jpeg.in_color_space := JCS_RGB;
6972 jpeg_set_defaults(@jpeg);
6973 jpeg_set_quality(@jpeg, 95, true);
6974 jpeg_start_compress(@jpeg, true);
6977 if Format = tfBGR8ub3 then
6978 GetMem(pTemp2, fRowSize)
6983 for Row := 0 to jpeg.image_height -1 do begin
6985 if Format = tfBGR8ub3 then
6986 CopyRow(pTemp2, pTemp)
6991 jpeg_write_scanlines(@jpeg, @pTemp2, 1);
6992 inc(pTemp, fRowSize);
6996 if Format = tfBGR8ub3 then
6999 jpeg_finish_compress(@jpeg);
7000 jpeg_destroy_compress(@jpeg);
7006 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
7007 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7008 procedure TglBitmap.SaveJPEG(const aStream: TStream);
7013 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
7014 raise EglBitmapUnsupportedFormat.Create(Format);
7016 Bmp := TBitmap.Create;
7018 Jpg := TJPEGImage.Create;
7020 AssignToBitmap(Bmp);
7021 if (Format in [tfAlpha8ub1, tfLuminance8ub1]) then begin
7022 Jpg.Grayscale := true;
7023 Jpg.PixelFormat := jf8Bit;
7026 Jpg.SaveToStream(aStream);
7037 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7038 //RAW/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7039 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7041 RawHeader = packed record
7047 BitsPerPixel: Integer;
7048 Precision: TglBitmapRec4ub;
7049 Shift: TglBitmapRec4ub;
7052 function TglBitmap.LoadRAW(const aStream: TStream): Boolean;
7056 fd: TFormatDescriptor;
7060 StartPos := aStream.Position;
7061 aStream.Read(header{%H-}, SizeOf(header));
7062 if (header.Magic <> 'glBMP') then begin
7063 aStream.Position := StartPos;
7067 fd := TFormatDescriptor.GetFromPrecShift(header.Precision, header.Shift, header.BitsPerPixel);
7068 if (fd.Format = tfEmpty) then
7069 raise EglBitmapUnsupportedFormat.Create('no supported format found');
7071 buf := GetMem(header.DataSize);
7072 aStream.Read(buf^, header.DataSize);
7073 SetDataPointer(buf, fd.Format, header.Width, header.Height);
7078 procedure TglBitmap.SaveRAW(const aStream: TStream);
7081 fd: TFormatDescriptor;
7083 fd := TFormatDescriptor.Get(Format);
7084 header.Magic := 'glBMP';
7085 header.Version := 1;
7086 header.Width := Width;
7087 header.Height := Height;
7088 header.DataSize := fd.GetSize(fDimension);
7089 header.BitsPerPixel := fd.BitsPerPixel;
7090 header.Precision := fd.Precision;
7091 header.Shift := fd.Shift;
7092 aStream.Write(header, SizeOf(header));
7093 aStream.Write(Data^, header.DataSize);
7096 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7097 //BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7098 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7105 BMP_COMP_BITFIELDS = 3;
7108 TBMPHeader = packed record
7113 bfOffBits: Cardinal;
7116 TBMPInfo = packed record
7122 biCompression: Cardinal;
7123 biSizeImage: Cardinal;
7124 biXPelsPerMeter: Longint;
7125 biYPelsPerMeter: Longint;
7126 biClrUsed: Cardinal;
7127 biClrImportant: Cardinal;
7130 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7131 function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
7133 //////////////////////////////////////////////////////////////////////////////////////////////////
7134 function ReadInfo(out aInfo: TBMPInfo; out aMask: TglBitmapRec4ul): TglBitmapFormat;
7137 aStream.Read(aInfo{%H-}, SizeOf(aInfo));
7138 FillChar(aMask{%H-}, SizeOf(aMask), 0);
7141 case aInfo.biCompression of
7143 BMP_COMP_RLE8: begin
7144 raise EglBitmap.Create('RLE compression is not supported');
7146 BMP_COMP_BITFIELDS: begin
7147 if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
7148 aStream.Read(aMask.r, SizeOf(aMask.r));
7149 aStream.Read(aMask.g, SizeOf(aMask.g));
7150 aStream.Read(aMask.b, SizeOf(aMask.b));
7151 aStream.Read(aMask.a, SizeOf(aMask.a));
7153 raise EglBitmap.Create('Bitfields are only supported for 16bit and 32bit formats');
7157 //get suitable format
7158 case aInfo.biBitCount of
7159 8: result := tfLuminance8ub1;
7160 16: result := tfX1RGB5us1;
7161 24: result := tfBGR8ub3;
7162 32: result := tfXRGB8ui1;
7166 function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TbmpColorTableFormat;
7169 ColorTable: TbmpColorTable;
7172 if (aInfo.biBitCount >= 16) then
7174 aFormat := tfLuminance8ub1;
7175 c := aInfo.biClrUsed;
7177 c := 1 shl aInfo.biBitCount;
7178 SetLength(ColorTable, c);
7179 for i := 0 to c-1 do begin
7180 aStream.Read(ColorTable[i], SizeOf(TbmpColorTableEnty));
7181 if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then
7182 aFormat := tfRGB8ub3;
7185 result := TbmpColorTableFormat.Create;
7186 result.BitsPerPixel := aInfo.biBitCount;
7187 result.ColorTable := ColorTable;
7191 //////////////////////////////////////////////////////////////////////////////////////////////////
7192 function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapRec4ul; const aInfo: TBMPInfo): TbmpBitfieldFormat;
7194 FormatDesc: TFormatDescriptor;
7197 if (aMask.r <> 0) or (aMask.g <> 0) or (aMask.b <> 0) or (aMask.a <> 0) then begin
7198 FormatDesc := TFormatDescriptor.GetFromMask(aMask);
7199 if (FormatDesc.Format = tfEmpty) then
7201 aFormat := FormatDesc.Format;
7202 if (aMask.a = 0) and TFormatDescriptor.Get(aFormat).HasAlpha then
7203 aFormat := TFormatDescriptor.Get(aFormat).WithoutAlpha;
7204 if (aMask.a <> 0) and not TFormatDescriptor.Get(aFormat).HasAlpha then
7205 aFormat := TFormatDescriptor.Get(aFormat).WithAlpha;
7207 result := TbmpBitfieldFormat.Create;
7208 result.SetValues(aInfo.biBitCount, aMask);
7215 ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
7216 PaddingBuff: Cardinal;
7217 LineBuf, ImageData, TmpData: PByte;
7218 SourceMD, DestMD: Pointer;
7219 BmpFormat: TglBitmapFormat;
7222 Mask: TglBitmapRec4ul;
7227 SpecialFormat: TFormatDescriptor;
7228 FormatDesc: TFormatDescriptor;
7230 //////////////////////////////////////////////////////////////////////////////////////////////////
7231 procedure SpecialFormatReadLine(aData: PByte; aLineBuf: PByte);
7234 Pixel: TglBitmapPixelData;
7236 aStream.Read(aLineBuf^, rbLineSize);
7237 SpecialFormat.PreparePixel(Pixel);
7238 for i := 0 to Info.biWidth-1 do begin
7239 SpecialFormat.Unmap(aLineBuf, Pixel, SourceMD);
7240 glBitmapConvertPixel(Pixel, SpecialFormat, FormatDesc);
7241 FormatDesc.Map(Pixel, aData, DestMD);
7247 BmpFormat := tfEmpty;
7248 SpecialFormat := nil;
7254 StartPos := aStream.Position;
7255 aStream.Read(Header{%H-}, SizeOf(Header));
7257 if Header.bfType = BMP_MAGIC then begin
7259 BmpFormat := ReadInfo(Info, Mask);
7260 SpecialFormat := ReadColorTable(BmpFormat, Info);
7261 if not Assigned(SpecialFormat) then
7262 SpecialFormat := CheckBitfields(BmpFormat, Mask, Info);
7263 aStream.Position := StartPos + Header.bfOffBits;
7265 if (BmpFormat <> tfEmpty) then begin
7266 FormatDesc := TFormatDescriptor.Get(BmpFormat);
7267 rbLineSize := Round(Info.biWidth * Info.biBitCount / 8); //ReadBuffer LineSize
7268 wbLineSize := Trunc(Info.biWidth * FormatDesc.BytesPerPixel);
7269 Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
7272 DestMD := FormatDesc.CreateMappingData;
7273 ImageSize := FormatDesc.GetSize(Info.biWidth, abs(Info.biHeight));
7274 GetMem(ImageData, ImageSize);
7275 if Assigned(SpecialFormat) then begin
7276 GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
7277 SourceMD := SpecialFormat.CreateMappingData;
7282 FillChar(ImageData^, ImageSize, $FF);
7283 TmpData := ImageData;
7284 if (Info.biHeight > 0) then
7285 Inc(TmpData, wbLineSize * (Info.biHeight-1));
7286 for i := 0 to Abs(Info.biHeight)-1 do begin
7287 if Assigned(SpecialFormat) then
7288 SpecialFormatReadLine(TmpData, LineBuf) //if is special format read and convert data
7290 aStream.Read(TmpData^, wbLineSize); //else only read data
7291 if (Info.biHeight > 0) then
7292 dec(TmpData, wbLineSize)
7294 inc(TmpData, wbLineSize);
7295 aStream.Read(PaddingBuff{%H-}, Padding);
7297 SetDataPointer(ImageData, BmpFormat, Info.biWidth, abs(Info.biHeight)); //be careful, Data could be freed by this method
7300 if Assigned(LineBuf) then
7302 if Assigned(SourceMD) then
7303 SpecialFormat.FreeMappingData(SourceMD);
7304 FormatDesc.FreeMappingData(DestMD);
7307 if Assigned(ImageData) then
7312 raise EglBitmap.Create('LoadBMP - No suitable format found');
7314 aStream.Position := StartPos;
7318 FreeAndNil(SpecialFormat);
7321 else aStream.Position := StartPos;
7324 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7325 procedure TglBitmap.SaveBMP(const aStream: TStream);
7329 Converter: TFormatDescriptor;
7330 FormatDesc: TFormatDescriptor;
7331 SourceFD, DestFD: Pointer;
7332 pData, srcData, dstData, ConvertBuffer: pByte;
7334 Pixel: TglBitmapPixelData;
7335 ImageSize, wbLineSize, rbLineSize, Padding, LineIdx, PixelIdx: Integer;
7336 RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
7338 PaddingBuff: Cardinal;
7340 function GetLineWidth : Integer;
7342 result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
7346 if not (ftBMP in FormatGetSupportedFiles(Format)) then
7347 raise EglBitmapUnsupportedFormat.Create(Format);
7350 FormatDesc := TFormatDescriptor.Get(Format);
7351 ImageSize := FormatDesc.GetSize(Dimension);
7353 FillChar(Header{%H-}, SizeOf(Header), 0);
7354 Header.bfType := BMP_MAGIC;
7355 Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
7356 Header.bfReserved1 := 0;
7357 Header.bfReserved2 := 0;
7358 Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
7360 FillChar(Info{%H-}, SizeOf(Info), 0);
7361 Info.biSize := SizeOf(Info);
7362 Info.biWidth := Width;
7363 Info.biHeight := Height;
7365 Info.biCompression := BMP_COMP_RGB;
7366 Info.biSizeImage := ImageSize;
7370 tfAlpha4ub1, tfAlpha8ub1, tfLuminance4ub1, tfLuminance8ub1, tfR3G3B2ub1:
7372 Info.biBitCount := 8;
7373 Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
7374 Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal); //256 ColorTable entries
7375 Converter := TbmpColorTableFormat.Create;
7376 with (Converter as TbmpColorTableFormat) do begin
7377 SetValues(fFormat, 1, FormatDesc.Precision, FormatDesc.Shift);
7382 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
7383 tfRGBX4us1, tfXRGB4us1, tfRGB5X1us1, tfX1RGB5us1, tfR5G6B5us1, tfRGB5A1us1, tfA1RGB5us1, tfRGBA4us1, tfARGB4us1,
7384 tfBGRX4us1, tfXBGR4us1, tfBGR5X1us1, tfX1BGR5us1, tfB5G6R5us1, tfBGR5A1us1, tfA1BGR5us1, tfBGRA4us1, tfABGR4us1:
7386 Info.biBitCount := 16;
7387 Info.biCompression := BMP_COMP_BITFIELDS;
7390 tfBGR8ub3, tfRGB8ub3:
7392 Info.biBitCount := 24;
7393 if (Format = tfRGB8ub3) then
7394 Converter := TfdBGR8ub3.Create; //use BGR8 Format Descriptor to Swap RGB Values
7397 tfRGBX8ui1, tfXRGB8ui1, tfRGB10X2ui1, tfX2RGB10ui1, tfRGBA8ui1, tfARGB8ui1, tfRGBA8ub4, tfRGB10A2ui1, tfA2RGB10ui1,
7398 tfBGRX8ui1, tfXBGR8ui1, tfBGR10X2ui1, tfX2BGR10ui1, tfBGRA8ui1, tfABGR8ui1, tfBGRA8ub4, tfBGR10A2ui1, tfA2BGR10ui1:
7400 Info.biBitCount := 32;
7401 Info.biCompression := BMP_COMP_BITFIELDS;
7404 raise EglBitmapUnsupportedFormat.Create(Format);
7406 Info.biXPelsPerMeter := 2835;
7407 Info.biYPelsPerMeter := 2835;
7410 if Info.biCompression = BMP_COMP_BITFIELDS then begin
7411 Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
7412 Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
7414 RedMask := FormatDesc.Mask.r;
7415 GreenMask := FormatDesc.Mask.g;
7416 BlueMask := FormatDesc.Mask.b;
7417 AlphaMask := FormatDesc.Mask.a;
7421 aStream.Write(Header, SizeOf(Header));
7422 aStream.Write(Info, SizeOf(Info));
7425 if Assigned(Converter) and (Converter is TbmpColorTableFormat) then
7426 with (Converter as TbmpColorTableFormat) do
7427 aStream.Write(ColorTable[0].b,
7428 SizeOf(TbmpColorTableEnty) * Length(ColorTable));
7431 if Info.biCompression = BMP_COMP_BITFIELDS then begin
7432 aStream.Write(RedMask, SizeOf(Cardinal));
7433 aStream.Write(GreenMask, SizeOf(Cardinal));
7434 aStream.Write(BlueMask, SizeOf(Cardinal));
7435 aStream.Write(AlphaMask, SizeOf(Cardinal));
7439 rbLineSize := Round(Info.biWidth * FormatDesc.BytesPerPixel);
7440 wbLineSize := Round(Info.biWidth * Info.biBitCount / 8);
7441 Padding := GetLineWidth - wbLineSize;
7445 inc(pData, (Height-1) * rbLineSize);
7447 // prepare row buffer. But only for RGB because RGBA supports color masks
7448 // so it's possible to change color within the image.
7449 if Assigned(Converter) then begin
7450 FormatDesc.PreparePixel(Pixel);
7451 GetMem(ConvertBuffer, wbLineSize);
7452 SourceFD := FormatDesc.CreateMappingData;
7453 DestFD := Converter.CreateMappingData;
7455 ConvertBuffer := nil;
7458 for LineIdx := 0 to Height - 1 do begin
7460 if Assigned(Converter) then begin
7462 dstData := ConvertBuffer;
7463 for PixelIdx := 0 to Info.biWidth-1 do begin
7464 FormatDesc.Unmap(srcData, Pixel, SourceFD);
7465 glBitmapConvertPixel(Pixel, FormatDesc, Converter);
7466 Converter.Map(Pixel, dstData, DestFD);
7468 aStream.Write(ConvertBuffer^, wbLineSize);
7470 aStream.Write(pData^, rbLineSize);
7472 dec(pData, rbLineSize);
7473 if (Padding > 0) then
7474 aStream.Write(PaddingBuff, Padding);
7477 // destroy row buffer
7478 if Assigned(ConvertBuffer) then begin
7479 FormatDesc.FreeMappingData(SourceFD);
7480 Converter.FreeMappingData(DestFD);
7481 FreeMem(ConvertBuffer);
7485 if Assigned(Converter) then
7490 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7491 //TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7492 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7494 TTGAHeader = packed record
7498 //ColorMapSpec: Array[0..4] of Byte;
7499 ColorMapStart: Word;
7500 ColorMapLength: Word;
7501 ColorMapEntrySize: Byte;
7511 TGA_UNCOMPRESSED_RGB = 2;
7512 TGA_UNCOMPRESSED_GRAY = 3;
7513 TGA_COMPRESSED_RGB = 10;
7514 TGA_COMPRESSED_GRAY = 11;
7516 TGA_NONE_COLOR_TABLE = 0;
7518 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7519 function TglBitmap.LoadTGA(const aStream: TStream): Boolean;
7522 ImageData: System.PByte;
7523 StartPosition: Int64;
7524 PixelSize, LineSize: Integer;
7525 tgaFormat: TglBitmapFormat;
7526 FormatDesc: TFormatDescriptor;
7527 Counter: packed record
7529 low, high, dir: Integer;
7536 ////////////////////////////////////////////////////////////////////////////////////////
7537 procedure ReadUncompressed;
7540 buf, tmp1, tmp2: System.PByte;
7543 if (Counter.X.dir < 0) then
7544 GetMem(buf, LineSize);
7546 while (Counter.Y.low <> Counter.Y.high + counter.Y.dir) do begin
7548 inc(tmp1, (Counter.Y.low * LineSize)); //pointer to LineStart
7549 if (Counter.X.dir < 0) then begin //flip X
7550 aStream.Read(buf^, LineSize);
7552 inc(tmp2, LineSize - PixelSize); //pointer to last pixel in line
7553 for i := 0 to Header.Width-1 do begin //for all pixels in line
7554 for j := 0 to PixelSize-1 do begin //for all bytes in pixel
7559 dec(tmp2, 2*PixelSize); //move 2 backwards, because j-loop moved 1 forward
7562 aStream.Read(tmp1^, LineSize);
7563 inc(Counter.Y.low, Counter.Y.dir); //move to next line index
7566 if Assigned(buf) then
7571 ////////////////////////////////////////////////////////////////////////////////////////
7572 procedure ReadCompressed;
7574 /////////////////////////////////////////////////////////////////
7576 TmpData: System.PByte;
7577 LinePixelsRead: Integer;
7578 procedure CheckLine;
7580 if (LinePixelsRead >= Header.Width) then begin
7581 LinePixelsRead := 0;
7582 inc(Counter.Y.low, Counter.Y.dir); //next line index
7583 TmpData := ImageData;
7584 inc(TmpData, Counter.Y.low * LineSize); //set line
7585 if (Counter.X.dir < 0) then //if x flipped then
7586 inc(TmpData, LineSize - PixelSize); //set last pixel
7590 /////////////////////////////////////////////////////////////////
7593 CacheSize, CachePos: Integer;
7594 procedure CachedRead(out Buffer; Count: Integer);
7598 if (CachePos + Count > CacheSize) then begin
7599 //if buffer overflow save non read bytes
7601 if (CacheSize - CachePos > 0) then begin
7602 BytesRead := CacheSize - CachePos;
7603 Move(PByteArray(Cache)^[CachePos], Buffer{%H-}, BytesRead);
7604 inc(CachePos, BytesRead);
7607 //load cache from file
7608 CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
7609 aStream.Read(Cache^, CacheSize);
7612 //read rest of requested bytes
7613 if (Count - BytesRead > 0) then begin
7614 Move(PByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
7615 inc(CachePos, Count - BytesRead);
7618 //if no buffer overflow just read the data
7619 Move(PByteArray(Cache)^[CachePos], Buffer, Count);
7620 inc(CachePos, Count);
7624 procedure PixelToBuffer(const aData: PByte; var aBuffer: PByte);
7629 inc(aBuffer, Counter.X.dir);
7632 PWord(aBuffer)^ := PWord(aData)^;
7633 inc(aBuffer, 2 * Counter.X.dir);
7636 PByteArray(aBuffer)^[0] := PByteArray(aData)^[0];
7637 PByteArray(aBuffer)^[1] := PByteArray(aData)^[1];
7638 PByteArray(aBuffer)^[2] := PByteArray(aData)^[2];
7639 inc(aBuffer, 3 * Counter.X.dir);
7642 PCardinal(aBuffer)^ := PCardinal(aData)^;
7643 inc(aBuffer, 4 * Counter.X.dir);
7649 TotalPixelsToRead, TotalPixelsRead: Integer;
7651 buf: array [0..3] of Byte; //1 pixel is max 32bit long
7652 PixelRepeat: Boolean;
7653 PixelsToRead, PixelCount: Integer;
7658 TotalPixelsToRead := Header.Width * Header.Height;
7659 TotalPixelsRead := 0;
7660 LinePixelsRead := 0;
7662 GetMem(Cache, CACHE_SIZE);
7664 TmpData := ImageData;
7665 inc(TmpData, Counter.Y.low * LineSize); //set line
7666 if (Counter.X.dir < 0) then //if x flipped then
7667 inc(TmpData, LineSize - PixelSize); //set last pixel
7671 CachedRead(Temp, 1);
7672 PixelRepeat := (Temp and $80) > 0;
7673 PixelsToRead := (Temp and $7F) + 1;
7674 inc(TotalPixelsRead, PixelsToRead);
7677 CachedRead(buf[0], PixelSize);
7678 while (PixelsToRead > 0) do begin
7680 PixelCount := Min(Header.Width - LinePixelsRead, PixelsToRead); //max read to EOL or EOF
7681 while (PixelCount > 0) do begin
7682 if not PixelRepeat then
7683 CachedRead(buf[0], PixelSize);
7684 PixelToBuffer(@buf[0], TmpData);
7685 inc(LinePixelsRead);
7690 until (TotalPixelsRead >= TotalPixelsToRead);
7696 function IsGrayFormat: Boolean;
7698 result := Header.ImageType in [TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_GRAY];
7704 // reading header to test file and set cursor back to begin
7705 StartPosition := aStream.Position;
7706 aStream.Read(Header{%H-}, SizeOf(Header));
7708 // no colormapped files
7709 if (Header.ColorMapType = TGA_NONE_COLOR_TABLE) and (Header.ImageType in [
7710 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY]) then
7713 if Header.ImageID <> 0 then // skip image ID
7714 aStream.Position := aStream.Position + Header.ImageID;
7716 tgaFormat := tfEmpty;
7718 8: if IsGrayFormat then case (Header.ImageDesc and $F) of
7719 0: tgaFormat := tfLuminance8ub1;
7720 8: tgaFormat := tfAlpha8ub1;
7723 16: if IsGrayFormat then case (Header.ImageDesc and $F) of
7724 0: tgaFormat := tfLuminance16us1;
7725 8: tgaFormat := tfLuminance8Alpha8ub2;
7726 end else case (Header.ImageDesc and $F) of
7727 0: tgaFormat := tfX1RGB5us1;
7728 1: tgaFormat := tfA1RGB5us1;
7729 4: tgaFormat := tfARGB4us1;
7732 24: if not IsGrayFormat then case (Header.ImageDesc and $F) of
7733 0: tgaFormat := tfBGR8ub3;
7736 32: if IsGrayFormat then case (Header.ImageDesc and $F) of
7737 0: tgaFormat := tfDepth32ui1;
7738 end else case (Header.ImageDesc and $F) of
7739 0: tgaFormat := tfX2RGB10ui1;
7740 2: tgaFormat := tfA2RGB10ui1;
7741 8: tgaFormat := tfARGB8ui1;
7745 if (tgaFormat = tfEmpty) then
7746 raise EglBitmap.Create('LoadTga - unsupported format');
7748 FormatDesc := TFormatDescriptor.Get(tgaFormat);
7749 PixelSize := FormatDesc.GetSize(1, 1);
7750 LineSize := FormatDesc.GetSize(Header.Width, 1);
7752 GetMem(ImageData, LineSize * Header.Height);
7755 if ((Header.ImageDesc and (1 shl 4)) > 0) then begin
7756 Counter.X.low := Header.Height-1;;
7757 Counter.X.high := 0;
7758 Counter.X.dir := -1;
7761 Counter.X.high := Header.Height-1;
7766 if ((Header.ImageDesc and (1 shl 5)) > 0) then begin
7768 Counter.Y.high := Header.Height-1;
7771 Counter.Y.low := Header.Height-1;;
7772 Counter.Y.high := 0;
7773 Counter.Y.dir := -1;
7777 case Header.ImageType of
7778 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY:
7780 TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY:
7784 SetDataPointer(ImageData, tgaFormat, Header.Width, Header.Height); //be careful, Data could be freed by this method
7787 if Assigned(ImageData) then
7792 aStream.Position := StartPosition;
7795 else aStream.Position := StartPosition;
7798 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7799 procedure TglBitmap.SaveTGA(const aStream: TStream);
7803 FormatDesc: TFormatDescriptor;
7805 if not (ftTGA in FormatGetSupportedFiles(Format)) then
7806 raise EglBitmapUnsupportedFormat.Create(Format);
7809 FormatDesc := TFormatDescriptor.Get(Format);
7810 FillChar(Header{%H-}, SizeOf(Header), 0);
7811 Header.ImageDesc := CountSetBits(FormatDesc.Range.a) and $F;
7812 Header.Bpp := FormatDesc.BitsPerPixel;
7813 Header.Width := Width;
7814 Header.Height := Height;
7815 Header.ImageDesc := Header.ImageDesc or $20; //flip y
7816 if FormatDesc.IsGrayscale or (not FormatDesc.IsGrayscale and not FormatDesc.HasRed and FormatDesc.HasAlpha) then
7817 Header.ImageType := TGA_UNCOMPRESSED_GRAY
7819 Header.ImageType := TGA_UNCOMPRESSED_RGB;
7820 aStream.Write(Header, SizeOf(Header));
7823 Size := FormatDesc.GetSize(Dimension);
7824 aStream.Write(Data^, Size);
7827 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7828 //DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7829 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7831 DDS_MAGIC: Cardinal = $20534444;
7833 // DDS_header.dwFlags
7834 DDSD_CAPS = $00000001;
7835 DDSD_HEIGHT = $00000002;
7836 DDSD_WIDTH = $00000004;
7837 DDSD_PIXELFORMAT = $00001000;
7839 // DDS_header.sPixelFormat.dwFlags
7840 DDPF_ALPHAPIXELS = $00000001;
7841 DDPF_ALPHA = $00000002;
7842 DDPF_FOURCC = $00000004;
7843 DDPF_RGB = $00000040;
7844 DDPF_LUMINANCE = $00020000;
7846 // DDS_header.sCaps.dwCaps1
7847 DDSCAPS_TEXTURE = $00001000;
7849 // DDS_header.sCaps.dwCaps2
7850 DDSCAPS2_CUBEMAP = $00000200;
7852 D3DFMT_DXT1 = $31545844;
7853 D3DFMT_DXT3 = $33545844;
7854 D3DFMT_DXT5 = $35545844;
7857 TDDSPixelFormat = packed record
7861 dwRGBBitCount: Cardinal;
7862 dwRBitMask: Cardinal;
7863 dwGBitMask: Cardinal;
7864 dwBBitMask: Cardinal;
7865 dwABitMask: Cardinal;
7868 TDDSCaps = packed record
7872 dwReserved: Cardinal;
7875 TDDSHeader = packed record
7880 dwPitchOrLinearSize: Cardinal;
7882 dwMipMapCount: Cardinal;
7883 dwReserved: array[0..10] of Cardinal;
7884 PixelFormat: TDDSPixelFormat;
7886 dwReserved2: Cardinal;
7889 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7890 function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
7893 Converter: TbmpBitfieldFormat;
7895 function GetDDSFormat: TglBitmapFormat;
7897 fd: TFormatDescriptor;
7899 Mask: TglBitmapRec4ul;
7900 Range: TglBitmapRec4ui;
7904 with Header.PixelFormat do begin
7906 if ((dwFlags and DDPF_FOURCC) > 0) then begin
7907 case Header.PixelFormat.dwFourCC of
7908 D3DFMT_DXT1: result := tfS3tcDtx1RGBA;
7909 D3DFMT_DXT3: result := tfS3tcDtx3RGBA;
7910 D3DFMT_DXT5: result := tfS3tcDtx5RGBA;
7912 end else if ((dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE or DDPF_ALPHA)) > 0) then begin
7914 if ((dwFlags and DDPF_LUMINANCE) = 0) then begin
7915 Mask.r := dwRBitMask;
7916 Mask.g := dwGBitMask;
7917 Mask.b := dwBBitMask;
7919 Mask.r := dwRBitMask;
7920 Mask.g := dwRBitMask;
7921 Mask.b := dwRBitMask;
7923 if (dwFlags and DDPF_ALPHAPIXELS > 0) then
7924 Mask.a := dwABitMask
7928 //find matching format
7929 fd := TFormatDescriptor.GetFromMask(Mask, dwRGBBitCount);
7930 result := fd.Format;
7931 if (result <> tfEmpty) then
7934 //find format with same Range
7936 Range.arr[i] := (2 shl CountSetBits(Mask.arr[i])) - 1;
7937 for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
7938 fd := TFormatDescriptor.Get(result);
7941 if (fd.Range.arr[i] <> Range.arr[i]) then begin
7949 //no format with same range found -> use default
7950 if (result = tfEmpty) then begin
7951 if (dwABitMask > 0) then
7952 result := tfRGBA8ui1
7954 result := tfRGB8ub3;
7957 Converter := TbmpBitfieldFormat.Create;
7958 Converter.SetValues(dwRGBBitCount, glBitmapRec4ul(dwRBitMask, dwGBitMask, dwBBitMask, dwABitMask));
7965 x, y, LineSize, RowSize, Magic: Cardinal;
7966 NewImage, TmpData, RowData, SrcData: System.PByte;
7967 SourceMD, DestMD: Pointer;
7968 Pixel: TglBitmapPixelData;
7969 ddsFormat: TglBitmapFormat;
7970 FormatDesc: TFormatDescriptor;
7975 StreamPos := aStream.Position;
7978 aStream.Read(Magic{%H-}, sizeof(Magic));
7979 if (Magic <> DDS_MAGIC) then begin
7980 aStream.Position := StreamPos;
7985 aStream.Read(Header{%H-}, sizeof(Header));
7986 if (Header.dwSize <> SizeOf(Header)) or
7987 ((Header.dwFlags and (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) <>
7988 (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) then
7990 aStream.Position := StreamPos;
7994 if ((Header.Caps.dwCaps1 and DDSCAPS2_CUBEMAP) > 0) then
7995 raise EglBitmap.Create('LoadDDS - CubeMaps are not supported');
7997 ddsFormat := GetDDSFormat;
7999 if (ddsFormat = tfEmpty) then
8000 raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
8002 FormatDesc := TFormatDescriptor.Get(ddsFormat);
8003 LineSize := Trunc(Header.dwWidth * FormatDesc.BytesPerPixel);
8004 GetMem(NewImage, Header.dwHeight * LineSize);
8006 TmpData := NewImage;
8009 if Assigned(Converter) then begin
8010 RowSize := Round(Header.dwWidth * Header.PixelFormat.dwRGBBitCount / 8);
8011 GetMem(RowData, RowSize);
8012 SourceMD := Converter.CreateMappingData;
8013 DestMD := FormatDesc.CreateMappingData;
8015 for y := 0 to Header.dwHeight-1 do begin
8016 TmpData := NewImage;
8017 inc(TmpData, y * LineSize);
8019 aStream.Read(SrcData^, RowSize);
8020 for x := 0 to Header.dwWidth-1 do begin
8021 Converter.Unmap(SrcData, Pixel, SourceMD);
8022 glBitmapConvertPixel(Pixel, Converter, FormatDesc);
8023 FormatDesc.Map(Pixel, TmpData, DestMD);
8027 Converter.FreeMappingData(SourceMD);
8028 FormatDesc.FreeMappingData(DestMD);
8034 if ((Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0) then begin
8035 RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
8036 for Y := 0 to Header.dwHeight-1 do begin
8037 aStream.Read(TmpData^, RowSize);
8038 Inc(TmpData, LineSize);
8043 if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0 then begin
8044 RowSize := (Header.PixelFormat.dwRGBBitCount * Header.dwWidth) shr 3;
8045 for Y := 0 to Header.dwHeight-1 do begin
8046 aStream.Read(TmpData^, RowSize);
8047 Inc(TmpData, LineSize);
8050 raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
8052 SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight); //be careful, Data could be freed by this method
8055 if Assigned(NewImage) then
8060 FreeAndNil(Converter);
8064 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8065 procedure TglBitmap.SaveDDS(const aStream: TStream);
8068 FormatDesc: TFormatDescriptor;
8070 if not (ftDDS in FormatGetSupportedFiles(Format)) then
8071 raise EglBitmapUnsupportedFormat.Create(Format);
8073 FormatDesc := TFormatDescriptor.Get(Format);
8076 FillChar(Header{%H-}, SizeOf(Header), 0);
8077 Header.dwSize := SizeOf(Header);
8078 Header.dwFlags := DDSD_WIDTH or DDSD_HEIGHT or DDSD_CAPS or DDSD_PIXELFORMAT;
8080 Header.dwWidth := Max(1, Width);
8081 Header.dwHeight := Max(1, Height);
8084 Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
8087 Header.PixelFormat.dwSize := sizeof(Header);
8088 if (FormatDesc.IsCompressed) then begin
8089 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_FOURCC;
8091 tfS3tcDtx1RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT1;
8092 tfS3tcDtx3RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT3;
8093 tfS3tcDtx5RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT5;
8095 end else if not FormatDesc.HasColor and FormatDesc.HasAlpha then begin
8096 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHA;
8097 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
8098 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
8099 end else if FormatDesc.IsGrayscale then begin
8100 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_LUMINANCE;
8101 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
8102 Header.PixelFormat.dwRBitMask := FormatDesc.Mask.r;
8103 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
8105 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_RGB;
8106 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
8107 Header.PixelFormat.dwRBitMask := FormatDesc.Mask.r;
8108 Header.PixelFormat.dwGBitMask := FormatDesc.Mask.g;
8109 Header.PixelFormat.dwBBitMask := FormatDesc.Mask.b;
8110 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
8113 if (FormatDesc.HasAlpha) then
8114 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
8116 aStream.Write(DDS_MAGIC, sizeof(DDS_MAGIC));
8117 aStream.Write(Header, SizeOf(Header));
8118 aStream.Write(Data^, FormatDesc.GetSize(Dimension));
8121 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8122 //TglBitmap1D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8123 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8124 procedure TglBitmap1D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
8125 const aWidth: Integer; const aHeight: Integer);
8130 if (aHeight > 1) then begin
8131 Size := TFormatDescriptor.Get(aFormat).GetSize(aWidth, 1);
8132 GetMem(pTemp, Size);
8134 Move(aData^, pTemp^, Size);
8143 inherited SetDataPointer(pTemp, aFormat, aWidth);
8146 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8147 function TglBitmap1D.FlipHorz: Boolean;
8150 pTempDest, pDest, pSource: PByte;
8152 result := inherited FlipHorz;
8153 if Assigned(Data) and not TFormatDescriptor.Get(Format).IsCompressed then begin
8155 GetMem(pDest, fRowSize);
8158 Inc(pTempDest, fRowSize);
8159 for Col := 0 to Width-1 do begin
8160 dec(pTempDest, fPixelSize); //dec before, because ptr is behind last byte of data
8161 Move(pSource^, pTempDest^, fPixelSize);
8162 Inc(pSource, fPixelSize);
8164 SetDataPointer(pDest, Format, Width); //be careful, Data could be freed by this method
8167 if Assigned(pDest) then
8174 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8175 procedure TglBitmap1D.UploadData(const aBuildWithGlu: Boolean);
8177 FormatDesc: TFormatDescriptor;
8180 FormatDesc := TFormatDescriptor.Get(Format);
8181 if FormatDesc.IsCompressed then begin
8182 if not Assigned(glCompressedTexImage1D) then
8183 raise EglBitmap.Create('compressed formats not supported by video adapter');
8184 glCompressedTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.GetSize(Width, 1), Data)
8185 end else if aBuildWithGlu then
8186 gluBuild1DMipmaps(Target, FormatDesc.glInternalFormat, Width, FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
8188 glTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
8191 if (FreeDataAfterGenTexture) then
8195 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8196 procedure TglBitmap1D.GenTexture(const aTestTextureSize: Boolean);
8198 BuildWithGlu, TexRec: Boolean;
8201 if Assigned(Data) then begin
8202 // Check Texture Size
8203 if (aTestTextureSize) then begin
8204 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
8206 if (Width > TexSize) then
8207 raise EglBitmapSizeToLarge.Create('TglBitmap1D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
8209 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
8210 (Target = GL_TEXTURE_RECTANGLE);
8211 if not (IsPowerOfTwo(Width) or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
8212 raise EglBitmapNonPowerOfTwo.Create('TglBitmap1D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8216 SetupParameters(BuildWithGlu);
8217 UploadData(BuildWithGlu);
8218 glAreTexturesResident(1, @fID, @fIsResident);
8222 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8223 procedure TglBitmap1D.AfterConstruction;
8226 Target := GL_TEXTURE_1D;
8229 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8230 //TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8231 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8232 function TglBitmap2D.GetScanline(const aIndex: Integer): Pointer;
8234 if (aIndex >= Low(fLines)) and (aIndex <= High(fLines)) then
8235 result := fLines[aIndex]
8240 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8241 procedure TglBitmap2D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
8242 const aWidth: Integer; const aHeight: Integer);
8244 Idx, LineWidth: Integer;
8246 inherited SetDataPointer(aData, aFormat, aWidth, aHeight);
8248 if not TFormatDescriptor.Get(aFormat).IsCompressed then begin
8250 if Assigned(Data) then begin
8251 SetLength(fLines, GetHeight);
8252 LineWidth := Trunc(GetWidth * TFormatDescriptor.Get(Format).BytesPerPixel);
8254 for Idx := 0 to GetHeight-1 do begin
8255 fLines[Idx] := Data;
8256 Inc(fLines[Idx], Idx * LineWidth);
8259 else SetLength(fLines, 0);
8261 SetLength(fLines, 0);
8265 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8266 procedure TglBitmap2D.UploadData(const aTarget: GLenum; const aBuildWithGlu: Boolean);
8268 FormatDesc: TFormatDescriptor;
8270 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
8272 FormatDesc := TFormatDescriptor.Get(Format);
8273 if FormatDesc.IsCompressed then begin
8274 if not Assigned(glCompressedTexImage2D) then
8275 raise EglBitmap.Create('compressed formats not supported by video adapter');
8276 glCompressedTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0, FormatDesc.GetSize(fDimension), Data)
8277 end else if aBuildWithGlu then begin
8278 gluBuild2DMipmaps(aTarget, FormatDesc.ChannelCount, Width, Height,
8279 FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
8281 glTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0,
8282 FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
8286 if (FreeDataAfterGenTexture) then
8290 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8291 procedure TglBitmap2D.AfterConstruction;
8294 Target := GL_TEXTURE_2D;
8297 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8298 procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
8301 Size, w, h: Integer;
8302 FormatDesc: TFormatDescriptor;
8304 FormatDesc := TFormatDescriptor.Get(aFormat);
8305 if FormatDesc.IsCompressed then
8306 raise EglBitmapUnsupportedFormat.Create(aFormat);
8308 w := aRight - aLeft;
8309 h := aBottom - aTop;
8310 Size := FormatDesc.GetSize(w, h);
8313 glPixelStorei(GL_PACK_ALIGNMENT, 1);
8314 glReadPixels(aLeft, aTop, w, h, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
8315 SetDataPointer(Temp, aFormat, w, h); //be careful, Data could be freed by this method
8318 if Assigned(Temp) then
8324 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8325 procedure TglBitmap2D.GetDataFromTexture;
8328 TempWidth, TempHeight: Integer;
8329 TempIntFormat: GLint;
8330 IntFormat: TglBitmapFormat;
8331 FormatDesc: TFormatDescriptor;
8336 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
8337 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
8338 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
8340 IntFormat := tfEmpty;
8341 FormatDesc := (TglBitmapFormatDescriptor.GetByFormat(TempIntFormat) as TFormatDescriptor);
8342 IntFormat := FormatDesc.Format;
8344 // Getting data from OpenGL
8345 FormatDesc := TFormatDescriptor.Get(IntFormat);
8346 GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
8348 if FormatDesc.IsCompressed then begin
8349 if not Assigned(glGetCompressedTexImage) then
8350 raise EglBitmap.Create('compressed formats not supported by video adapter');
8351 glGetCompressedTexImage(Target, 0, Temp)
8353 glGetTexImage(Target, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
8354 SetDataPointer(Temp, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
8356 if Assigned(Temp) then
8362 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8363 procedure TglBitmap2D.GenTexture(const aTestTextureSize: Boolean);
8365 BuildWithGlu, PotTex, TexRec: Boolean;
8368 if Assigned(Data) then begin
8369 // Check Texture Size
8370 if (aTestTextureSize) then begin
8371 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
8373 if ((Height > TexSize) or (Width > TexSize)) then
8374 raise EglBitmapSizeToLarge.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
8376 PotTex := IsPowerOfTwo(Height) and IsPowerOfTwo(Width);
8377 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE);
8378 if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
8379 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8383 SetupParameters(BuildWithGlu);
8384 UploadData(Target, BuildWithGlu);
8385 glAreTexturesResident(1, @fID, @fIsResident);
8389 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8390 function TglBitmap2D.FlipHorz: Boolean;
8393 TempDestData, DestData, SourceData: PByte;
8396 result := inherited FlipHorz;
8397 if Assigned(Data) then begin
8399 ImgSize := Height * fRowSize;
8400 GetMem(DestData, ImgSize);
8402 TempDestData := DestData;
8403 Dec(TempDestData, fRowSize + fPixelSize);
8404 for Row := 0 to Height -1 do begin
8405 Inc(TempDestData, fRowSize * 2);
8406 for Col := 0 to Width -1 do begin
8407 Move(SourceData^, TempDestData^, fPixelSize);
8408 Inc(SourceData, fPixelSize);
8409 Dec(TempDestData, fPixelSize);
8412 SetDataPointer(DestData, Format, Width, Height); //be careful, Data could be freed by this method
8415 if Assigned(DestData) then
8422 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8423 function TglBitmap2D.FlipVert: Boolean;
8426 TempDestData, DestData, SourceData: PByte;
8428 result := inherited FlipVert;
8429 if Assigned(Data) then begin
8431 GetMem(DestData, Height * fRowSize);
8433 TempDestData := DestData;
8434 Inc(TempDestData, Width * (Height -1) * fPixelSize);
8435 for Row := 0 to Height -1 do begin
8436 Move(SourceData^, TempDestData^, fRowSize);
8437 Dec(TempDestData, fRowSize);
8438 Inc(SourceData, fRowSize);
8440 SetDataPointer(DestData, Format, Width, Height); //be careful, Data could be freed by this method
8443 if Assigned(DestData) then
8450 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8451 //TglBitmap2D - ToNormalMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8452 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8454 TMatrixItem = record
8459 PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
8460 TglBitmapToNormalMapRec = Record
8462 Heights: array of Single;
8463 MatrixU : array of TMatrixItem;
8464 MatrixV : array of TMatrixItem;
8468 ONE_OVER_255 = 1 / 255;
8470 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8471 procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
8475 with FuncRec do begin
8477 Source.Data.r * LUMINANCE_WEIGHT_R +
8478 Source.Data.g * LUMINANCE_WEIGHT_G +
8479 Source.Data.b * LUMINANCE_WEIGHT_B;
8480 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255;
8484 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8485 procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
8488 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
8491 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8492 procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
8494 TVec = Array[0..2] of Single;
8501 function GetHeight(X, Y: Integer): Single;
8503 with FuncRec do begin
8504 X := Max(0, Min(Size.X -1, X));
8505 Y := Max(0, Min(Size.Y -1, Y));
8506 result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
8511 with FuncRec do begin
8512 with PglBitmapToNormalMapRec(Args)^ do begin
8514 for Idx := Low(MatrixU) to High(MatrixU) do
8515 du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
8518 for Idx := Low(MatrixU) to High(MatrixU) do
8519 dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
8521 Vec[0] := -du * Scale;
8522 Vec[1] := -dv * Scale;
8527 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
8528 if Len <> 0 then begin
8529 Vec[0] := Vec[0] * Len;
8530 Vec[1] := Vec[1] * Len;
8531 Vec[2] := Vec[2] * Len;
8535 Dest.Data.r := Trunc((Vec[0] + 1) * 127.5);
8536 Dest.Data.g := Trunc((Vec[1] + 1) * 127.5);
8537 Dest.Data.b := Trunc((Vec[2] + 1) * 127.5);
8541 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8542 procedure TglBitmap2D.ToNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
8544 Rec: TglBitmapToNormalMapRec;
8546 procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
8548 if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
8549 Matrix[Index].X := X;
8550 Matrix[Index].Y := Y;
8551 Matrix[Index].W := W;
8556 if TFormatDescriptor.Get(Format).IsCompressed then
8557 raise EglBitmapUnsupportedFormat.Create(Format);
8559 if aScale > 100 then
8561 else if aScale < -100 then
8564 Rec.Scale := aScale;
8566 SetLength(Rec.Heights, Width * Height);
8570 SetLength(Rec.MatrixU, 2);
8571 SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
8572 SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
8574 SetLength(Rec.MatrixV, 2);
8575 SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
8576 SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
8580 SetLength(Rec.MatrixU, 6);
8581 SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
8582 SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
8583 SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
8584 SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
8585 SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
8586 SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
8588 SetLength(Rec.MatrixV, 6);
8589 SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
8590 SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
8591 SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
8592 SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
8593 SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
8594 SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
8598 SetLength(Rec.MatrixU, 6);
8599 SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
8600 SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
8601 SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
8602 SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
8603 SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
8604 SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
8606 SetLength(Rec.MatrixV, 6);
8607 SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
8608 SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
8609 SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
8610 SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
8611 SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
8612 SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
8616 SetLength(Rec.MatrixU, 20);
8617 SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
8618 SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
8619 SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
8620 SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
8621 SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
8622 SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
8623 SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
8624 SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
8625 SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
8626 SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
8627 SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
8628 SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
8629 SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
8630 SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
8631 SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
8632 SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
8633 SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
8634 SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
8635 SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
8636 SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
8638 SetLength(Rec.MatrixV, 20);
8639 SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
8640 SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
8641 SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
8642 SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
8643 SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
8644 SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
8645 SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
8646 SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
8647 SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
8648 SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
8649 SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
8650 SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
8651 SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
8652 SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
8653 SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
8654 SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
8655 SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
8656 SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
8657 SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
8658 SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
8663 if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
8664 AddFunc(glBitmapToNormalMapPrepareAlphaFunc, false, @Rec)
8666 AddFunc(glBitmapToNormalMapPrepareFunc, false, @Rec);
8667 AddFunc(glBitmapToNormalMapFunc, false, @Rec);
8669 SetLength(Rec.Heights, 0);
8673 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8674 //TglBitmapCubeMap////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8675 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8676 procedure TglBitmapCubeMap.GenTexture(const aTestTextureSize: Boolean);
8678 Assert(false, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
8681 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8682 procedure TglBitmapCubeMap.AfterConstruction;
8686 if not (GL_VERSION_1_3 or GL_ARB_texture_cube_map or GL_EXT_texture_cube_map) then
8687 raise EglBitmap.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
8690 Target := GL_TEXTURE_CUBE_MAP;
8691 fGenMode := GL_REFLECTION_MAP;
8694 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8695 procedure TglBitmapCubeMap.GenerateCubeMap(const aCubeTarget: Cardinal; const aTestTextureSize: Boolean);
8697 BuildWithGlu: Boolean;
8700 if (aTestTextureSize) then begin
8701 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @TexSize);
8703 if (Height > TexSize) or (Width > TexSize) then
8704 raise EglBitmapSizeToLarge.Create('TglBitmapCubeMap.GenTexture - The size for the Cubemap is to large. It''s may be not conform with the Hardware.');
8706 if not ((IsPowerOfTwo(Height) and IsPowerOfTwo(Width)) or GL_VERSION_2_0 or GL_ARB_texture_non_power_of_two) then
8707 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenTexture - Cubemaps dosn''t support non power of two texture.');
8712 SetupParameters(BuildWithGlu);
8713 UploadData(aCubeTarget, BuildWithGlu);
8716 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8717 procedure TglBitmapCubeMap.Bind(const aEnableTexCoordsGen: Boolean; const aEnableTextureUnit: Boolean);
8719 inherited Bind (aEnableTextureUnit);
8720 if aEnableTexCoordsGen then begin
8721 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, fGenMode);
8722 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, fGenMode);
8723 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, fGenMode);
8724 glEnable(GL_TEXTURE_GEN_S);
8725 glEnable(GL_TEXTURE_GEN_T);
8726 glEnable(GL_TEXTURE_GEN_R);
8730 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8731 procedure TglBitmapCubeMap.Unbind(const aDisableTexCoordsGen: Boolean; const aDisableTextureUnit: Boolean);
8733 inherited Unbind(aDisableTextureUnit);
8734 if aDisableTexCoordsGen then begin
8735 glDisable(GL_TEXTURE_GEN_S);
8736 glDisable(GL_TEXTURE_GEN_T);
8737 glDisable(GL_TEXTURE_GEN_R);
8741 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8742 //TglBitmapNormalMap//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8743 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8745 TVec = Array[0..2] of Single;
8746 TglBitmapNormalMapGetVectorFunc = procedure (out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8748 PglBitmapNormalMapRec = ^TglBitmapNormalMapRec;
8749 TglBitmapNormalMapRec = record
8751 Func: TglBitmapNormalMapGetVectorFunc;
8754 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8755 procedure glBitmapNormalMapPosX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8757 aVec[0] := aHalfSize;
8758 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8759 aVec[2] := - (aPosition.X + 0.5 - aHalfSize);
8762 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8763 procedure glBitmapNormalMapNegX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8765 aVec[0] := - aHalfSize;
8766 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8767 aVec[2] := aPosition.X + 0.5 - aHalfSize;
8770 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8771 procedure glBitmapNormalMapPosY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8773 aVec[0] := aPosition.X + 0.5 - aHalfSize;
8774 aVec[1] := aHalfSize;
8775 aVec[2] := aPosition.Y + 0.5 - aHalfSize;
8778 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8779 procedure glBitmapNormalMapNegY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8781 aVec[0] := aPosition.X + 0.5 - aHalfSize;
8782 aVec[1] := - aHalfSize;
8783 aVec[2] := - (aPosition.Y + 0.5 - aHalfSize);
8786 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8787 procedure glBitmapNormalMapPosZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8789 aVec[0] := aPosition.X + 0.5 - aHalfSize;
8790 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8791 aVec[2] := aHalfSize;
8794 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8795 procedure glBitmapNormalMapNegZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8797 aVec[0] := - (aPosition.X + 0.5 - aHalfSize);
8798 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8799 aVec[2] := - aHalfSize;
8802 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8803 procedure glBitmapNormalMapFunc(var FuncRec: TglBitmapFunctionRec);
8809 with FuncRec do begin
8810 with PglBitmapNormalMapRec(Args)^ do begin
8811 Func(Vec, Position, HalfSize);
8814 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
8815 if Len <> 0 then begin
8816 Vec[0] := Vec[0] * Len;
8817 Vec[1] := Vec[1] * Len;
8818 Vec[2] := Vec[2] * Len;
8821 // Scale Vector and AddVectro
8822 Vec[0] := Vec[0] * 0.5 + 0.5;
8823 Vec[1] := Vec[1] * 0.5 + 0.5;
8824 Vec[2] := Vec[2] * 0.5 + 0.5;
8829 Dest.Data.arr[i] := Round(Vec[i] * 255);
8833 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8834 procedure TglBitmapNormalMap.AfterConstruction;
8837 fGenMode := GL_NORMAL_MAP;
8840 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8841 procedure TglBitmapNormalMap.GenerateNormalMap(const aSize: Integer; const aTestTextureSize: Boolean);
8843 Rec: TglBitmapNormalMapRec;
8844 SizeRec: TglBitmapPixelPosition;
8846 Rec.HalfSize := aSize div 2;
8847 FreeDataAfterGenTexture := false;
8849 SizeRec.Fields := [ffX, ffY];
8854 Rec.Func := glBitmapNormalMapPosX;
8855 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
8856 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X, aTestTextureSize);
8859 Rec.Func := glBitmapNormalMapNegX;
8860 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
8861 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, aTestTextureSize);
8864 Rec.Func := glBitmapNormalMapPosY;
8865 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
8866 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, aTestTextureSize);
8869 Rec.Func := glBitmapNormalMapNegY;
8870 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
8871 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, aTestTextureSize);
8874 Rec.Func := glBitmapNormalMapPosZ;
8875 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
8876 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, aTestTextureSize);
8879 Rec.Func := glBitmapNormalMapNegZ;
8880 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
8881 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, aTestTextureSize);
8886 glBitmapSetDefaultFormat (tfEmpty);
8887 glBitmapSetDefaultMipmap (mmMipmap);
8888 glBitmapSetDefaultFilter (GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
8889 glBitmapSetDefaultWrap (GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
8890 glBitmapSetDefaultSwizzle(GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA);
8892 glBitmapSetDefaultFreeDataAfterGenTexture(true);
8893 glBitmapSetDefaultDeleteTextureOnFree (true);
8895 TFormatDescriptor.Init;
8897 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
8898 OpenGLInitialized := false;
8899 InitOpenGLCS := TCriticalSection.Create;
8903 TFormatDescriptor.Finalize;
8905 {$IFDEF GLB_NATIVE_OGL}
8906 if Assigned(GL_LibHandle) then
8907 glbFreeLibrary(GL_LibHandle);
8909 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
8910 if Assigned(GLU_LibHandle) then
8911 glbFreeLibrary(GLU_LibHandle);
8912 FreeAndNil(InitOpenGLCS);