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}
863 TglBitmapFileTypes = set of TglBitmapFileType;
870 TglBitmapNormalMapFunc = (
876 ////////////////////////////////////////////////////////////////////////////////////////////////////
877 EglBitmap = class(Exception);
878 EglBitmapNotSupported = class(Exception);
879 EglBitmapSizeToLarge = class(EglBitmap);
880 EglBitmapNonPowerOfTwo = class(EglBitmap);
881 EglBitmapUnsupportedFormat = class(EglBitmap)
883 constructor Create(const aFormat: TglBitmapFormat); overload;
884 constructor Create(const aMsg: String; const aFormat: TglBitmapFormat); overload;
887 ////////////////////////////////////////////////////////////////////////////////////////////////////
888 TglBitmapRec4ui = packed record
890 0: (r, g, b, a: Cardinal);
891 1: (arr: array[0..3] of Cardinal);
894 TglBitmapRec4ub = packed record
896 0: (r, g, b, a: Byte);
897 1: (arr: array[0..3] of Byte);
900 TglBitmapRec4ul = packed record
902 0: (r, g, b, a: QWord);
903 1: (arr: array[0..3] of QWord);
906 TglBitmapFormatDescriptor = class(TObject)
909 fBytesPerPixel: Single;
910 fChannelCount: Integer;
911 fMask: TglBitmapRec4ul;
912 fRange: TglBitmapRec4ui;
914 function GetHasRed: Boolean;
915 function GetHasGreen: Boolean;
916 function GetHasBlue: Boolean;
917 function GetHasAlpha: Boolean;
918 function GetHasColor: Boolean;
919 function GetIsGrayscale: Boolean;
921 fFormat: TglBitmapFormat;
922 fWithAlpha: TglBitmapFormat;
923 fWithoutAlpha: TglBitmapFormat;
924 fOpenGLFormat: TglBitmapFormat;
925 fRGBInverted: TglBitmapFormat;
926 fUncompressed: TglBitmapFormat;
928 fBitsPerPixel: Integer;
929 fIsCompressed: Boolean;
931 fPrecision: TglBitmapRec4ub;
932 fShift: TglBitmapRec4ub;
935 fglInternalFormat: GLenum;
936 fglDataFormat: GLenum;
938 procedure SetValues; virtual;
939 procedure CalcValues;
941 property Format: TglBitmapFormat read fFormat;
942 property ChannelCount: Integer read fChannelCount;
943 property IsCompressed: Boolean read fIsCompressed;
944 property BitsPerPixel: Integer read fBitsPerPixel;
945 property BytesPerPixel: Single read fBytesPerPixel;
947 property Precision: TglBitmapRec4ub read fPrecision;
948 property Shift: TglBitmapRec4ub read fShift;
949 property Range: TglBitmapRec4ui read fRange;
950 property Mask: TglBitmapRec4ul read fMask;
952 property RGBInverted: TglBitmapFormat read fRGBInverted;
953 property WithAlpha: TglBitmapFormat read fWithAlpha;
954 property WithoutAlpha: TglBitmapFormat read fWithAlpha;
955 property OpenGLFormat: TglBitmapFormat read fOpenGLFormat;
956 property Uncompressed: TglBitmapFormat read fUncompressed;
958 property glFormat: GLenum read fglFormat;
959 property glInternalFormat: GLenum read fglInternalFormat;
960 property glDataFormat: GLenum read fglDataFormat;
962 property HasRed: Boolean read GetHasRed;
963 property HasGreen: Boolean read GetHasGreen;
964 property HasBlue: Boolean read GetHasBlue;
965 property HasAlpha: Boolean read GetHasAlpha;
966 property HasColor: Boolean read GetHasColor;
967 property IsGrayscale: Boolean read GetIsGrayscale;
971 class function GetByFormat(const aInternalFormat: GLenum): TglBitmapFormatDescriptor;
974 ////////////////////////////////////////////////////////////////////////////////////////////////////
975 TglBitmapPixelData = packed record
976 Data: TglBitmapRec4ui;
977 Range: TglBitmapRec4ui;
978 Format: TglBitmapFormat;
980 PglBitmapPixelData = ^TglBitmapPixelData;
982 TglBitmapPixelPositionFields = set of (ffX, ffY);
983 TglBitmapPixelPosition = record
984 Fields : TglBitmapPixelPositionFields;
989 ////////////////////////////////////////////////////////////////////////////////////////////////////
991 TglBitmapFunctionRec = record
993 Size: TglBitmapPixelPosition;
994 Position: TglBitmapPixelPosition;
995 Source: TglBitmapPixelData;
996 Dest: TglBitmapPixelData;
999 TglBitmapFunction = procedure(var FuncRec: TglBitmapFunctionRec);
1001 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1004 function GetFormatDesc: TglBitmapFormatDescriptor;
1008 fAnisotropic: Integer;
1009 fDeleteTextureOnFree: Boolean;
1010 fFreeDataOnDestroy: Boolean;
1011 fFreeDataAfterGenTexture: Boolean;
1013 fIsResident: GLboolean;
1014 fBorderColor: array[0..3] of Single;
1016 fDimension: TglBitmapPixelPosition;
1017 fMipMap: TglBitmapMipMap;
1018 fFormat: TglBitmapFormat;
1021 fPixelSize: Integer;
1034 fSwizzle: array[0..3] of GLenum;
1038 fCustomName: String;
1039 fCustomNameW: WideString;
1040 fCustomData: Pointer;
1043 function GetWidth: Integer; virtual;
1044 function GetHeight: Integer; virtual;
1046 function GetFileWidth: Integer; virtual;
1047 function GetFileHeight: Integer; virtual;
1050 procedure SetCustomData(const aValue: Pointer);
1051 procedure SetCustomName(const aValue: String);
1052 procedure SetCustomNameW(const aValue: WideString);
1053 procedure SetFreeDataOnDestroy(const aValue: Boolean);
1054 procedure SetDeleteTextureOnFree(const aValue: Boolean);
1055 procedure SetFormat(const aValue: TglBitmapFormat);
1056 procedure SetFreeDataAfterGenTexture(const aValue: Boolean);
1057 procedure SetID(const aValue: Cardinal);
1058 procedure SetMipMap(const aValue: TglBitmapMipMap);
1059 procedure SetTarget(const aValue: Cardinal);
1060 procedure SetAnisotropic(const aValue: Integer);
1063 procedure SetupParameters(out aBuildWithGlu: Boolean);
1064 procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
1065 const aWidth: Integer = -1; const aHeight: Integer = -1); virtual; //be careful, aData could be freed by this method
1066 procedure GenTexture(const aTestTextureSize: Boolean = true); virtual; abstract;
1068 function FlipHorz: Boolean; virtual;
1069 function FlipVert: Boolean; virtual;
1071 property Width: Integer read GetWidth;
1072 property Height: Integer read GetHeight;
1074 property FileWidth: Integer read GetFileWidth;
1075 property FileHeight: Integer read GetFileHeight;
1078 property ID: Cardinal read fID write SetID;
1079 property Target: Cardinal read fTarget write SetTarget;
1080 property Format: TglBitmapFormat read fFormat write SetFormat;
1081 property MipMap: TglBitmapMipMap read fMipMap write SetMipMap;
1082 property Anisotropic: Integer read fAnisotropic write SetAnisotropic;
1084 property FormatDesc: TglBitmapFormatDescriptor read GetFormatDesc;
1086 property Filename: String read fFilename;
1087 property CustomName: String read fCustomName write SetCustomName;
1088 property CustomNameW: WideString read fCustomNameW write SetCustomNameW;
1089 property CustomData: Pointer read fCustomData write SetCustomData;
1091 property DeleteTextureOnFree: Boolean read fDeleteTextureOnFree write SetDeleteTextureOnFree;
1092 property FreeDataOnDestroy: Boolean read fFreeDataOnDestroy write SetFreeDataOnDestroy;
1093 property FreeDataAfterGenTexture: Boolean read fFreeDataAfterGenTexture write SetFreeDataAfterGenTexture;
1095 property Dimension: TglBitmapPixelPosition read fDimension;
1096 property Data: PByte read fData;
1097 property IsResident: GLboolean read fIsResident;
1099 procedure AfterConstruction; override;
1100 procedure BeforeDestruction; override;
1102 procedure PrepareResType(var aResource: String; var aResType: PChar);
1105 procedure LoadFromFile(const aFilename: String);
1106 procedure LoadFromStream(const aStream: TStream); virtual;
1107 procedure LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
1108 const aFormat: TglBitmapFormat; const aArgs: Pointer = nil);
1109 procedure LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil);
1110 procedure LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
1113 procedure SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
1114 procedure SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType); virtual;
1117 function AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer = nil): Boolean; overload;
1118 function AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
1119 const aFormat: TglBitmapFormat; const aArgs: Pointer = nil): Boolean; overload;
1123 function AssignToSurface(out aSurface: PSDL_Surface): Boolean;
1124 function AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
1125 function AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
1126 function AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil;
1127 const aArgs: Pointer = nil): Boolean;
1131 function AssignToBitmap(const aBitmap: TBitmap): Boolean;
1132 function AssignFromBitmap(const aBitmap: TBitmap): Boolean;
1133 function AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
1134 function AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction = nil;
1135 const aArgs: Pointer = nil): Boolean;
1138 {$IFDEF GLB_LAZARUS}
1139 function AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
1140 function AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
1141 function AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
1142 function AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction = nil;
1143 const aArgs: Pointer = nil): Boolean;
1146 function AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil;
1147 const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1148 function AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
1149 const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1151 function AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer = nil): Boolean; virtual;
1152 function AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1153 function AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1154 function AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1156 function AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte = 0): Boolean;
1157 function AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal = 0): Boolean;
1158 function AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single = 0): Boolean;
1160 function AddAlphaFromValue(const aAlpha: Byte): Boolean;
1161 function AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
1162 function AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
1164 function RemoveAlpha: Boolean; virtual;
1167 function Clone: TglBitmap;
1168 function ConvertTo(const aFormat: TglBitmapFormat): Boolean; virtual;
1169 procedure Invert(const aUseRGB: Boolean = true; const aUseAlpha: Boolean = false);
1170 procedure SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
1174 procedure FillWithColor(const aRed, aGreen, aBlue: Byte; const aAlpha: Byte = 255);
1175 procedure FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal = $FFFFFFFF);
1176 procedure FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha : Single = 1);
1179 procedure SetFilter(const aMin, aMag: GLenum);
1181 const S: GLenum = GL_CLAMP_TO_EDGE;
1182 const T: GLenum = GL_CLAMP_TO_EDGE;
1183 const R: GLenum = GL_CLAMP_TO_EDGE);
1184 procedure SetSwizzle(const r, g, b, a: GLenum);
1186 procedure Bind(const aEnableTextureUnit: Boolean = true); virtual;
1187 procedure Unbind(const aDisableTextureUnit: Boolean = true); virtual;
1190 constructor Create; overload;
1191 constructor Create(const aFileName: String); overload;
1192 constructor Create(const aStream: TStream); overload;
1193 constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; aData: PByte = nil); overload;
1194 constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer = nil); overload;
1195 constructor Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil); overload;
1196 constructor Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar); overload;
1198 {$IFDEF GLB_SUPPORT_PNG_READ} function LoadPNG(const aStream: TStream): Boolean; virtual; {$ENDIF}
1199 {$ifdef GLB_SUPPORT_PNG_WRITE} procedure SavePNG(const aStream: TStream); virtual; {$ENDIF}
1201 {$IFDEF GLB_SUPPORT_JPEG_READ} function LoadJPEG(const aStream: TStream): Boolean; virtual; {$ENDIF}
1202 {$IFDEF GLB_SUPPORT_JPEG_WRITE} procedure SaveJPEG(const aStream: TStream); virtual; {$ENDIF}
1204 function LoadBMP(const aStream: TStream): Boolean; virtual;
1205 procedure SaveBMP(const aStream: TStream); virtual;
1207 function LoadTGA(const aStream: TStream): Boolean; virtual;
1208 procedure SaveTGA(const aStream: TStream); virtual;
1210 function LoadDDS(const aStream: TStream): Boolean; virtual;
1211 procedure SaveDDS(const aStream: TStream); virtual;
1214 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1215 TglBitmap1D = class(TglBitmap)
1217 procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
1218 const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
1219 procedure UploadData(const aBuildWithGlu: Boolean);
1222 procedure AfterConstruction; override;
1223 function FlipHorz: Boolean; override;
1224 procedure GenTexture(const aTestTextureSize: Boolean = true); override;
1227 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1228 TglBitmap2D = class(TglBitmap)
1230 fLines: array of PByte;
1231 function GetScanline(const aIndex: Integer): Pointer;
1232 procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
1233 const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
1234 procedure UploadData(const aTarget: GLenum; const aBuildWithGlu: Boolean);
1238 property Scanline[const aIndex: Integer]: Pointer read GetScanline;
1240 procedure AfterConstruction; override;
1242 procedure GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
1243 procedure GetDataFromTexture;
1244 procedure GenTexture(const aTestTextureSize: Boolean = true); override;
1246 function FlipHorz: Boolean; override;
1247 function FlipVert: Boolean; override;
1249 procedure ToNormalMap(const aFunc: TglBitmapNormalMapFunc = nm3x3;
1250 const aScale: Single = 2; const aUseAlpha: Boolean = false);
1253 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1254 TglBitmapCubeMap = class(TglBitmap2D)
1257 procedure GenTexture(const aTestTextureSize: Boolean = true); reintroduce;
1259 procedure AfterConstruction; override;
1260 procedure GenerateCubeMap(const aCubeTarget: Cardinal; const aTestTextureSize: Boolean = true);
1261 procedure Bind(const aEnableTexCoordsGen: Boolean = true; const aEnableTextureUnit: Boolean = true); reintroduce; virtual;
1262 procedure Unbind(const aDisableTexCoordsGen: Boolean = true; const aDisableTextureUnit: Boolean = true); reintroduce; virtual;
1265 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1266 TglBitmapNormalMap = class(TglBitmapCubeMap)
1268 procedure AfterConstruction; override;
1269 procedure GenerateNormalMap(const aSize: Integer = 32; const aTestTextureSize: Boolean = true);
1273 NULL_SIZE: TglBitmapPixelPosition = (Fields: []; X: 0; Y: 0);
1275 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
1276 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
1277 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
1278 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
1279 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
1280 procedure glBitmapSetDefaultWrap(
1281 const S: Cardinal = GL_CLAMP_TO_EDGE;
1282 const T: Cardinal = GL_CLAMP_TO_EDGE;
1283 const R: Cardinal = GL_CLAMP_TO_EDGE);
1285 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
1286 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
1287 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
1288 function glBitmapGetDefaultFormat: TglBitmapFormat;
1289 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
1290 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
1292 function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
1293 function glBitmapRec4ub(const r, g, b, a: Byte): TglBitmapRec4ub;
1294 function glBitmapRec4ui(const r, g, b, a: Cardinal): TglBitmapRec4ui;
1295 function glBitmapRec4ul(const r, g, b, a: QWord): TglBitmapRec4ul;
1296 function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean;
1298 function glBitmapCreateTestTexture(const aFormat: TglBitmapFormat): TglBitmap2D;
1301 glBitmapDefaultDeleteTextureOnFree: Boolean;
1302 glBitmapDefaultFreeDataAfterGenTextures: Boolean;
1303 glBitmapDefaultFormat: TglBitmapFormat;
1304 glBitmapDefaultMipmap: TglBitmapMipMap;
1305 glBitmapDefaultFilterMin: Cardinal;
1306 glBitmapDefaultFilterMag: Cardinal;
1307 glBitmapDefaultWrapS: Cardinal;
1308 glBitmapDefaultWrapT: Cardinal;
1309 glBitmapDefaultWrapR: Cardinal;
1310 glDefaultSwizzle: array[0..3] of GLenum;
1313 function CreateGrayPalette: HPALETTE;
1319 Math, syncobjs, typinfo
1320 {$IF DEFINED(GLB_SUPPORT_JPEG_READ) AND DEFINED(GLB_LAZ_JPEG)}, FPReadJPEG{$IFEND};
1324 QWord = System.UInt64;
1331 ////////////////////////////////////////////////////////////////////////////////////////////////////
1332 TFormatDescriptor = class(TglBitmapFormatDescriptor)
1334 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); virtual; abstract;
1335 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract;
1337 function GetSize(const aSize: TglBitmapPixelPosition): Integer; overload; virtual;
1338 function GetSize(const aWidth, aHeight: Integer): Integer; overload; virtual;
1340 function CreateMappingData: Pointer; virtual;
1341 procedure FreeMappingData(var aMappingData: Pointer); virtual;
1343 function IsEmpty: Boolean; virtual;
1344 function MaskMatch(const aMask: TglBitmapRec4ul): Boolean; virtual;
1346 procedure PreparePixel(out aPixel: TglBitmapPixelData); virtual;
1348 class procedure Init;
1349 class function Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
1350 class function GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
1351 class function GetFromMask(const aMask: TglBitmapRec4ul; const aBitCount: Integer = 0): TFormatDescriptor;
1352 class procedure Clear;
1353 class procedure Finalize;
1355 TFormatDescriptorClass = class of TFormatDescriptor;
1357 TfdEmpty = class(TFormatDescriptor);
1359 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1360 TfdAlphaUB1 = class(TFormatDescriptor) //1* unsigned byte
1361 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1362 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1365 TfdLuminanceUB1 = class(TFormatDescriptor) //1* unsigned byte
1366 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1367 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1370 TfdUniversalUB1 = class(TFormatDescriptor) //1* unsigned byte
1371 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1372 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1375 TfdLuminanceAlphaUB2 = class(TfdLuminanceUB1) //2* unsigned byte
1376 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1377 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1380 TfdRGBub3 = class(TFormatDescriptor) //3* unsigned byte
1381 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1382 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1385 TfdBGRub3 = class(TFormatDescriptor) //3* unsigned byte (inverse)
1386 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1387 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1390 TfdRGBAub4 = class(TfdRGBub3) //3* unsigned byte
1391 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1392 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1395 TfdBGRAub4 = class(TfdBGRub3) //3* unsigned byte (inverse)
1396 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1397 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1400 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1401 TfdAlphaUS1 = class(TFormatDescriptor) //1* unsigned short
1402 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1403 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1406 TfdLuminanceUS1 = class(TFormatDescriptor) //1* unsigned short
1407 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1408 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1411 TfdUniversalUS1 = class(TFormatDescriptor) //1* unsigned short
1412 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1413 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1416 TfdDepthUS1 = class(TFormatDescriptor) //1* unsigned short
1417 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1418 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1421 TfdLuminanceAlphaUS2 = class(TfdLuminanceUS1) //2* unsigned short
1422 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1423 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1426 TfdRGBus3 = class(TFormatDescriptor) //3* unsigned short
1427 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1428 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1431 TfdBGRus3 = class(TFormatDescriptor) //3* unsigned short (inverse)
1432 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1433 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1436 TfdRGBAus4 = class(TfdRGBus3) //4* unsigned short
1437 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1438 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1441 TfdARGBus4 = class(TfdRGBus3) //4* unsigned short
1442 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1443 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1446 TfdBGRAus4 = class(TfdBGRus3) //4* unsigned short (inverse)
1447 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1448 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1451 TfdABGRus4 = class(TfdBGRus3) //4* unsigned short (inverse)
1452 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1453 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1456 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1457 TfdUniversalUI1 = class(TFormatDescriptor) //1* unsigned int
1458 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1459 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1462 TfdDepthUI1 = class(TFormatDescriptor) //1* unsigned int
1463 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1464 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1467 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1468 TfdAlpha4ub1 = class(TfdAlphaUB1)
1469 procedure SetValues; override;
1472 TfdAlpha8ub1 = class(TfdAlphaUB1)
1473 procedure SetValues; override;
1476 TfdAlpha16us1 = class(TfdAlphaUS1)
1477 procedure SetValues; override;
1480 TfdLuminance4ub1 = class(TfdLuminanceUB1)
1481 procedure SetValues; override;
1484 TfdLuminance8ub1 = class(TfdLuminanceUB1)
1485 procedure SetValues; override;
1488 TfdLuminance16us1 = class(TfdLuminanceUS1)
1489 procedure SetValues; override;
1492 TfdLuminance4Alpha4ub2 = class(TfdLuminanceAlphaUB2)
1493 procedure SetValues; override;
1496 TfdLuminance6Alpha2ub2 = class(TfdLuminanceAlphaUB2)
1497 procedure SetValues; override;
1500 TfdLuminance8Alpha8ub2 = class(TfdLuminanceAlphaUB2)
1501 procedure SetValues; override;
1504 TfdLuminance12Alpha4us2 = class(TfdLuminanceAlphaUS2)
1505 procedure SetValues; override;
1508 TfdLuminance16Alpha16us2 = class(TfdLuminanceAlphaUS2)
1509 procedure SetValues; override;
1512 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1513 TfdR3G3B2ub1 = class(TfdUniversalUB1)
1514 procedure SetValues; override;
1517 TfdRGBX4us1 = class(TfdUniversalUS1)
1518 procedure SetValues; override;
1521 TfdXRGB4us1 = class(TfdUniversalUS1)
1522 procedure SetValues; override;
1525 TfdR5G6B5us1 = class(TfdUniversalUS1)
1526 procedure SetValues; override;
1529 TfdRGB5X1us1 = class(TfdUniversalUS1)
1530 procedure SetValues; override;
1533 TfdX1RGB5us1 = class(TfdUniversalUS1)
1534 procedure SetValues; override;
1537 TfdRGB8ub3 = class(TfdRGBub3)
1538 procedure SetValues; override;
1541 TfdRGBX8ui1 = class(TfdUniversalUI1)
1542 procedure SetValues; override;
1545 TfdXRGB8ui1 = class(TfdUniversalUI1)
1546 procedure SetValues; override;
1549 TfdRGB10X2ui1 = class(TfdUniversalUI1)
1550 procedure SetValues; override;
1553 TfdX2RGB10ui1 = class(TfdUniversalUI1)
1554 procedure SetValues; override;
1557 TfdRGB16us3 = class(TfdRGBus3)
1558 procedure SetValues; override;
1561 TfdRGBA4us1 = class(TfdUniversalUS1)
1562 procedure SetValues; override;
1565 TfdARGB4us1 = class(TfdUniversalUS1)
1566 procedure SetValues; override;
1569 TfdRGB5A1us1 = class(TfdUniversalUS1)
1570 procedure SetValues; override;
1573 TfdA1RGB5us1 = class(TfdUniversalUS1)
1574 procedure SetValues; override;
1577 TfdRGBA8ui1 = class(TfdUniversalUI1)
1578 procedure SetValues; override;
1581 TfdARGB8ui1 = class(TfdUniversalUI1)
1582 procedure SetValues; override;
1585 TfdRGBA8ub4 = class(TfdRGBAub4)
1586 procedure SetValues; override;
1589 TfdRGB10A2ui1 = class(TfdUniversalUI1)
1590 procedure SetValues; override;
1593 TfdA2RGB10ui1 = class(TfdUniversalUI1)
1594 procedure SetValues; override;
1597 TfdRGBA16us4 = class(TfdRGBAus4)
1598 procedure SetValues; override;
1601 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1602 TfdBGRX4us1 = class(TfdUniversalUS1)
1603 procedure SetValues; override;
1606 TfdXBGR4us1 = class(TfdUniversalUS1)
1607 procedure SetValues; override;
1610 TfdB5G6R5us1 = class(TfdUniversalUS1)
1611 procedure SetValues; override;
1614 TfdBGR5X1us1 = class(TfdUniversalUS1)
1615 procedure SetValues; override;
1618 TfdX1BGR5us1 = class(TfdUniversalUS1)
1619 procedure SetValues; override;
1622 TfdBGR8ub3 = class(TfdBGRub3)
1623 procedure SetValues; override;
1626 TfdBGRX8ui1 = class(TfdUniversalUI1)
1627 procedure SetValues; override;
1630 TfdXBGR8ui1 = class(TfdUniversalUI1)
1631 procedure SetValues; override;
1634 TfdBGR10X2ui1 = class(TfdUniversalUI1)
1635 procedure SetValues; override;
1638 TfdX2BGR10ui1 = class(TfdUniversalUI1)
1639 procedure SetValues; override;
1642 TfdBGR16us3 = class(TfdBGRus3)
1643 procedure SetValues; override;
1646 TfdBGRA4us1 = class(TfdUniversalUS1)
1647 procedure SetValues; override;
1650 TfdABGR4us1 = class(TfdUniversalUS1)
1651 procedure SetValues; override;
1654 TfdBGR5A1us1 = class(TfdUniversalUS1)
1655 procedure SetValues; override;
1658 TfdA1BGR5us1 = class(TfdUniversalUS1)
1659 procedure SetValues; override;
1662 TfdBGRA8ui1 = class(TfdUniversalUI1)
1663 procedure SetValues; override;
1666 TfdABGR8ui1 = class(TfdUniversalUI1)
1667 procedure SetValues; override;
1670 TfdBGRA8ub4 = class(TfdBGRAub4)
1671 procedure SetValues; override;
1674 TfdBGR10A2ui1 = class(TfdUniversalUI1)
1675 procedure SetValues; override;
1678 TfdA2BGR10ui1 = class(TfdUniversalUI1)
1679 procedure SetValues; override;
1682 TfdBGRA16us4 = class(TfdBGRAus4)
1683 procedure SetValues; override;
1686 TfdDepth16us1 = class(TfdDepthUS1)
1687 procedure SetValues; override;
1690 TfdDepth24ui1 = class(TfdDepthUI1)
1691 procedure SetValues; override;
1694 TfdDepth32ui1 = class(TfdDepthUI1)
1695 procedure SetValues; override;
1698 TfdS3tcDtx1RGBA = class(TFormatDescriptor)
1699 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1700 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1701 procedure SetValues; override;
1704 TfdS3tcDtx3RGBA = class(TFormatDescriptor)
1705 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1706 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1707 procedure SetValues; override;
1710 TfdS3tcDtx5RGBA = class(TFormatDescriptor)
1711 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1712 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1713 procedure SetValues; override;
1716 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1717 TbmpBitfieldFormat = class(TFormatDescriptor)
1719 procedure SetValues(const aBPP: Integer; aMask: TglBitmapRec4ul); overload;
1720 procedure SetValues(const aBBP: Integer; const aPrec, aShift: TglBitmapRec4ub); overload;
1721 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1722 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1725 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1726 TbmpColorTableEnty = packed record
1729 TbmpColorTable = array of TbmpColorTableEnty;
1730 TbmpColorTableFormat = class(TFormatDescriptor)
1732 fBitsPerPixel: Integer;
1733 fColorTable: TbmpColorTable;
1735 procedure SetValues; override; overload;
1737 property ColorTable: TbmpColorTable read fColorTable write fColorTable;
1738 property BitsPerPixel: Integer read fBitsPerPixel write fBitsPerPixel;
1740 procedure SetValues(const aFormat: TglBitmapFormat; const aBPP: Integer; const aPrec, aShift: TglBitmapRec4ub); overload;
1741 procedure CalcValues;
1742 procedure CreateColorTable;
1744 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1745 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1746 destructor Destroy; override;
1750 LUMINANCE_WEIGHT_R = 0.30;
1751 LUMINANCE_WEIGHT_G = 0.59;
1752 LUMINANCE_WEIGHT_B = 0.11;
1754 ALPHA_WEIGHT_R = 0.30;
1755 ALPHA_WEIGHT_G = 0.59;
1756 ALPHA_WEIGHT_B = 0.11;
1758 DEPTH_WEIGHT_R = 0.333333333;
1759 DEPTH_WEIGHT_G = 0.333333333;
1760 DEPTH_WEIGHT_B = 0.333333333;
1762 FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
1773 TfdLuminance4Alpha4ub2,
1774 TfdLuminance6Alpha2ub2,
1775 TfdLuminance8Alpha8ub2,
1776 TfdLuminance12Alpha4us2,
1777 TfdLuminance16Alpha16us2,
1836 FormatDescriptorCS: TCriticalSection;
1837 FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
1839 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1840 constructor EglBitmapUnsupportedFormat.Create(const aFormat: TglBitmapFormat);
1842 inherited Create('unsupported format: ' + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1845 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1846 constructor EglBitmapUnsupportedFormat.Create(const aMsg: String; const aFormat: TglBitmapFormat);
1848 inherited Create(aMsg + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1851 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1852 function glBitmapPosition(X: Integer; Y: Integer): TglBitmapPixelPosition;
1854 result.Fields := [];
1857 result.Fields := result.Fields + [ffX];
1859 result.Fields := result.Fields + [ffY];
1861 result.X := Max(0, X);
1862 result.Y := Max(0, Y);
1865 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1866 function glBitmapRec4ub(const r, g, b, a: Byte): TglBitmapRec4ub;
1874 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1875 function glBitmapRec4ui(const r, g, b, a: Cardinal): TglBitmapRec4ui;
1883 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1884 function glBitmapRec4ul(const r, g, b, a: QWord): TglBitmapRec4ul;
1892 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1893 function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean;
1898 for i := 0 to high(r1.arr) do
1899 if (r1.arr[i] <> r2.arr[i]) then
1904 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1905 function glBitmapCreateTestTexture(const aFormat: TglBitmapFormat): TglBitmap2D;
1907 desc: TFormatDescriptor;
1911 px: TglBitmapPixelData;
1914 desc := TFormatDescriptor.Get(aFormat);
1915 if (desc.IsCompressed) or (desc.glFormat = 0) then
1918 p := GetMem(ceil(25 * desc.BytesPerPixel)); // 5 x 5 pixel
1919 md := desc.CreateMappingData;
1922 desc.PreparePixel(px);
1924 for x := 0 to 4 do begin
1925 px.Data := glBitmapRec4ui(0, 0, 0, 0);
1926 for i := 0 to 3 do begin
1927 if ((y < 3) and (y = i)) or
1928 ((y = 3) and (i < 3)) or
1929 ((y = 4) and (i = 3))
1931 px.Data.arr[i] := Trunc(px.Range.arr[i] / 4 * x)
1932 else if ((y < 4) and (i = 3)) or
1933 ((y = 4) and (i < 3))
1935 px.Data.arr[i] := px.Range.arr[i]
1937 px.Data.arr[i] := 0; //px.Range.arr[i];
1939 desc.Map(px, tmp, md);
1942 desc.FreeMappingData(md);
1945 result := TglBitmap2D.Create(glBitmapPosition(5, 5), aFormat, p);
1946 result.FreeDataOnDestroy := true;
1947 result.FreeDataAfterGenTexture := false;
1948 result.SetFilter(GL_NEAREST, GL_NEAREST);
1951 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1952 function glBitmapShiftRec(const r, g, b, a: Byte): TglBitmapRec4ub;
1960 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1961 function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
1967 tfAlpha4ub1, tfAlpha8ub1,
1968 tfLuminance4ub1, tfLuminance8ub1, tfR3G3B2ub1,
1971 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
1972 tfRGBX4us1, tfXRGB4us1, tfRGB5X1us1, tfX1RGB5us1, tfR5G6B5us1, tfRGB5A1us1, tfA1RGB5us1, tfRGBA4us1, tfARGB4us1,
1973 tfBGRX4us1, tfXBGR4us1, tfBGR5X1us1, tfX1BGR5us1, tfB5G6R5us1, tfBGR5A1us1, tfA1BGR5us1, tfBGRA4us1, tfABGR4us1,
1976 tfBGR8ub3, tfRGB8ub3,
1979 tfRGBX8ui1, tfXRGB8ui1, tfRGB10X2ui1, tfX2RGB10ui1, tfRGBA8ui1, tfARGB8ui1, tfRGBA8ub4, tfRGB10A2ui1, tfA2RGB10ui1,
1980 tfBGRX8ui1, tfXBGR8ui1, tfBGR10X2ui1, tfX2BGR10ui1, tfBGRA8ui1, tfABGR8ui1, tfBGRA8ub4, tfBGR10A2ui1, tfA2BGR10ui1])
1982 result := result + [ ftBMP ];
1986 tfAlpha4ub1, tfAlpha8ub1, tfLuminance4ub1, tfLuminance8ub1,
1989 tfAlpha16us1, tfLuminance16us1,
1990 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
1991 tfX1RGB5us1, tfARGB4us1, tfA1RGB5us1, tfDepth16us1,
1997 tfX2RGB10ui1, tfARGB8ui1, tfBGRA8ub4, tfA2RGB10ui1,
1998 tfDepth24ui1, tfDepth32ui1])
2000 result := result + [ftTGA];
2002 if not (aFormat in [tfEmpty, tfRGB16us3, tfBGR16us3]) then
2003 result := result + [ftDDS];
2005 {$IFDEF GLB_SUPPORT_PNG_WRITE}
2007 tfAlpha8ub1, tfLuminance8ub1, tfLuminance8Alpha8ub2,
2008 tfRGB8ub3, tfRGBA8ui1,
2009 tfBGR8ub3, tfBGRA8ui1] then
2010 result := result + [ftPNG];
2013 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
2014 if aFormat in [tfAlpha8ub1, tfLuminance8ub1, tfRGB8ub3, tfBGR8ub3] then
2015 result := result + [ftJPEG];
2019 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2020 function IsPowerOfTwo(aNumber: Integer): Boolean;
2022 while (aNumber and 1) = 0 do
2023 aNumber := aNumber shr 1;
2024 result := aNumber = 1;
2027 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2028 function GetTopMostBit(aBitSet: QWord): Integer;
2031 while aBitSet > 0 do begin
2033 aBitSet := aBitSet shr 1;
2037 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2038 function CountSetBits(aBitSet: QWord): Integer;
2041 while aBitSet > 0 do begin
2042 if (aBitSet and 1) = 1 then
2044 aBitSet := aBitSet shr 1;
2048 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2049 function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
2052 LUMINANCE_WEIGHT_R * aPixel.Data.r +
2053 LUMINANCE_WEIGHT_G * aPixel.Data.g +
2054 LUMINANCE_WEIGHT_B * aPixel.Data.b);
2057 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2058 function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
2061 DEPTH_WEIGHT_R * aPixel.Data.r +
2062 DEPTH_WEIGHT_G * aPixel.Data.g +
2063 DEPTH_WEIGHT_B * aPixel.Data.b);
2066 {$IFDEF GLB_NATIVE_OGL}
2067 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2068 //OpenGLInitialization///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2069 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2071 GL_LibHandle: Pointer = nil;
2073 function glbGetProcAddress(aProcName: PAnsiChar; aLibHandle: Pointer = nil; const aRaiseOnErr: Boolean = true): Pointer;
2075 if not Assigned(aLibHandle) then
2076 aLibHandle := GL_LibHandle;
2078 {$IF DEFINED(GLB_WIN)}
2079 result := GetProcAddress({%H-}HMODULE(aLibHandle), aProcName);
2080 if Assigned(result) then
2083 if Assigned(wglGetProcAddress) then
2084 result := wglGetProcAddress(aProcName);
2085 {$ELSEIF DEFINED(GLB_LINUX)}
2086 if Assigned(glXGetProcAddress) then begin
2087 result := glXGetProcAddress(aProcName);
2088 if Assigned(result) then
2092 if Assigned(glXGetProcAddressARB) then begin
2093 result := glXGetProcAddressARB(aProcName);
2094 if Assigned(result) then
2098 result := dlsym(aLibHandle, aProcName);
2100 if not Assigned(result) and aRaiseOnErr then
2101 raise EglBitmap.Create('unable to load procedure form library: ' + aProcName);
2104 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
2106 GLU_LibHandle: Pointer = nil;
2107 OpenGLInitialized: Boolean;
2108 InitOpenGLCS: TCriticalSection;
2110 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2111 procedure glbInitOpenGL;
2113 ////////////////////////////////////////////////////////////////////////////////
2114 function glbLoadLibrary(const aName: PChar): Pointer;
2116 {$IF DEFINED(GLB_WIN)}
2117 result := {%H-}Pointer(LoadLibrary(aName));
2118 {$ELSEIF DEFINED(GLB_LINUX)}
2119 result := dlopen(Name, RTLD_LAZY);
2125 ////////////////////////////////////////////////////////////////////////////////
2126 function glbFreeLibrary(const aLibHandle: Pointer): Boolean;
2129 if not Assigned(aLibHandle) then
2132 {$IF DEFINED(GLB_WIN)}
2133 Result := FreeLibrary({%H-}HINST(aLibHandle));
2134 {$ELSEIF DEFINED(GLB_LINUX)}
2135 Result := dlclose(aLibHandle) = 0;
2140 if Assigned(GL_LibHandle) then
2141 glbFreeLibrary(GL_LibHandle);
2143 if Assigned(GLU_LibHandle) then
2144 glbFreeLibrary(GLU_LibHandle);
2146 GL_LibHandle := glbLoadLibrary(libopengl);
2147 if not Assigned(GL_LibHandle) then
2148 raise EglBitmap.Create('unable to load library: ' + libopengl);
2150 GLU_LibHandle := glbLoadLibrary(libglu);
2151 if not Assigned(GLU_LibHandle) then
2152 raise EglBitmap.Create('unable to load library: ' + libglu);
2154 {$IF DEFINED(GLB_WIN)}
2155 wglGetProcAddress := glbGetProcAddress('wglGetProcAddress');
2156 {$ELSEIF DEFINED(GLB_LINUX)}
2157 glXGetProcAddress := glbGetProcAddress('glXGetProcAddress');
2158 glXGetProcAddressARB := glbGetProcAddress('glXGetProcAddressARB');
2161 glEnable := glbGetProcAddress('glEnable');
2162 glDisable := glbGetProcAddress('glDisable');
2163 glGetString := glbGetProcAddress('glGetString');
2164 glGetIntegerv := glbGetProcAddress('glGetIntegerv');
2165 glTexParameteri := glbGetProcAddress('glTexParameteri');
2166 glTexParameteriv := glbGetProcAddress('glTexParameteriv');
2167 glTexParameterfv := glbGetProcAddress('glTexParameterfv');
2168 glGetTexParameteriv := glbGetProcAddress('glGetTexParameteriv');
2169 glGetTexParameterfv := glbGetProcAddress('glGetTexParameterfv');
2170 glGetTexLevelParameteriv := glbGetProcAddress('glGetTexLevelParameteriv');
2171 glGetTexLevelParameterfv := glbGetProcAddress('glGetTexLevelParameterfv');
2172 glTexGeni := glbGetProcAddress('glTexGeni');
2173 glGenTextures := glbGetProcAddress('glGenTextures');
2174 glBindTexture := glbGetProcAddress('glBindTexture');
2175 glDeleteTextures := glbGetProcAddress('glDeleteTextures');
2176 glAreTexturesResident := glbGetProcAddress('glAreTexturesResident');
2177 glReadPixels := glbGetProcAddress('glReadPixels');
2178 glPixelStorei := glbGetProcAddress('glPixelStorei');
2179 glTexImage1D := glbGetProcAddress('glTexImage1D');
2180 glTexImage2D := glbGetProcAddress('glTexImage2D');
2181 glGetTexImage := glbGetProcAddress('glGetTexImage');
2183 gluBuild1DMipmaps := glbGetProcAddress('gluBuild1DMipmaps', GLU_LibHandle);
2184 gluBuild2DMipmaps := glbGetProcAddress('gluBuild2DMipmaps', GLU_LibHandle);
2188 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2189 procedure glbReadOpenGLExtensions;
2192 MajorVersion, MinorVersion: Integer;
2194 ///////////////////////////////////////////////////////////////////////////////////////////
2195 procedure TrimVersionString(aBuffer: AnsiString; out aMajor, aMinor: Integer);
2202 Separator := Pos(AnsiString('.'), aBuffer);
2203 if (Separator > 1) and (Separator < Length(aBuffer)) and
2204 (aBuffer[Separator - 1] in ['0'..'9']) and
2205 (aBuffer[Separator + 1] in ['0'..'9']) then begin
2208 while (Separator > 0) and (aBuffer[Separator] in ['0'..'9']) do
2211 Delete(aBuffer, 1, Separator);
2212 Separator := Pos(AnsiString('.'), aBuffer) + 1;
2214 while (Separator <= Length(aBuffer)) and (AnsiChar(aBuffer[Separator]) in ['0'..'9']) do
2217 Delete(aBuffer, Separator, 255);
2218 Separator := Pos(AnsiString('.'), aBuffer);
2220 aMajor := StrToInt(Copy(String(aBuffer), 1, Separator - 1));
2221 aMinor := StrToInt(Copy(String(aBuffer), Separator + 1, 1));
2225 ///////////////////////////////////////////////////////////////////////////////////////////
2226 function CheckExtension(const Extension: AnsiString): Boolean;
2230 ExtPos := Pos(Extension, Buffer);
2231 result := ExtPos > 0;
2233 result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
2236 ///////////////////////////////////////////////////////////////////////////////////////////
2237 function CheckVersion(const aMajor, aMinor: Integer): Boolean;
2239 result := (MajorVersion > aMajor) or ((MajorVersion = aMajor) and (MinorVersion >= aMinor));
2243 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
2246 if not OpenGLInitialized then begin
2248 OpenGLInitialized := true;
2256 Buffer := glGetString(GL_VERSION);
2257 TrimVersionString(Buffer, MajorVersion, MinorVersion);
2259 GL_VERSION_1_2 := CheckVersion(1, 2);
2260 GL_VERSION_1_3 := CheckVersion(1, 3);
2261 GL_VERSION_1_4 := CheckVersion(1, 4);
2262 GL_VERSION_2_0 := CheckVersion(2, 0);
2263 GL_VERSION_3_3 := CheckVersion(3, 3);
2266 Buffer := glGetString(GL_EXTENSIONS);
2267 GL_ARB_texture_border_clamp := CheckExtension('GL_ARB_texture_border_clamp');
2268 GL_ARB_texture_non_power_of_two := CheckExtension('GL_ARB_texture_non_power_of_two');
2269 GL_ARB_texture_swizzle := CheckExtension('GL_ARB_texture_swizzle');
2270 GL_ARB_texture_cube_map := CheckExtension('GL_ARB_texture_cube_map');
2271 GL_ARB_texture_rectangle := CheckExtension('GL_ARB_texture_rectangle');
2272 GL_ARB_texture_mirrored_repeat := CheckExtension('GL_ARB_texture_mirrored_repeat');
2273 GL_EXT_texture_edge_clamp := CheckExtension('GL_EXT_texture_edge_clamp');
2274 GL_EXT_texture_filter_anisotropic := CheckExtension('GL_EXT_texture_filter_anisotropic');
2275 GL_EXT_texture_rectangle := CheckExtension('GL_EXT_texture_rectangle');
2276 GL_EXT_texture_swizzle := CheckExtension('GL_EXT_texture_swizzle');
2277 GL_EXT_texture_cube_map := CheckExtension('GL_EXT_texture_cube_map');
2278 GL_NV_texture_rectangle := CheckExtension('GL_NV_texture_rectangle');
2279 GL_IBM_texture_mirrored_repeat := CheckExtension('GL_IBM_texture_mirrored_repeat');
2280 GL_SGIS_generate_mipmap := CheckExtension('GL_SGIS_generate_mipmap');
2282 if GL_VERSION_1_3 then begin
2283 glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1D');
2284 glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2D');
2285 glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImage');
2287 glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1DARB', nil, false);
2288 glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2DARB', nil, false);
2289 glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImageARB', nil, false);
2294 {$IFDEF GLB_SDL_IMAGE}
2295 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2296 // SDL Image Helper /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2297 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2298 function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
2300 result := TStream(context^.unknown.data1).Seek(offset, whence);
2303 function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
2305 result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
2308 function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
2310 result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
2313 function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
2318 function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
2320 result := SDL_AllocRW;
2322 if result = nil then
2323 raise EglBitmap.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
2325 result^.seek := glBitmapRWseek;
2326 result^.read := glBitmapRWread;
2327 result^.write := glBitmapRWwrite;
2328 result^.close := glBitmapRWclose;
2329 result^.unknown.data1 := Stream;
2333 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2334 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
2336 glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
2339 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2340 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
2342 glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
2345 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2346 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
2348 glBitmapDefaultMipmap := aValue;
2351 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2352 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
2354 glBitmapDefaultFormat := aFormat;
2357 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2358 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
2360 glBitmapDefaultFilterMin := aMin;
2361 glBitmapDefaultFilterMag := aMag;
2364 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2365 procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
2367 glBitmapDefaultWrapS := S;
2368 glBitmapDefaultWrapT := T;
2369 glBitmapDefaultWrapR := R;
2372 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2373 procedure glBitmapSetDefaultSwizzle(const r: GLenum = GL_RED; g: GLenum = GL_GREEN; b: GLenum = GL_BLUE; a: GLenum = GL_ALPHA);
2375 glDefaultSwizzle[0] := r;
2376 glDefaultSwizzle[1] := g;
2377 glDefaultSwizzle[2] := b;
2378 glDefaultSwizzle[3] := a;
2381 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2382 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
2384 result := glBitmapDefaultDeleteTextureOnFree;
2387 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2388 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
2390 result := glBitmapDefaultFreeDataAfterGenTextures;
2393 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2394 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
2396 result := glBitmapDefaultMipmap;
2399 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2400 function glBitmapGetDefaultFormat: TglBitmapFormat;
2402 result := glBitmapDefaultFormat;
2405 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2406 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
2408 aMin := glBitmapDefaultFilterMin;
2409 aMag := glBitmapDefaultFilterMag;
2412 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2413 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
2415 S := glBitmapDefaultWrapS;
2416 T := glBitmapDefaultWrapT;
2417 R := glBitmapDefaultWrapR;
2420 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2421 procedure glBitmapGetDefaultSwizzle(var r, g, b, a: GLenum);
2423 r := glDefaultSwizzle[0];
2424 g := glDefaultSwizzle[1];
2425 b := glDefaultSwizzle[2];
2426 a := glDefaultSwizzle[3];
2429 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2430 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2431 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2432 function TFormatDescriptor.GetSize(const aSize: TglBitmapPixelPosition): Integer;
2436 if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
2437 w := Max(1, aSize.X);
2438 h := Max(1, aSize.Y);
2439 result := GetSize(w, h);
2444 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2445 function TFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer;
2448 if (aWidth <= 0) or (aHeight <= 0) then
2450 result := Ceil(aWidth * aHeight * BytesPerPixel);
2453 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2454 function TFormatDescriptor.CreateMappingData: Pointer;
2459 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2460 procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
2465 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2466 function TFormatDescriptor.IsEmpty: Boolean;
2468 result := (fFormat = tfEmpty);
2471 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2472 function TFormatDescriptor.MaskMatch(const aMask: TglBitmapRec4ul): Boolean;
2478 if (aMask.r = 0) and (aMask.g = 0) and (aMask.b = 0) and (aMask.a = 0) then
2479 raise EglBitmap.Create('FormatCheckFormat - All Masks are 0');
2482 if (aMask.arr[i] <> m.arr[i]) then
2487 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2488 procedure TFormatDescriptor.PreparePixel(out aPixel: TglBitmapPixelData);
2490 FillChar(aPixel{%H-}, SizeOf(aPixel), 0);
2491 aPixel.Data := Range;
2492 aPixel.Format := fFormat;
2493 aPixel.Range := Range;
2496 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2497 //TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2498 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2499 procedure TfdAlphaUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2501 aData^ := aPixel.Data.a;
2505 procedure TfdAlphaUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2510 aPixel.Data.a := aData^;
2514 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2515 //TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2516 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2517 procedure TfdLuminanceUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2519 aData^ := LuminanceWeight(aPixel);
2523 procedure TfdLuminanceUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2525 aPixel.Data.r := aData^;
2526 aPixel.Data.g := aData^;
2527 aPixel.Data.b := aData^;
2532 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2533 //TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2534 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2535 procedure TfdUniversalUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2541 if (Range.arr[i] > 0) then
2542 aData^ := aData^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2546 procedure TfdUniversalUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2551 aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and Range.arr[i];
2555 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2556 //TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2557 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2558 procedure TfdLuminanceAlphaUB2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2560 inherited Map(aPixel, aData, aMapData);
2561 aData^ := aPixel.Data.a;
2565 procedure TfdLuminanceAlphaUB2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2567 inherited Unmap(aData, aPixel, aMapData);
2568 aPixel.Data.a := aData^;
2572 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2573 //TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2574 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2575 procedure TfdRGBub3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2577 aData^ := aPixel.Data.r;
2579 aData^ := aPixel.Data.g;
2581 aData^ := aPixel.Data.b;
2585 procedure TfdRGBub3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2587 aPixel.Data.r := aData^;
2589 aPixel.Data.g := aData^;
2591 aPixel.Data.b := aData^;
2596 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2597 //TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2598 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2599 procedure TfdBGRub3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2601 aData^ := aPixel.Data.b;
2603 aData^ := aPixel.Data.g;
2605 aData^ := aPixel.Data.r;
2609 procedure TfdBGRub3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2611 aPixel.Data.b := aData^;
2613 aPixel.Data.g := aData^;
2615 aPixel.Data.r := aData^;
2620 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2621 //TfdRGBA_UB4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2622 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2623 procedure TfdRGBAub4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2625 inherited Map(aPixel, aData, aMapData);
2626 aData^ := aPixel.Data.a;
2630 procedure TfdRGBAub4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2632 inherited Unmap(aData, aPixel, aMapData);
2633 aPixel.Data.a := aData^;
2637 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2638 //TfdBGRA_UB4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2639 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2640 procedure TfdBGRAub4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2642 inherited Map(aPixel, aData, aMapData);
2643 aData^ := aPixel.Data.a;
2647 procedure TfdBGRAub4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2649 inherited Unmap(aData, aPixel, aMapData);
2650 aPixel.Data.a := aData^;
2654 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2655 //TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2656 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2657 procedure TfdAlphaUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2659 PWord(aData)^ := aPixel.Data.a;
2663 procedure TfdAlphaUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2668 aPixel.Data.a := PWord(aData)^;
2672 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2673 //TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2674 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2675 procedure TfdLuminanceUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2677 PWord(aData)^ := LuminanceWeight(aPixel);
2681 procedure TfdLuminanceUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2683 aPixel.Data.r := PWord(aData)^;
2684 aPixel.Data.g := PWord(aData)^;
2685 aPixel.Data.b := PWord(aData)^;
2690 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2691 //TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2692 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2693 procedure TfdUniversalUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2699 if (Range.arr[i] > 0) then
2700 PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2704 procedure TfdUniversalUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2709 aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and Range.arr[i];
2713 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2714 //TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2715 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2716 procedure TfdDepthUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2718 PWord(aData)^ := DepthWeight(aPixel);
2722 procedure TfdDepthUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2724 aPixel.Data.r := PWord(aData)^;
2725 aPixel.Data.g := PWord(aData)^;
2726 aPixel.Data.b := PWord(aData)^;
2727 aPixel.Data.a := PWord(aData)^;;
2731 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2732 //TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2733 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2734 procedure TfdLuminanceAlphaUS2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2736 inherited Map(aPixel, aData, aMapData);
2737 PWord(aData)^ := aPixel.Data.a;
2741 procedure TfdLuminanceAlphaUS2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2743 inherited Unmap(aData, aPixel, aMapData);
2744 aPixel.Data.a := PWord(aData)^;
2748 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2749 //TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2750 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2751 procedure TfdRGBus3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2753 PWord(aData)^ := aPixel.Data.r;
2755 PWord(aData)^ := aPixel.Data.g;
2757 PWord(aData)^ := aPixel.Data.b;
2761 procedure TfdRGBus3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2763 aPixel.Data.r := PWord(aData)^;
2765 aPixel.Data.g := PWord(aData)^;
2767 aPixel.Data.b := PWord(aData)^;
2772 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2773 //TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2774 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2775 procedure TfdBGRus3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2777 PWord(aData)^ := aPixel.Data.b;
2779 PWord(aData)^ := aPixel.Data.g;
2781 PWord(aData)^ := aPixel.Data.r;
2785 procedure TfdBGRus3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2787 aPixel.Data.b := PWord(aData)^;
2789 aPixel.Data.g := PWord(aData)^;
2791 aPixel.Data.r := PWord(aData)^;
2796 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2797 //TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2798 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2799 procedure TfdRGBAus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2801 inherited Map(aPixel, aData, aMapData);
2802 PWord(aData)^ := aPixel.Data.a;
2806 procedure TfdRGBAus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2808 inherited Unmap(aData, aPixel, aMapData);
2809 aPixel.Data.a := PWord(aData)^;
2813 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2814 //TfdARGB_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2815 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2816 procedure TfdARGBus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2818 PWord(aData)^ := aPixel.Data.a;
2820 inherited Map(aPixel, aData, aMapData);
2823 procedure TfdARGBus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2825 aPixel.Data.a := PWord(aData)^;
2827 inherited Unmap(aData, aPixel, aMapData);
2830 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2831 //TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2832 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2833 procedure TfdBGRAus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2835 inherited Map(aPixel, aData, aMapData);
2836 PWord(aData)^ := aPixel.Data.a;
2840 procedure TfdBGRAus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2842 inherited Unmap(aData, aPixel, aMapData);
2843 aPixel.Data.a := PWord(aData)^;
2847 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2848 //TfdABGR_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2849 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2850 procedure TfdABGRus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2852 PWord(aData)^ := aPixel.Data.a;
2854 inherited Map(aPixel, aData, aMapData);
2857 procedure TfdABGRus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2859 aPixel.Data.a := PWord(aData)^;
2861 inherited Unmap(aData, aPixel, aMapData);
2864 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2865 //TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2866 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2867 procedure TfdUniversalUI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2871 PCardinal(aData)^ := 0;
2873 if (Range.arr[i] > 0) then
2874 PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2878 procedure TfdUniversalUI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2883 aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and Range.arr[i];
2887 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2888 //TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2889 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2890 procedure TfdDepthUI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2892 PCardinal(aData)^ := DepthWeight(aPixel);
2896 procedure TfdDepthUI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2898 aPixel.Data.r := PCardinal(aData)^;
2899 aPixel.Data.g := PCardinal(aData)^;
2900 aPixel.Data.b := PCardinal(aData)^;
2901 aPixel.Data.a := PCardinal(aData)^;
2905 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2906 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2907 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2908 procedure TfdAlpha4ub1.SetValues;
2910 inherited SetValues;
2912 fFormat := tfAlpha4ub1;
2913 fWithAlpha := tfAlpha4ub1;
2914 fOpenGLFormat := tfAlpha4ub1;
2915 fPrecision := glBitmapRec4ub(0, 0, 0, 8);
2916 fShift := glBitmapRec4ub(0, 0, 0, 0);
2917 fglFormat := GL_ALPHA;
2918 fglInternalFormat := GL_ALPHA4;
2919 fglDataFormat := GL_UNSIGNED_BYTE;
2922 procedure TfdAlpha8ub1.SetValues;
2924 inherited SetValues;
2926 fFormat := tfAlpha8ub1;
2927 fWithAlpha := tfAlpha8ub1;
2928 fOpenGLFormat := tfAlpha8ub1;
2929 fPrecision := glBitmapRec4ub(0, 0, 0, 8);
2930 fShift := glBitmapRec4ub(0, 0, 0, 0);
2931 fglFormat := GL_ALPHA;
2932 fglInternalFormat := GL_ALPHA8;
2933 fglDataFormat := GL_UNSIGNED_BYTE;
2936 procedure TfdAlpha16us1.SetValues;
2938 inherited SetValues;
2939 fBitsPerPixel := 16;
2940 fFormat := tfAlpha16us1;
2941 fWithAlpha := tfAlpha16us1;
2942 fOpenGLFormat := tfAlpha16us1;
2943 fPrecision := glBitmapRec4ub(0, 0, 0, 16);
2944 fShift := glBitmapRec4ub(0, 0, 0, 0);
2945 fglFormat := GL_ALPHA;
2946 fglInternalFormat := GL_ALPHA16;
2947 fglDataFormat := GL_UNSIGNED_SHORT;
2950 procedure TfdLuminance4ub1.SetValues;
2952 inherited SetValues;
2954 fFormat := tfLuminance4ub1;
2955 fWithAlpha := tfLuminance4Alpha4ub2;
2956 fWithoutAlpha := tfLuminance4ub1;
2957 fOpenGLFormat := tfLuminance4ub1;
2958 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
2959 fShift := glBitmapRec4ub(0, 0, 0, 0);
2960 fglFormat := GL_LUMINANCE;
2961 fglInternalFormat := GL_LUMINANCE4;
2962 fglDataFormat := GL_UNSIGNED_BYTE;
2965 procedure TfdLuminance8ub1.SetValues;
2967 inherited SetValues;
2969 fFormat := tfLuminance8ub1;
2970 fWithAlpha := tfLuminance8Alpha8ub2;
2971 fWithoutAlpha := tfLuminance8ub1;
2972 fOpenGLFormat := tfLuminance8ub1;
2973 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
2974 fShift := glBitmapRec4ub(0, 0, 0, 0);
2975 fglFormat := GL_LUMINANCE;
2976 fglInternalFormat := GL_LUMINANCE8;
2977 fglDataFormat := GL_UNSIGNED_BYTE;
2980 procedure TfdLuminance16us1.SetValues;
2982 inherited SetValues;
2983 fBitsPerPixel := 16;
2984 fFormat := tfLuminance16us1;
2985 fWithAlpha := tfLuminance16Alpha16us2;
2986 fWithoutAlpha := tfLuminance16us1;
2987 fOpenGLFormat := tfLuminance16us1;
2988 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
2989 fShift := glBitmapRec4ub( 0, 0, 0, 0);
2990 fglFormat := GL_LUMINANCE;
2991 fglInternalFormat := GL_LUMINANCE16;
2992 fglDataFormat := GL_UNSIGNED_SHORT;
2995 procedure TfdLuminance4Alpha4ub2.SetValues;
2997 inherited SetValues;
2998 fBitsPerPixel := 16;
2999 fFormat := tfLuminance4Alpha4ub2;
3000 fWithAlpha := tfLuminance4Alpha4ub2;
3001 fWithoutAlpha := tfLuminance4ub1;
3002 fOpenGLFormat := tfLuminance4Alpha4ub2;
3003 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
3004 fShift := glBitmapRec4ub(0, 0, 0, 8);
3005 fglFormat := GL_LUMINANCE_ALPHA;
3006 fglInternalFormat := GL_LUMINANCE4_ALPHA4;
3007 fglDataFormat := GL_UNSIGNED_BYTE;
3010 procedure TfdLuminance6Alpha2ub2.SetValues;
3012 inherited SetValues;
3013 fBitsPerPixel := 16;
3014 fFormat := tfLuminance6Alpha2ub2;
3015 fWithAlpha := tfLuminance6Alpha2ub2;
3016 fWithoutAlpha := tfLuminance8ub1;
3017 fOpenGLFormat := tfLuminance6Alpha2ub2;
3018 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
3019 fShift := glBitmapRec4ub(0, 0, 0, 8);
3020 fglFormat := GL_LUMINANCE_ALPHA;
3021 fglInternalFormat := GL_LUMINANCE6_ALPHA2;
3022 fglDataFormat := GL_UNSIGNED_BYTE;
3025 procedure TfdLuminance8Alpha8ub2.SetValues;
3027 inherited SetValues;
3028 fBitsPerPixel := 16;
3029 fFormat := tfLuminance8Alpha8ub2;
3030 fWithAlpha := tfLuminance8Alpha8ub2;
3031 fWithoutAlpha := tfLuminance8ub1;
3032 fOpenGLFormat := tfLuminance8Alpha8ub2;
3033 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
3034 fShift := glBitmapRec4ub(0, 0, 0, 8);
3035 fglFormat := GL_LUMINANCE_ALPHA;
3036 fglInternalFormat := GL_LUMINANCE8_ALPHA8;
3037 fglDataFormat := GL_UNSIGNED_BYTE;
3040 procedure TfdLuminance12Alpha4us2.SetValues;
3042 inherited SetValues;
3043 fBitsPerPixel := 32;
3044 fFormat := tfLuminance12Alpha4us2;
3045 fWithAlpha := tfLuminance12Alpha4us2;
3046 fWithoutAlpha := tfLuminance16us1;
3047 fOpenGLFormat := tfLuminance12Alpha4us2;
3048 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3049 fShift := glBitmapRec4ub( 0, 0, 0, 16);
3050 fglFormat := GL_LUMINANCE_ALPHA;
3051 fglInternalFormat := GL_LUMINANCE12_ALPHA4;
3052 fglDataFormat := GL_UNSIGNED_SHORT;
3055 procedure TfdLuminance16Alpha16us2.SetValues;
3057 inherited SetValues;
3058 fBitsPerPixel := 32;
3059 fFormat := tfLuminance16Alpha16us2;
3060 fWithAlpha := tfLuminance16Alpha16us2;
3061 fWithoutAlpha := tfLuminance16us1;
3062 fOpenGLFormat := tfLuminance16Alpha16us2;
3063 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3064 fShift := glBitmapRec4ub( 0, 0, 0, 16);
3065 fglFormat := GL_LUMINANCE_ALPHA;
3066 fglInternalFormat := GL_LUMINANCE16_ALPHA16;
3067 fglDataFormat := GL_UNSIGNED_SHORT;
3070 procedure TfdR3G3B2ub1.SetValues;
3072 inherited SetValues;
3074 fFormat := tfR3G3B2ub1;
3075 fWithAlpha := tfRGBA4us1;
3076 fWithoutAlpha := tfR3G3B2ub1;
3077 fOpenGLFormat := tfR3G3B2ub1;
3078 fRGBInverted := tfEmpty;
3079 fPrecision := glBitmapRec4ub(3, 3, 2, 0);
3080 fShift := glBitmapRec4ub(5, 2, 0, 0);
3081 fglFormat := GL_RGB;
3082 fglInternalFormat := GL_R3_G3_B2;
3083 fglDataFormat := GL_UNSIGNED_BYTE_3_3_2;
3086 procedure TfdRGBX4us1.SetValues;
3088 inherited SetValues;
3089 fBitsPerPixel := 16;
3090 fFormat := tfRGBX4us1;
3091 fWithAlpha := tfRGBA4us1;
3092 fWithoutAlpha := tfRGBX4us1;
3093 fOpenGLFormat := tfRGBX4us1;
3094 fRGBInverted := tfBGRX4us1;
3095 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
3096 fShift := glBitmapRec4ub(12, 8, 4, 0);
3097 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3098 fglInternalFormat := GL_RGB4;
3099 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3102 procedure TfdXRGB4us1.SetValues;
3104 inherited SetValues;
3105 fBitsPerPixel := 16;
3106 fFormat := tfXRGB4us1;
3107 fWithAlpha := tfARGB4us1;
3108 fWithoutAlpha := tfXRGB4us1;
3109 fOpenGLFormat := tfXRGB4us1;
3110 fRGBInverted := tfXBGR4us1;
3111 fPrecision := glBitmapRec4ub(4, 4, 4, 0);
3112 fShift := glBitmapRec4ub(8, 4, 0, 0);
3113 fglFormat := GL_BGRA;
3114 fglInternalFormat := GL_RGB4;
3115 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3118 procedure TfdR5G6B5us1.SetValues;
3120 inherited SetValues;
3121 fBitsPerPixel := 16;
3122 fFormat := tfR5G6B5us1;
3123 fWithAlpha := tfRGB5A1us1;
3124 fWithoutAlpha := tfR5G6B5us1;
3125 fOpenGLFormat := tfR5G6B5us1;
3126 fRGBInverted := tfB5G6R5us1;
3127 fPrecision := glBitmapRec4ub( 5, 6, 5, 0);
3128 fShift := glBitmapRec4ub(11, 5, 0, 0);
3129 fglFormat := GL_RGB;
3130 fglInternalFormat := GL_RGB565;
3131 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5;
3134 procedure TfdRGB5X1us1.SetValues;
3136 inherited SetValues;
3137 fBitsPerPixel := 16;
3138 fFormat := tfRGB5X1us1;
3139 fWithAlpha := tfRGB5A1us1;
3140 fWithoutAlpha := tfRGB5X1us1;
3141 fOpenGLFormat := tfRGB5X1us1;
3142 fRGBInverted := tfBGR5X1us1;
3143 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3144 fShift := glBitmapRec4ub(11, 6, 1, 0);
3145 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3146 fglInternalFormat := GL_RGB5;
3147 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3150 procedure TfdX1RGB5us1.SetValues;
3152 inherited SetValues;
3153 fBitsPerPixel := 16;
3154 fFormat := tfX1RGB5us1;
3155 fWithAlpha := tfA1RGB5us1;
3156 fWithoutAlpha := tfX1RGB5us1;
3157 fOpenGLFormat := tfX1RGB5us1;
3158 fRGBInverted := tfX1BGR5us1;
3159 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3160 fShift := glBitmapRec4ub(10, 5, 0, 0);
3161 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3162 fglInternalFormat := GL_RGB5;
3163 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3166 procedure TfdRGB8ub3.SetValues;
3168 inherited SetValues;
3169 fBitsPerPixel := 24;
3170 fFormat := tfRGB8ub3;
3171 fWithAlpha := tfRGBA8ub4;
3172 fWithoutAlpha := tfRGB8ub3;
3173 fOpenGLFormat := tfRGB8ub3;
3174 fRGBInverted := tfBGR8ub3;
3175 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
3176 fShift := glBitmapRec4ub(0, 8, 16, 0);
3177 fglFormat := GL_RGB;
3178 fglInternalFormat := GL_RGB8;
3179 fglDataFormat := GL_UNSIGNED_BYTE;
3182 procedure TfdRGBX8ui1.SetValues;
3184 inherited SetValues;
3185 fBitsPerPixel := 32;
3186 fFormat := tfRGBX8ui1;
3187 fWithAlpha := tfRGBA8ui1;
3188 fWithoutAlpha := tfRGBX8ui1;
3189 fOpenGLFormat := tfRGB8ub3;
3190 fRGBInverted := tfBGRX8ui1;
3191 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3192 fShift := glBitmapRec4ub(24, 16, 8, 0);
3193 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3194 fglInternalFormat := GL_RGB8;
3195 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3198 procedure TfdXRGB8ui1.SetValues;
3200 inherited SetValues;
3201 fBitsPerPixel := 32;
3202 fFormat := tfXRGB8ui1;
3203 fWithAlpha := tfXRGB8ui1;
3204 fWithoutAlpha := tfXRGB8ui1;
3205 fOpenGLFormat := tfRGB8ub3;
3206 fRGBInverted := tfXBGR8ui1;
3207 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3208 fShift := glBitmapRec4ub(16, 8, 0, 0);
3209 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3210 fglInternalFormat := GL_RGB8;
3211 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3214 procedure TfdRGB10X2ui1.SetValues;
3216 inherited SetValues;
3217 fBitsPerPixel := 32;
3218 fFormat := tfRGB10X2ui1;
3219 fWithAlpha := tfRGB10A2ui1;
3220 fWithoutAlpha := tfRGB10X2ui1;
3221 fOpenGLFormat := tfRGB10X2ui1;
3222 fRGBInverted := tfBGR10X2ui1;
3223 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3224 fShift := glBitmapRec4ub(22, 12, 2, 0);
3225 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3226 fglInternalFormat := GL_RGB10;
3227 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3230 procedure TfdX2RGB10ui1.SetValues;
3232 inherited SetValues;
3233 fBitsPerPixel := 32;
3234 fFormat := tfX2RGB10ui1;
3235 fWithAlpha := tfA2RGB10ui1;
3236 fWithoutAlpha := tfX2RGB10ui1;
3237 fOpenGLFormat := tfX2RGB10ui1;
3238 fRGBInverted := tfX2BGR10ui1;
3239 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3240 fShift := glBitmapRec4ub(20, 10, 0, 0);
3241 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3242 fglInternalFormat := GL_RGB10;
3243 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3246 procedure TfdRGB16us3.SetValues;
3248 inherited SetValues;
3249 fBitsPerPixel := 48;
3250 fFormat := tfRGB16us3;
3251 fWithAlpha := tfRGBA16us4;
3252 fWithoutAlpha := tfRGB16us3;
3253 fOpenGLFormat := tfRGB16us3;
3254 fRGBInverted := tfBGR16us3;
3255 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
3256 fShift := glBitmapRec4ub( 0, 16, 32, 0);
3257 fglFormat := GL_RGB;
3258 fglInternalFormat := GL_RGB16;
3259 fglDataFormat := GL_UNSIGNED_SHORT;
3262 procedure TfdRGBA4us1.SetValues;
3264 inherited SetValues;
3265 fBitsPerPixel := 16;
3266 fFormat := tfRGBA4us1;
3267 fWithAlpha := tfRGBA4us1;
3268 fWithoutAlpha := tfRGBX4us1;
3269 fOpenGLFormat := tfRGBA4us1;
3270 fRGBInverted := tfBGRA4us1;
3271 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3272 fShift := glBitmapRec4ub(12, 8, 4, 0);
3273 fglFormat := GL_RGBA;
3274 fglInternalFormat := GL_RGBA4;
3275 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3278 procedure TfdARGB4us1.SetValues;
3280 inherited SetValues;
3281 fBitsPerPixel := 16;
3282 fFormat := tfARGB4us1;
3283 fWithAlpha := tfARGB4us1;
3284 fWithoutAlpha := tfXRGB4us1;
3285 fOpenGLFormat := tfARGB4us1;
3286 fRGBInverted := tfABGR4us1;
3287 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3288 fShift := glBitmapRec4ub( 8, 4, 0, 12);
3289 fglFormat := GL_BGRA;
3290 fglInternalFormat := GL_RGBA4;
3291 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3294 procedure TfdRGB5A1us1.SetValues;
3296 inherited SetValues;
3297 fBitsPerPixel := 16;
3298 fFormat := tfRGB5A1us1;
3299 fWithAlpha := tfRGB5A1us1;
3300 fWithoutAlpha := tfRGB5X1us1;
3301 fOpenGLFormat := tfRGB5A1us1;
3302 fRGBInverted := tfBGR5A1us1;
3303 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3304 fShift := glBitmapRec4ub(11, 6, 1, 0);
3305 fglFormat := GL_RGBA;
3306 fglInternalFormat := GL_RGB5_A1;
3307 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3310 procedure TfdA1RGB5us1.SetValues;
3312 inherited SetValues;
3313 fBitsPerPixel := 16;
3314 fFormat := tfA1RGB5us1;
3315 fWithAlpha := tfA1RGB5us1;
3316 fWithoutAlpha := tfX1RGB5us1;
3317 fOpenGLFormat := tfA1RGB5us1;
3318 fRGBInverted := tfA1BGR5us1;
3319 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3320 fShift := glBitmapRec4ub(10, 5, 0, 15);
3321 fglFormat := GL_BGRA;
3322 fglInternalFormat := GL_RGB5_A1;
3323 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3326 procedure TfdRGBA8ui1.SetValues;
3328 inherited SetValues;
3329 fBitsPerPixel := 32;
3330 fFormat := tfRGBA8ui1;
3331 fWithAlpha := tfRGBA8ui1;
3332 fWithoutAlpha := tfRGBX8ui1;
3333 fOpenGLFormat := tfRGBA8ui1;
3334 fRGBInverted := tfBGRA8ui1;
3335 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3336 fShift := glBitmapRec4ub(24, 16, 8, 0);
3337 fglFormat := GL_RGBA;
3338 fglInternalFormat := GL_RGBA8;
3339 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3342 procedure TfdARGB8ui1.SetValues;
3344 inherited SetValues;
3345 fBitsPerPixel := 32;
3346 fFormat := tfARGB8ui1;
3347 fWithAlpha := tfARGB8ui1;
3348 fWithoutAlpha := tfXRGB8ui1;
3349 fOpenGLFormat := tfARGB8ui1;
3350 fRGBInverted := tfABGR8ui1;
3351 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3352 fShift := glBitmapRec4ub(16, 8, 0, 24);
3353 fglFormat := GL_BGRA;
3354 fglInternalFormat := GL_RGBA8;
3355 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3358 procedure TfdRGBA8ub4.SetValues;
3360 inherited SetValues;
3361 fBitsPerPixel := 32;
3362 fFormat := tfRGBA8ub4;
3363 fWithAlpha := tfRGBA8ub4;
3364 fWithoutAlpha := tfRGB8ub3;
3365 fOpenGLFormat := tfRGBA8ub4;
3366 fRGBInverted := tfBGRA8ub4;
3367 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3368 fShift := glBitmapRec4ub( 0, 8, 16, 24);
3369 fglFormat := GL_RGBA;
3370 fglInternalFormat := GL_RGBA8;
3371 fglDataFormat := GL_UNSIGNED_BYTE;
3374 procedure TfdRGB10A2ui1.SetValues;
3376 inherited SetValues;
3377 fBitsPerPixel := 32;
3378 fFormat := tfRGB10A2ui1;
3379 fWithAlpha := tfRGB10A2ui1;
3380 fWithoutAlpha := tfRGB10X2ui1;
3381 fOpenGLFormat := tfRGB10A2ui1;
3382 fRGBInverted := tfBGR10A2ui1;
3383 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3384 fShift := glBitmapRec4ub(22, 12, 2, 0);
3385 fglFormat := GL_RGBA;
3386 fglInternalFormat := GL_RGB10_A2;
3387 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3390 procedure TfdA2RGB10ui1.SetValues;
3392 inherited SetValues;
3393 fBitsPerPixel := 32;
3394 fFormat := tfA2RGB10ui1;
3395 fWithAlpha := tfA2RGB10ui1;
3396 fWithoutAlpha := tfX2RGB10ui1;
3397 fOpenGLFormat := tfA2RGB10ui1;
3398 fRGBInverted := tfA2BGR10ui1;
3399 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3400 fShift := glBitmapRec4ub(20, 10, 0, 30);
3401 fglFormat := GL_BGRA;
3402 fglInternalFormat := GL_RGB10_A2;
3403 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3406 procedure TfdRGBA16us4.SetValues;
3408 inherited SetValues;
3409 fBitsPerPixel := 64;
3410 fFormat := tfRGBA16us4;
3411 fWithAlpha := tfRGBA16us4;
3412 fWithoutAlpha := tfRGB16us3;
3413 fOpenGLFormat := tfRGBA16us4;
3414 fRGBInverted := tfBGRA16us4;
3415 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3416 fShift := glBitmapRec4ub( 0, 16, 32, 48);
3417 fglFormat := GL_RGBA;
3418 fglInternalFormat := GL_RGBA16;
3419 fglDataFormat := GL_UNSIGNED_SHORT;
3422 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3423 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3424 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3425 procedure TfdBGRX4us1.SetValues;
3427 inherited SetValues;
3428 fBitsPerPixel := 16;
3429 fFormat := tfBGRX4us1;
3430 fWithAlpha := tfBGRA4us1;
3431 fWithoutAlpha := tfBGRX4us1;
3432 fOpenGLFormat := tfBGRX4us1;
3433 fRGBInverted := tfRGBX4us1;
3434 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
3435 fShift := glBitmapRec4ub( 4, 8, 12, 0);
3436 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3437 fglInternalFormat := GL_RGB4;
3438 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3441 procedure TfdXBGR4us1.SetValues;
3443 inherited SetValues;
3444 fBitsPerPixel := 16;
3445 fFormat := tfXBGR4us1;
3446 fWithAlpha := tfABGR4us1;
3447 fWithoutAlpha := tfXBGR4us1;
3448 fOpenGLFormat := tfXBGR4us1;
3449 fRGBInverted := tfXRGB4us1;
3450 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
3451 fShift := glBitmapRec4ub( 0, 4, 8, 0);
3452 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3453 fglInternalFormat := GL_RGB4;
3454 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3457 procedure TfdB5G6R5us1.SetValues;
3459 inherited SetValues;
3460 fBitsPerPixel := 16;
3461 fFormat := tfB5G6R5us1;
3462 fWithAlpha := tfBGR5A1us1;
3463 fWithoutAlpha := tfB5G6R5us1;
3464 fOpenGLFormat := tfB5G6R5us1;
3465 fRGBInverted := tfR5G6B5us1;
3466 fPrecision := glBitmapRec4ub( 5, 6, 5, 0);
3467 fShift := glBitmapRec4ub( 0, 5, 11, 0);
3468 fglFormat := GL_RGB;
3469 fglInternalFormat := GL_RGB565;
3470 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5_REV;
3473 procedure TfdBGR5X1us1.SetValues;
3475 inherited SetValues;
3476 fBitsPerPixel := 16;
3477 fFormat := tfBGR5X1us1;
3478 fWithAlpha := tfBGR5A1us1;
3479 fWithoutAlpha := tfBGR5X1us1;
3480 fOpenGLFormat := tfBGR5X1us1;
3481 fRGBInverted := tfRGB5X1us1;
3482 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3483 fShift := glBitmapRec4ub( 1, 6, 11, 0);
3484 fglFormat := GL_BGRA;
3485 fglInternalFormat := GL_RGB5;
3486 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3489 procedure TfdX1BGR5us1.SetValues;
3491 inherited SetValues;
3492 fBitsPerPixel := 16;
3493 fFormat := tfX1BGR5us1;
3494 fWithAlpha := tfA1BGR5us1;
3495 fWithoutAlpha := tfX1BGR5us1;
3496 fOpenGLFormat := tfX1BGR5us1;
3497 fRGBInverted := tfX1RGB5us1;
3498 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3499 fShift := glBitmapRec4ub( 0, 5, 10, 0);
3500 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3501 fglInternalFormat := GL_RGB5;
3502 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3505 procedure TfdBGR8ub3.SetValues;
3507 inherited SetValues;
3508 fBitsPerPixel := 24;
3509 fFormat := tfBGR8ub3;
3510 fWithAlpha := tfBGRA8ub4;
3511 fWithoutAlpha := tfBGR8ub3;
3512 fOpenGLFormat := tfBGR8ub3;
3513 fRGBInverted := tfRGB8ub3;
3514 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3515 fShift := glBitmapRec4ub(16, 8, 0, 0);
3516 fglFormat := GL_BGR;
3517 fglInternalFormat := GL_RGB8;
3518 fglDataFormat := GL_UNSIGNED_BYTE;
3521 procedure TfdBGRX8ui1.SetValues;
3523 inherited SetValues;
3524 fBitsPerPixel := 32;
3525 fFormat := tfBGRX8ui1;
3526 fWithAlpha := tfBGRA8ui1;
3527 fWithoutAlpha := tfBGRX8ui1;
3528 fOpenGLFormat := tfBGRX8ui1;
3529 fRGBInverted := tfRGBX8ui1;
3530 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3531 fShift := glBitmapRec4ub( 8, 16, 24, 0);
3532 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3533 fglInternalFormat := GL_RGB8;
3534 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3537 procedure TfdXBGR8ui1.SetValues;
3539 inherited SetValues;
3540 fBitsPerPixel := 32;
3541 fFormat := tfXBGR8ui1;
3542 fWithAlpha := tfABGR8ui1;
3543 fWithoutAlpha := tfXBGR8ui1;
3544 fOpenGLFormat := tfXBGR8ui1;
3545 fRGBInverted := tfXRGB8ui1;
3546 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3547 fShift := glBitmapRec4ub( 0, 8, 16, 0);
3548 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3549 fglInternalFormat := GL_RGB8;
3550 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3553 procedure TfdBGR10X2ui1.SetValues;
3555 inherited SetValues;
3556 fBitsPerPixel := 32;
3557 fFormat := tfBGR10X2ui1;
3558 fWithAlpha := tfBGR10A2ui1;
3559 fWithoutAlpha := tfBGR10X2ui1;
3560 fOpenGLFormat := tfBGR10X2ui1;
3561 fRGBInverted := tfRGB10X2ui1;
3562 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3563 fShift := glBitmapRec4ub( 2, 12, 22, 0);
3564 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3565 fglInternalFormat := GL_RGB10;
3566 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3569 procedure TfdX2BGR10ui1.SetValues;
3571 inherited SetValues;
3572 fBitsPerPixel := 32;
3573 fFormat := tfX2BGR10ui1;
3574 fWithAlpha := tfA2BGR10ui1;
3575 fWithoutAlpha := tfX2BGR10ui1;
3576 fOpenGLFormat := tfX2BGR10ui1;
3577 fRGBInverted := tfX2RGB10ui1;
3578 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3579 fShift := glBitmapRec4ub( 0, 10, 20, 0);
3580 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3581 fglInternalFormat := GL_RGB10;
3582 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3585 procedure TfdBGR16us3.SetValues;
3587 inherited SetValues;
3588 fBitsPerPixel := 48;
3589 fFormat := tfBGR16us3;
3590 fWithAlpha := tfBGRA16us4;
3591 fWithoutAlpha := tfBGR16us3;
3592 fOpenGLFormat := tfBGR16us3;
3593 fRGBInverted := tfRGB16us3;
3594 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
3595 fShift := glBitmapRec4ub(32, 16, 0, 0);
3596 fglFormat := GL_BGR;
3597 fglInternalFormat := GL_RGB16;
3598 fglDataFormat := GL_UNSIGNED_SHORT;
3601 procedure TfdBGRA4us1.SetValues;
3603 inherited SetValues;
3604 fBitsPerPixel := 16;
3605 fFormat := tfBGRA4us1;
3606 fWithAlpha := tfBGRA4us1;
3607 fWithoutAlpha := tfBGRX4us1;
3608 fOpenGLFormat := tfBGRA4us1;
3609 fRGBInverted := tfRGBA4us1;
3610 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3611 fShift := glBitmapRec4ub( 4, 8, 12, 0);
3612 fglFormat := GL_BGRA;
3613 fglInternalFormat := GL_RGBA4;
3614 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3617 procedure TfdABGR4us1.SetValues;
3619 inherited SetValues;
3620 fBitsPerPixel := 16;
3621 fFormat := tfABGR4us1;
3622 fWithAlpha := tfABGR4us1;
3623 fWithoutAlpha := tfXBGR4us1;
3624 fOpenGLFormat := tfABGR4us1;
3625 fRGBInverted := tfARGB4us1;
3626 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3627 fShift := glBitmapRec4ub( 0, 4, 8, 12);
3628 fglFormat := GL_RGBA;
3629 fglInternalFormat := GL_RGBA4;
3630 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3633 procedure TfdBGR5A1us1.SetValues;
3635 inherited SetValues;
3636 fBitsPerPixel := 16;
3637 fFormat := tfBGR5A1us1;
3638 fWithAlpha := tfBGR5A1us1;
3639 fWithoutAlpha := tfBGR5X1us1;
3640 fOpenGLFormat := tfBGR5A1us1;
3641 fRGBInverted := tfRGB5A1us1;
3642 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3643 fShift := glBitmapRec4ub( 1, 6, 11, 0);
3644 fglFormat := GL_BGRA;
3645 fglInternalFormat := GL_RGB5_A1;
3646 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3649 procedure TfdA1BGR5us1.SetValues;
3651 inherited SetValues;
3652 fBitsPerPixel := 16;
3653 fFormat := tfA1BGR5us1;
3654 fWithAlpha := tfA1BGR5us1;
3655 fWithoutAlpha := tfX1BGR5us1;
3656 fOpenGLFormat := tfA1BGR5us1;
3657 fRGBInverted := tfA1RGB5us1;
3658 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3659 fShift := glBitmapRec4ub( 0, 5, 10, 15);
3660 fglFormat := GL_RGBA;
3661 fglInternalFormat := GL_RGB5_A1;
3662 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3665 procedure TfdBGRA8ui1.SetValues;
3667 inherited SetValues;
3668 fBitsPerPixel := 32;
3669 fFormat := tfBGRA8ui1;
3670 fWithAlpha := tfBGRA8ui1;
3671 fWithoutAlpha := tfBGRX8ui1;
3672 fOpenGLFormat := tfBGRA8ui1;
3673 fRGBInverted := tfRGBA8ui1;
3674 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3675 fShift := glBitmapRec4ub( 8, 16, 24, 0);
3676 fglFormat := GL_BGRA;
3677 fglInternalFormat := GL_RGBA8;
3678 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3681 procedure TfdABGR8ui1.SetValues;
3683 inherited SetValues;
3684 fBitsPerPixel := 32;
3685 fFormat := tfABGR8ui1;
3686 fWithAlpha := tfABGR8ui1;
3687 fWithoutAlpha := tfXBGR8ui1;
3688 fOpenGLFormat := tfABGR8ui1;
3689 fRGBInverted := tfARGB8ui1;
3690 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3691 fShift := glBitmapRec4ub( 0, 8, 16, 24);
3692 fglFormat := GL_RGBA;
3693 fglInternalFormat := GL_RGBA8;
3694 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3697 procedure TfdBGRA8ub4.SetValues;
3699 inherited SetValues;
3700 fBitsPerPixel := 32;
3701 fFormat := tfBGRA8ub4;
3702 fWithAlpha := tfBGRA8ub4;
3703 fWithoutAlpha := tfBGR8ub3;
3704 fOpenGLFormat := tfBGRA8ub4;
3705 fRGBInverted := tfRGBA8ub4;
3706 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3707 fShift := glBitmapRec4ub(16, 8, 0, 24);
3708 fglFormat := GL_BGRA;
3709 fglInternalFormat := GL_RGBA8;
3710 fglDataFormat := GL_UNSIGNED_BYTE;
3713 procedure TfdBGR10A2ui1.SetValues;
3715 inherited SetValues;
3716 fBitsPerPixel := 32;
3717 fFormat := tfBGR10A2ui1;
3718 fWithAlpha := tfBGR10A2ui1;
3719 fWithoutAlpha := tfBGR10X2ui1;
3720 fOpenGLFormat := tfBGR10A2ui1;
3721 fRGBInverted := tfRGB10A2ui1;
3722 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3723 fShift := glBitmapRec4ub( 2, 12, 22, 0);
3724 fglFormat := GL_BGRA;
3725 fglInternalFormat := GL_RGB10_A2;
3726 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3729 procedure TfdA2BGR10ui1.SetValues;
3731 inherited SetValues;
3732 fBitsPerPixel := 32;
3733 fFormat := tfA2BGR10ui1;
3734 fWithAlpha := tfA2BGR10ui1;
3735 fWithoutAlpha := tfX2BGR10ui1;
3736 fOpenGLFormat := tfA2BGR10ui1;
3737 fRGBInverted := tfA2RGB10ui1;
3738 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3739 fShift := glBitmapRec4ub( 0, 10, 20, 30);
3740 fglFormat := GL_RGBA;
3741 fglInternalFormat := GL_RGB10_A2;
3742 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3745 procedure TfdBGRA16us4.SetValues;
3747 inherited SetValues;
3748 fBitsPerPixel := 64;
3749 fFormat := tfBGRA16us4;
3750 fWithAlpha := tfBGRA16us4;
3751 fWithoutAlpha := tfBGR16us3;
3752 fOpenGLFormat := tfBGRA16us4;
3753 fRGBInverted := tfRGBA16us4;
3754 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3755 fShift := glBitmapRec4ub(32, 16, 0, 48);
3756 fglFormat := GL_BGRA;
3757 fglInternalFormat := GL_RGBA16;
3758 fglDataFormat := GL_UNSIGNED_SHORT;
3761 procedure TfdDepth16us1.SetValues;
3763 inherited SetValues;
3764 fBitsPerPixel := 16;
3765 fFormat := tfDepth16us1;
3766 fWithoutAlpha := tfDepth16us1;
3767 fOpenGLFormat := tfDepth16us1;
3768 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3769 fShift := glBitmapRec4ub( 0, 0, 0, 0);
3770 fglFormat := GL_DEPTH_COMPONENT;
3771 fglInternalFormat := GL_DEPTH_COMPONENT16;
3772 fglDataFormat := GL_UNSIGNED_SHORT;
3775 procedure TfdDepth24ui1.SetValues;
3777 inherited SetValues;
3778 fBitsPerPixel := 32;
3779 fFormat := tfDepth24ui1;
3780 fWithoutAlpha := tfDepth24ui1;
3781 fOpenGLFormat := tfDepth24ui1;
3782 fPrecision := glBitmapRec4ub(32, 32, 32, 32);
3783 fShift := glBitmapRec4ub( 0, 0, 0, 0);
3784 fglFormat := GL_DEPTH_COMPONENT;
3785 fglInternalFormat := GL_DEPTH_COMPONENT24;
3786 fglDataFormat := GL_UNSIGNED_INT;
3789 procedure TfdDepth32ui1.SetValues;
3791 inherited SetValues;
3792 fBitsPerPixel := 32;
3793 fFormat := tfDepth32ui1;
3794 fWithoutAlpha := tfDepth32ui1;
3795 fOpenGLFormat := tfDepth32ui1;
3796 fPrecision := glBitmapRec4ub(32, 32, 32, 32);
3797 fShift := glBitmapRec4ub( 0, 0, 0, 0);
3798 fglFormat := GL_DEPTH_COMPONENT;
3799 fglInternalFormat := GL_DEPTH_COMPONENT32;
3800 fglDataFormat := GL_UNSIGNED_INT;
3803 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3804 //TfdS3tcDtx1RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3805 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3806 procedure TfdS3tcDtx1RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3808 raise EglBitmap.Create('mapping for compressed formats is not supported');
3811 procedure TfdS3tcDtx1RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3813 raise EglBitmap.Create('mapping for compressed formats is not supported');
3816 procedure TfdS3tcDtx1RGBA.SetValues;
3818 inherited SetValues;
3819 fFormat := tfS3tcDtx1RGBA;
3820 fWithAlpha := tfS3tcDtx1RGBA;
3821 fOpenGLFormat := tfS3tcDtx1RGBA;
3822 fUncompressed := tfRGB5A1us1;
3824 fIsCompressed := true;
3825 fglFormat := GL_COMPRESSED_RGBA;
3826 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
3827 fglDataFormat := GL_UNSIGNED_BYTE;
3830 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3831 //TfdS3tcDtx3RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3832 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3833 procedure TfdS3tcDtx3RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3835 raise EglBitmap.Create('mapping for compressed formats is not supported');
3838 procedure TfdS3tcDtx3RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3840 raise EglBitmap.Create('mapping for compressed formats is not supported');
3843 procedure TfdS3tcDtx3RGBA.SetValues;
3845 inherited SetValues;
3846 fFormat := tfS3tcDtx3RGBA;
3847 fWithAlpha := tfS3tcDtx3RGBA;
3848 fOpenGLFormat := tfS3tcDtx3RGBA;
3849 fUncompressed := tfRGBA8ub4;
3851 fIsCompressed := true;
3852 fglFormat := GL_COMPRESSED_RGBA;
3853 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
3854 fglDataFormat := GL_UNSIGNED_BYTE;
3857 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3858 //TfdS3tcDtx5RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3859 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3860 procedure TfdS3tcDtx5RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3862 raise EglBitmap.Create('mapping for compressed formats is not supported');
3865 procedure TfdS3tcDtx5RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3867 raise EglBitmap.Create('mapping for compressed formats is not supported');
3870 procedure TfdS3tcDtx5RGBA.SetValues;
3873 fFormat := tfS3tcDtx3RGBA;
3874 fWithAlpha := tfS3tcDtx3RGBA;
3875 fOpenGLFormat := tfS3tcDtx3RGBA;
3876 fUncompressed := tfRGBA8ub4;
3878 fIsCompressed := true;
3879 fglFormat := GL_COMPRESSED_RGBA;
3880 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
3881 fglDataFormat := GL_UNSIGNED_BYTE;
3884 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3885 //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3886 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3887 function TglBitmapFormatDescriptor.GetHasRed: Boolean;
3889 result := (fPrecision.r > 0);
3892 function TglBitmapFormatDescriptor.GetHasGreen: Boolean;
3894 result := (fPrecision.g > 0);
3897 function TglBitmapFormatDescriptor.GetHasBlue: Boolean;
3899 result := (fPrecision.b > 0);
3902 function TglBitmapFormatDescriptor.GetHasAlpha: Boolean;
3904 result := (fPrecision.a > 0);
3907 function TglBitmapFormatDescriptor.GetHasColor: Boolean;
3909 result := HasRed or HasGreen or HasBlue;
3912 function TglBitmapFormatDescriptor.GetIsGrayscale: Boolean;
3914 result := (Mask.r = Mask.g) and (Mask.g = Mask.b) and (Mask.r > 0);
3917 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3918 procedure TglBitmapFormatDescriptor.SetValues;
3921 fWithAlpha := tfEmpty;
3922 fWithoutAlpha := tfEmpty;
3923 fOpenGLFormat := tfEmpty;
3924 fRGBInverted := tfEmpty;
3925 fUncompressed := tfEmpty;
3928 fIsCompressed := false;
3931 fglInternalFormat := 0;
3934 FillChar(fPrecision, 0, SizeOf(fPrecision));
3935 FillChar(fShift, 0, SizeOf(fShift));
3938 procedure TglBitmapFormatDescriptor.CalcValues;
3942 fBytesPerPixel := fBitsPerPixel / 8;
3944 for i := 0 to 3 do begin
3945 if (fPrecision.arr[i] > 0) then
3947 fRange.arr[i] := (1 shl fPrecision.arr[i]) - 1;
3948 fMask.arr[i] := fRange.arr[i] shl fShift.arr[i];
3952 constructor TglBitmapFormatDescriptor.Create;
3959 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3960 class function TglBitmapFormatDescriptor.GetByFormat(const aInternalFormat: GLenum): TglBitmapFormatDescriptor;
3964 for f := Low(TglBitmapFormat) to High(TglBitmapFormat) do begin
3965 result := TFormatDescriptor.Get(f);
3966 if (result.glInternalFormat = aInternalFormat) then
3969 result := TFormatDescriptor.Get(tfEmpty);
3972 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3973 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3974 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3975 class procedure TFormatDescriptor.Init;
3977 if not Assigned(FormatDescriptorCS) then
3978 FormatDescriptorCS := TCriticalSection.Create;
3981 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3982 class function TFormatDescriptor.Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
3984 FormatDescriptorCS.Enter;
3986 result := FormatDescriptors[aFormat];
3987 if not Assigned(result) then begin
3988 result := FORMAT_DESCRIPTOR_CLASSES[aFormat].Create;
3989 FormatDescriptors[aFormat] := result;
3992 FormatDescriptorCS.Leave;
3996 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3997 class function TFormatDescriptor.GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
3999 result := Get(Get(aFormat).WithAlpha);
4002 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4003 class function TFormatDescriptor.GetFromMask(const aMask: TglBitmapRec4ul; const aBitCount: Integer): TFormatDescriptor;
4005 ft: TglBitmapFormat;
4007 // find matching format with OpenGL support
4008 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4010 if (result.MaskMatch(aMask)) and
4011 (result.glFormat <> 0) and
4012 (result.glInternalFormat <> 0) and
4013 ((aBitCount = 0) or (aBitCount = result.BitsPerPixel))
4018 // find matching format without OpenGL Support
4019 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4021 if result.MaskMatch(aMask) and ((aBitCount = 0) or (aBitCount = result.BitsPerPixel)) then
4025 result := FormatDescriptors[tfEmpty];
4028 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4029 class procedure TFormatDescriptor.Clear;
4033 FormatDescriptorCS.Enter;
4035 for f := low(FormatDescriptors) to high(FormatDescriptors) do
4036 FreeAndNil(FormatDescriptors[f]);
4038 FormatDescriptorCS.Leave;
4042 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4043 class procedure TFormatDescriptor.Finalize;
4046 FreeAndNil(FormatDescriptorCS);
4049 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4050 //TBitfieldFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4051 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4052 procedure TbmpBitfieldFormat.SetValues(const aBPP: Integer; aMask: TglBitmapRec4ul);
4056 for i := 0 to 3 do begin
4058 while (aMask.arr[i] > 0) and (aMask.arr[i] and 1 > 0) do begin
4059 aMask.arr[i] := aMask.arr[i] shr 1;
4062 fPrecision.arr[i] := CountSetBits(aMask.arr[i]);
4067 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4068 procedure TbmpBitfieldFormat.SetValues(const aBBP: Integer; const aPrec, aShift: TglBitmapRec4ub);
4070 fBitsPerPixel := aBBP;
4071 fPrecision := aPrec;
4076 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4077 procedure TbmpBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4082 ((aPixel.Data.r and Range.r) shl Shift.r) or
4083 ((aPixel.Data.g and Range.g) shl Shift.g) or
4084 ((aPixel.Data.b and Range.b) shl Shift.b) or
4085 ((aPixel.Data.a and Range.a) shl Shift.a);
4086 case BitsPerPixel of
4088 16: PWord(aData)^ := data;
4089 32: PCardinal(aData)^ := data;
4090 64: PQWord(aData)^ := data;
4092 raise EglBitmap.CreateFmt('invalid pixel size: %d', [BitsPerPixel]);
4094 inc(aData, Round(BytesPerPixel));
4097 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4098 procedure TbmpBitfieldFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4103 case BitsPerPixel of
4105 16: data := PWord(aData)^;
4106 32: data := PCardinal(aData)^;
4107 64: data := PQWord(aData)^;
4109 raise EglBitmap.CreateFmt('invalid pixel size: %d', [BitsPerPixel]);
4112 aPixel.Data.arr[i] := (data shr fShift.arr[i]) and Range.arr[i];
4113 inc(aData, Round(BytesPerPixel));
4116 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4117 //TColorTableFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4118 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4119 procedure TbmpColorTableFormat.SetValues;
4121 inherited SetValues;
4122 fShift := glBitmapRec4ub(8, 8, 8, 0);
4125 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4126 procedure TbmpColorTableFormat.SetValues(const aFormat: TglBitmapFormat; const aBPP: Integer; const aPrec, aShift: TglBitmapRec4ub);
4129 fBitsPerPixel := aBPP;
4130 fPrecision := aPrec;
4135 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4136 procedure TbmpColorTableFormat.CalcValues;
4138 inherited CalcValues;
4141 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4142 procedure TbmpColorTableFormat.CreateColorTable;
4146 SetLength(fColorTable, 256);
4147 if not HasColor then begin
4149 for i := 0 to High(fColorTable) do begin
4150 fColorTable[i].r := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4151 fColorTable[i].g := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4152 fColorTable[i].b := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4153 fColorTable[i].a := 0;
4157 for i := 0 to High(fColorTable) do begin
4158 fColorTable[i].r := Round(((i shr Shift.r) and Range.r) / Range.r * 255);
4159 fColorTable[i].g := Round(((i shr Shift.g) and Range.g) / Range.g * 255);
4160 fColorTable[i].b := Round(((i shr Shift.b) and Range.b) / Range.b * 255);
4161 fColorTable[i].a := 0;
4166 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4167 procedure TbmpColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4169 if (BitsPerPixel <> 8) then
4170 raise EglBitmapUnsupportedFormat.Create('color table are only supported for 8bit formats');
4171 if not HasColor then
4173 aData^ := aPixel.Data.a
4177 ((aPixel.Data.r and Range.r) shl Shift.r) or
4178 ((aPixel.Data.g and Range.g) shl Shift.g) or
4179 ((aPixel.Data.b and Range.b) shl Shift.b));
4183 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4184 procedure TbmpColorTableFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4186 if (BitsPerPixel <> 8) then
4187 raise EglBitmapUnsupportedFormat.Create('color table are only supported for 8bit formats');
4188 with fColorTable[aData^] do begin
4197 destructor TbmpColorTableFormat.Destroy;
4199 SetLength(fColorTable, 0);
4203 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4204 //TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4205 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4206 procedure glBitmapConvertPixel(var aPixel: TglBitmapPixelData; const aSourceFD, aDestFD: TFormatDescriptor);
4210 for i := 0 to 3 do begin
4211 if (aSourceFD.Range.arr[i] <> aDestFD.Range.arr[i]) then begin
4212 if (aSourceFD.Range.arr[i] > 0) then
4213 aPixel.Data.arr[i] := Round(aPixel.Data.arr[i] / aSourceFD.Range.arr[i] * aDestFD.Range.arr[i])
4215 aPixel.Data.arr[i] := 0;
4220 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4221 procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
4223 with aFuncRec do begin
4224 if (Source.Range.r > 0) then
4225 Dest.Data.r := Source.Data.r;
4226 if (Source.Range.g > 0) then
4227 Dest.Data.g := Source.Data.g;
4228 if (Source.Range.b > 0) then
4229 Dest.Data.b := Source.Data.b;
4230 if (Source.Range.a > 0) then
4231 Dest.Data.a := Source.Data.a;
4235 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4236 procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
4240 with aFuncRec do begin
4242 if (Source.Range.arr[i] > 0) then
4243 Dest.Data.arr[i] := Round(Dest.Range.arr[i] * Source.Data.arr[i] / Source.Range.arr[i]);
4248 TShiftData = packed record
4250 0: (r, g, b, a: SmallInt);
4251 1: (arr: array[0..3] of SmallInt);
4253 PShiftData = ^TShiftData;
4255 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4256 procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
4262 if (Source.Range.arr[i] > 0) then
4263 Dest.Data.arr[i] := Source.Data.arr[i] shr PShiftData(Args)^.arr[i];
4266 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4267 procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
4269 with aFuncRec do begin
4270 Dest.Data := Source.Data;
4271 if ({%H-}PtrUInt(Args) and $1 > 0) then begin
4272 Dest.Data.r := Dest.Data.r xor Dest.Range.r;
4273 Dest.Data.g := Dest.Data.g xor Dest.Range.g;
4274 Dest.Data.b := Dest.Data.b xor Dest.Range.b;
4276 if ({%H-}PtrUInt(Args) and $2 > 0) then begin
4277 Dest.Data.a := Dest.Data.a xor Dest.Range.a;
4282 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4283 procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
4287 with aFuncRec do begin
4289 Dest.Data.arr[i] := PglBitmapPixelData(Args)^.Data.arr[i];
4293 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4294 procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4298 with FuncRec do begin
4299 if (FuncRec.Args = nil) then begin //source has no alpha
4301 Source.Data.r / Source.Range.r * ALPHA_WEIGHT_R +
4302 Source.Data.g / Source.Range.g * ALPHA_WEIGHT_G +
4303 Source.Data.b / Source.Range.b * ALPHA_WEIGHT_B;
4304 Dest.Data.a := Round(Dest.Range.a * Temp);
4306 Dest.Data.a := Round(Source.Data.a / Source.Range.a * Dest.Range.a);
4310 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4311 procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4313 PglBitmapPixelData = ^TglBitmapPixelData;
4315 with FuncRec do begin
4316 Dest.Data.r := Source.Data.r;
4317 Dest.Data.g := Source.Data.g;
4318 Dest.Data.b := Source.Data.b;
4320 with PglBitmapPixelData(Args)^ do
4321 if ((Dest.Data.r <= Data.r) and (Dest.Data.r >= Range.r) and
4322 (Dest.Data.g <= Data.g) and (Dest.Data.g >= Range.g) and
4323 (Dest.Data.b <= Data.b) and (Dest.Data.b >= Range.b)) then
4326 Dest.Data.a := Dest.Range.a;
4330 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4331 procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4333 with FuncRec do begin
4334 Dest.Data.r := Source.Data.r;
4335 Dest.Data.g := Source.Data.g;
4336 Dest.Data.b := Source.Data.b;
4337 Dest.Data.a := PCardinal(Args)^;
4341 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4342 procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
4345 TRGBPix = array [0..2] of byte;
4349 while aWidth > 0 do begin
4350 Temp := PRGBPix(aData)^[0];
4351 PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
4352 PRGBPix(aData)^[2] := Temp;
4362 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4363 //TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4364 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4365 function TglBitmap.GetFormatDesc: TglBitmapFormatDescriptor;
4367 result := TFormatDescriptor.Get(Format);
4370 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4371 function TglBitmap.GetWidth: Integer;
4373 if (ffX in fDimension.Fields) then
4374 result := fDimension.X
4379 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4380 function TglBitmap.GetHeight: Integer;
4382 if (ffY in fDimension.Fields) then
4383 result := fDimension.Y
4388 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4389 function TglBitmap.GetFileWidth: Integer;
4391 result := Max(1, Width);
4394 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4395 function TglBitmap.GetFileHeight: Integer;
4397 result := Max(1, Height);
4400 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4401 procedure TglBitmap.SetCustomData(const aValue: Pointer);
4403 if fCustomData = aValue then
4405 fCustomData := aValue;
4408 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4409 procedure TglBitmap.SetCustomName(const aValue: String);
4411 if fCustomName = aValue then
4413 fCustomName := aValue;
4416 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4417 procedure TglBitmap.SetCustomNameW(const aValue: WideString);
4419 if fCustomNameW = aValue then
4421 fCustomNameW := aValue;
4424 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4425 procedure TglBitmap.SetFreeDataOnDestroy(const aValue: Boolean);
4427 if fFreeDataOnDestroy = aValue then
4429 fFreeDataOnDestroy := aValue;
4432 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4433 procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
4435 if fDeleteTextureOnFree = aValue then
4437 fDeleteTextureOnFree := aValue;
4440 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4441 procedure TglBitmap.SetFormat(const aValue: TglBitmapFormat);
4443 if fFormat = aValue then
4445 if TFormatDescriptor.Get(Format).BitsPerPixel <> TFormatDescriptor.Get(aValue).BitsPerPixel then
4446 raise EglBitmapUnsupportedFormat.Create(Format);
4447 SetDataPointer(fData, aValue, Width, Height); //be careful, Data could be freed by this method
4450 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4451 procedure TglBitmap.SetFreeDataAfterGenTexture(const aValue: Boolean);
4453 if fFreeDataAfterGenTexture = aValue then
4455 fFreeDataAfterGenTexture := aValue;
4458 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4459 procedure TglBitmap.SetID(const aValue: Cardinal);
4461 if fID = aValue then
4466 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4467 procedure TglBitmap.SetMipMap(const aValue: TglBitmapMipMap);
4469 if fMipMap = aValue then
4474 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4475 procedure TglBitmap.SetTarget(const aValue: Cardinal);
4477 if fTarget = aValue then
4482 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4483 procedure TglBitmap.SetAnisotropic(const aValue: Integer);
4485 MaxAnisotropic: Integer;
4487 fAnisotropic := aValue;
4488 if (ID > 0) then begin
4489 if GL_EXT_texture_filter_anisotropic then begin
4490 if fAnisotropic > 0 then begin
4492 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
4493 if aValue > MaxAnisotropic then
4494 fAnisotropic := MaxAnisotropic;
4495 glTexParameteri(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, fAnisotropic);
4503 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4504 procedure TglBitmap.CreateID;
4507 glDeleteTextures(1, @fID);
4508 glGenTextures(1, @fID);
4512 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4513 procedure TglBitmap.SetupParameters(out aBuildWithGlu: Boolean);
4515 // Set Up Parameters
4516 SetWrap(fWrapS, fWrapT, fWrapR);
4517 SetFilter(fFilterMin, fFilterMag);
4518 SetAnisotropic(fAnisotropic);
4519 SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
4521 if (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
4522 SetSwizzle(fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
4524 // Mip Maps Generation Mode
4525 aBuildWithGlu := false;
4526 if (MipMap = mmMipmap) then begin
4527 if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
4528 glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
4530 aBuildWithGlu := true;
4531 end else if (MipMap = mmMipmapGlu) then
4532 aBuildWithGlu := true;
4535 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4536 procedure TglBitmap.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
4537 const aWidth: Integer; const aHeight: Integer);
4541 if (Data <> aData) then begin
4542 if (Assigned(Data)) then
4547 if not Assigned(fData) then begin
4551 FillChar(fDimension, SizeOf(fDimension), 0);
4552 if aWidth <> -1 then begin
4553 fDimension.Fields := fDimension.Fields + [ffX];
4554 fDimension.X := aWidth;
4557 if aHeight <> -1 then begin
4558 fDimension.Fields := fDimension.Fields + [ffY];
4559 fDimension.Y := aHeight;
4562 s := TFormatDescriptor.Get(aFormat).BytesPerPixel;
4564 fPixelSize := Ceil(s);
4565 fRowSize := Ceil(s * aWidth);
4569 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4570 function TglBitmap.FlipHorz: Boolean;
4575 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4576 function TglBitmap.FlipVert: Boolean;
4581 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4582 //TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4583 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4584 procedure TglBitmap.AfterConstruction;
4586 inherited AfterConstruction;
4590 fIsResident := false;
4592 fMipMap := glBitmapDefaultMipmap;
4593 fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
4594 fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
4596 glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
4597 glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
4598 glBitmapGetDefaultSwizzle (fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
4601 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4602 procedure TglBitmap.BeforeDestruction;
4606 if fFreeDataOnDestroy then begin
4608 SetDataPointer(NewData, tfEmpty); //be careful, Data could be freed by this method
4610 if (fID > 0) and fDeleteTextureOnFree then
4611 glDeleteTextures(1, @fID);
4612 inherited BeforeDestruction;
4615 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4616 procedure TglBitmap.PrepareResType(var aResource: String; var aResType: PChar);
4620 if not Assigned(aResType) then begin
4621 TempPos := Pos('.', aResource);
4622 aResType := PChar(UpperCase(Copy(aResource, TempPos + 1, Length(aResource) - TempPos)));
4623 aResource := UpperCase(Copy(aResource, 0, TempPos -1));
4627 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4628 procedure TglBitmap.LoadFromFile(const aFilename: String);
4632 if not FileExists(aFilename) then
4633 raise EglBitmap.Create('file does not exist: ' + aFilename);
4634 fFilename := aFilename;
4635 fs := TFileStream.Create(fFilename, fmOpenRead);
4644 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4645 procedure TglBitmap.LoadFromStream(const aStream: TStream);
4647 {$IFDEF GLB_SUPPORT_PNG_READ}
4648 if not LoadPNG(aStream) then
4650 {$IFDEF GLB_SUPPORT_JPEG_READ}
4651 if not LoadJPEG(aStream) then
4653 if not LoadDDS(aStream) then
4654 if not LoadTGA(aStream) then
4655 if not LoadBMP(aStream) then
4656 raise EglBitmap.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
4659 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4660 procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
4661 const aFormat: TglBitmapFormat; const aArgs: Pointer);
4666 size := TFormatDescriptor.Get(aFormat).GetSize(aSize);
4667 GetMem(tmpData, size);
4669 FillChar(tmpData^, size, #$FF);
4670 SetDataPointer(tmpData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
4672 if Assigned(tmpData) then
4676 AddFunc(Self, aFunc, false, aFormat, aArgs);
4679 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4680 procedure TglBitmap.LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar);
4682 rs: TResourceStream;
4684 PrepareResType(aResource, aResType);
4685 rs := TResourceStream.Create(aInstance, aResource, aResType);
4693 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4694 procedure TglBitmap.LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
4696 rs: TResourceStream;
4698 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
4706 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4707 procedure TglBitmap.SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
4711 fs := TFileStream.Create(aFileName, fmCreate);
4714 SaveToStream(fs, aFileType);
4720 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4721 procedure TglBitmap.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
4724 {$IFDEF GLB_SUPPORT_PNG_WRITE}
4725 ftPNG: SavePNG(aStream);
4727 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
4728 ftJPEG: SaveJPEG(aStream);
4730 ftDDS: SaveDDS(aStream);
4731 ftTGA: SaveTGA(aStream);
4732 ftBMP: SaveBMP(aStream);
4736 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4737 function TglBitmap.AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer): Boolean;
4739 result := AddFunc(Self, aFunc, aCreateTemp, Format, aArgs);
4742 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4743 function TglBitmap.AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
4744 const aFormat: TglBitmapFormat; const aArgs: Pointer): Boolean;
4746 DestData, TmpData, SourceData: pByte;
4747 TempHeight, TempWidth: Integer;
4748 SourceFD, DestFD: TFormatDescriptor;
4749 SourceMD, DestMD: Pointer;
4751 FuncRec: TglBitmapFunctionRec;
4753 Assert(Assigned(Data));
4754 Assert(Assigned(aSource));
4755 Assert(Assigned(aSource.Data));
4758 if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
4759 SourceFD := TFormatDescriptor.Get(aSource.Format);
4760 DestFD := TFormatDescriptor.Get(aFormat);
4762 if (SourceFD.IsCompressed) then
4763 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', SourceFD.Format);
4764 if (DestFD.IsCompressed) then
4765 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', DestFD.Format);
4767 // inkompatible Formats so CreateTemp
4768 if (SourceFD.BitsPerPixel <> DestFD.BitsPerPixel) then
4769 aCreateTemp := true;
4772 TempHeight := Max(1, aSource.Height);
4773 TempWidth := Max(1, aSource.Width);
4775 FuncRec.Sender := Self;
4776 FuncRec.Args := aArgs;
4779 if aCreateTemp then begin
4780 GetMem(TmpData, DestFD.GetSize(TempWidth, TempHeight));
4781 DestData := TmpData;
4786 SourceFD.PreparePixel(FuncRec.Source);
4787 DestFD.PreparePixel (FuncRec.Dest);
4789 SourceMD := SourceFD.CreateMappingData;
4790 DestMD := DestFD.CreateMappingData;
4792 FuncRec.Size := aSource.Dimension;
4793 FuncRec.Position.Fields := FuncRec.Size.Fields;
4796 SourceData := aSource.Data;
4797 FuncRec.Position.Y := 0;
4798 while FuncRec.Position.Y < TempHeight do begin
4799 FuncRec.Position.X := 0;
4800 while FuncRec.Position.X < TempWidth do begin
4801 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
4803 DestFD.Map(FuncRec.Dest, DestData, DestMD);
4804 inc(FuncRec.Position.X);
4806 inc(FuncRec.Position.Y);
4809 // Updating Image or InternalFormat
4811 SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height) //be careful, Data could be freed by this method
4812 else if (aFormat <> fFormat) then
4817 SourceFD.FreeMappingData(SourceMD);
4818 DestFD.FreeMappingData(DestMD);
4821 if aCreateTemp and Assigned(TmpData) then
4829 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4830 function TglBitmap.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
4832 Row, RowSize: Integer;
4833 SourceData, TmpData: PByte;
4835 FormatDesc: TFormatDescriptor;
4837 function GetRowPointer(Row: Integer): pByte;
4839 result := aSurface.pixels;
4840 Inc(result, Row * RowSize);
4846 FormatDesc := TFormatDescriptor.Get(Format);
4847 if FormatDesc.IsCompressed then
4848 raise EglBitmapUnsupportedFormat.Create(Format);
4850 if Assigned(Data) then begin
4851 case Trunc(FormatDesc.PixelSize) of
4857 raise EglBitmapUnsupportedFormat.Create(Format);
4860 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
4861 FormatDesc.RedMask, FormatDesc.GreenMask, FormatDesc.BlueMask, FormatDesc.AlphaMask);
4863 RowSize := FormatDesc.GetSize(FileWidth, 1);
4865 for Row := 0 to FileHeight-1 do begin
4866 TmpData := GetRowPointer(Row);
4867 if Assigned(TmpData) then begin
4868 Move(SourceData^, TmpData^, RowSize);
4869 inc(SourceData, RowSize);
4876 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4877 function TglBitmap.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
4879 pSource, pData, pTempData: PByte;
4880 Row, RowSize, TempWidth, TempHeight: Integer;
4881 IntFormat: TglBitmapFormat;
4882 fd: TFormatDescriptor;
4883 Mask: TglBitmapMask;
4885 function GetRowPointer(Row: Integer): pByte;
4887 result := aSurface^.pixels;
4888 Inc(result, Row * RowSize);
4893 if (Assigned(aSurface)) then begin
4894 with aSurface^.format^ do begin
4899 IntFormat := TFormatDescriptor.GetFromMask(Mask).Format;
4900 if (IntFormat = tfEmpty) then
4901 raise EglBitmap.Create('AssignFromSurface - Invalid Pixelformat.');
4904 fd := TFormatDescriptor.Get(IntFormat);
4905 TempWidth := aSurface^.w;
4906 TempHeight := aSurface^.h;
4907 RowSize := fd.GetSize(TempWidth, 1);
4908 GetMem(pData, TempHeight * RowSize);
4911 for Row := 0 to TempHeight -1 do begin
4912 pSource := GetRowPointer(Row);
4913 if (Assigned(pSource)) then begin
4914 Move(pSource^, pTempData^, RowSize);
4915 Inc(pTempData, RowSize);
4918 SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
4921 if Assigned(pData) then
4928 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4929 function TglBitmap.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
4931 Row, Col, AlphaInterleave: Integer;
4932 pSource, pDest: PByte;
4934 function GetRowPointer(Row: Integer): pByte;
4936 result := aSurface.pixels;
4937 Inc(result, Row * Width);
4942 if Assigned(Data) then begin
4943 if Format in [tfAlpha8ub1, tfLuminance8Alpha8ub2, tfBGRA8ub4, tfRGBA8ub4] then begin
4944 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
4946 AlphaInterleave := 0;
4948 tfLuminance8Alpha8ub2:
4949 AlphaInterleave := 1;
4950 tfBGRA8ub4, tfRGBA8ub4:
4951 AlphaInterleave := 3;
4955 for Row := 0 to Height -1 do begin
4956 pDest := GetRowPointer(Row);
4957 if Assigned(pDest) then begin
4958 for Col := 0 to Width -1 do begin
4959 Inc(pSource, AlphaInterleave);
4971 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4972 function TglBitmap.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
4976 bmp := TglBitmap2D.Create;
4978 bmp.AssignFromSurface(aSurface);
4979 result := AddAlphaFromGlBitmap(bmp, aFunc, aArgs);
4987 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4988 function CreateGrayPalette: HPALETTE;
4993 GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
4995 Pal.palVersion := $300;
4996 Pal.palNumEntries := 256;
4998 for Idx := 0 to Pal.palNumEntries - 1 do begin
4999 Pal.palPalEntry[Idx].peRed := Idx;
5000 Pal.palPalEntry[Idx].peGreen := Idx;
5001 Pal.palPalEntry[Idx].peBlue := Idx;
5002 Pal.palPalEntry[Idx].peFlags := 0;
5004 Result := CreatePalette(Pal^);
5008 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5009 function TglBitmap.AssignToBitmap(const aBitmap: TBitmap): Boolean;
5012 pSource, pData: PByte;
5015 if Assigned(Data) then begin
5016 if Assigned(aBitmap) then begin
5017 aBitmap.Width := Width;
5018 aBitmap.Height := Height;
5021 tfAlpha8ub1, tfLuminance8ub1: begin
5022 aBitmap.PixelFormat := pf8bit;
5023 aBitmap.Palette := CreateGrayPalette;
5026 aBitmap.PixelFormat := pf15bit;
5028 aBitmap.PixelFormat := pf16bit;
5029 tfRGB8ub3, tfBGR8ub3:
5030 aBitmap.PixelFormat := pf24bit;
5031 tfRGBA8ub4, tfBGRA8ub4:
5032 aBitmap.PixelFormat := pf32bit;
5034 raise EglBitmap.Create('AssignToBitmap - Invalid Pixelformat.');
5038 for Row := 0 to FileHeight -1 do begin
5039 pData := aBitmap.Scanline[Row];
5040 Move(pSource^, pData^, fRowSize);
5041 Inc(pSource, fRowSize);
5042 if (Format in [tfRGB8ub3, tfRGBA8ub4]) then // swap RGB(A) to BGR(A)
5043 SwapRGB(pData, FileWidth, Format = tfRGBA8ub4);
5050 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5051 function TglBitmap.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
5053 pSource, pData, pTempData: PByte;
5054 Row, RowSize, TempWidth, TempHeight: Integer;
5055 IntFormat: TglBitmapFormat;
5059 if (Assigned(aBitmap)) then begin
5060 case aBitmap.PixelFormat of
5062 IntFormat := tfLuminance8ub1;
5064 IntFormat := tfRGB5A1us1;
5066 IntFormat := tfR5G6B5us1;
5068 IntFormat := tfBGR8ub3;
5070 IntFormat := tfBGRA8ub4;
5072 raise EglBitmap.Create('AssignFromBitmap - Invalid Pixelformat.');
5075 TempWidth := aBitmap.Width;
5076 TempHeight := aBitmap.Height;
5077 RowSize := TFormatDescriptor.Get(IntFormat).GetSize(TempWidth, 1);
5078 GetMem(pData, TempHeight * RowSize);
5081 for Row := 0 to TempHeight -1 do begin
5082 pSource := aBitmap.Scanline[Row];
5083 if (Assigned(pSource)) then begin
5084 Move(pSource^, pTempData^, RowSize);
5085 Inc(pTempData, RowSize);
5088 SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
5091 if Assigned(pData) then
5098 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5099 function TglBitmap.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
5101 Row, Col, AlphaInterleave: Integer;
5102 pSource, pDest: PByte;
5106 if Assigned(Data) then begin
5107 if (Format in [tfAlpha8ub1, tfLuminance8Alpha8ub2, tfRGBA8ub4, tfBGRA8ub4]) then begin
5108 if Assigned(aBitmap) then begin
5109 aBitmap.PixelFormat := pf8bit;
5110 aBitmap.Palette := CreateGrayPalette;
5111 aBitmap.Width := Width;
5112 aBitmap.Height := Height;
5115 tfLuminance8Alpha8ub2:
5116 AlphaInterleave := 1;
5117 tfRGBA8ub4, tfBGRA8ub4:
5118 AlphaInterleave := 3;
5120 AlphaInterleave := 0;
5126 for Row := 0 to Height -1 do begin
5127 pDest := aBitmap.Scanline[Row];
5128 if Assigned(pDest) then begin
5129 for Col := 0 to Width -1 do begin
5130 Inc(pSource, AlphaInterleave);
5143 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5144 function TglBitmap.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5148 tex := TglBitmap2D.Create;
5150 tex.AssignFromBitmap(ABitmap);
5151 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5158 {$IFDEF GLB_LAZARUS}
5159 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5160 function TglBitmap.AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
5162 rid: TRawImageDescription;
5163 FormatDesc: TFormatDescriptor;
5165 if not Assigned(Data) then
5166 raise EglBitmap.Create('no pixel data assigned. load data before save');
5169 if not Assigned(aImage) or (Format = tfEmpty) then
5171 FormatDesc := TFormatDescriptor.Get(Format);
5172 if FormatDesc.IsCompressed then
5175 FillChar(rid{%H-}, SizeOf(rid), 0);
5176 if FormatDesc.IsGrayscale then
5177 rid.Format := ricfGray
5179 rid.Format := ricfRGBA;
5182 rid.Height := Height;
5183 rid.Depth := FormatDesc.BitsPerPixel;
5184 rid.BitOrder := riboBitsInOrder;
5185 rid.ByteOrder := riboLSBFirst;
5186 rid.LineOrder := riloTopToBottom;
5187 rid.LineEnd := rileTight;
5188 rid.BitsPerPixel := FormatDesc.BitsPerPixel;
5189 rid.RedPrec := CountSetBits(FormatDesc.Range.r);
5190 rid.GreenPrec := CountSetBits(FormatDesc.Range.g);
5191 rid.BluePrec := CountSetBits(FormatDesc.Range.b);
5192 rid.AlphaPrec := CountSetBits(FormatDesc.Range.a);
5193 rid.RedShift := FormatDesc.Shift.r;
5194 rid.GreenShift := FormatDesc.Shift.g;
5195 rid.BlueShift := FormatDesc.Shift.b;
5196 rid.AlphaShift := FormatDesc.Shift.a;
5198 rid.MaskBitsPerPixel := 0;
5199 rid.PaletteColorCount := 0;
5201 aImage.DataDescription := rid;
5204 if not Assigned(aImage.PixelData) then
5205 raise EglBitmap.Create('error while creating LazIntfImage');
5206 Move(Data^, aImage.PixelData^, FormatDesc.GetSize(Dimension));
5211 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5212 function TglBitmap.AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
5215 FormatDesc: TFormatDescriptor;
5219 Mask: TglBitmapRec4ul;
5221 procedure CopyConvert;
5223 bfFormat: TbmpBitfieldFormat;
5224 pSourceLine, pDestLine: PByte;
5225 pSourceMD, pDestMD: Pointer;
5226 Shift, Prec: TglBitmapRec4ub;
5228 pixel: TglBitmapPixelData;
5230 bfFormat := TbmpBitfieldFormat.Create;
5231 with aImage.DataDescription do begin
5233 Prec.g := GreenPrec;
5235 Prec.a := AlphaPrec;
5236 Shift.r := RedShift;
5237 Shift.g := GreenShift;
5238 Shift.b := BlueShift;
5239 Shift.a := AlphaShift;
5240 bfFormat.SetValues(BitsPerPixel, Prec, Shift);
5242 pSourceMD := bfFormat.CreateMappingData;
5243 pDestMD := FormatDesc.CreateMappingData;
5245 for y := 0 to aImage.Height-1 do begin
5246 pSourceLine := aImage.PixelData + y {%H-}* aImage.DataDescription.BytesPerLine;
5247 pDestLine := ImageData + y * Round(FormatDesc.BytesPerPixel * aImage.Width);
5248 for x := 0 to aImage.Width-1 do begin
5249 bfFormat.Unmap(pSourceLine, pixel, pSourceMD);
5250 FormatDesc.Map(pixel, pDestLine, pDestMD);
5254 FormatDesc.FreeMappingData(pDestMD);
5255 bfFormat.FreeMappingData(pSourceMD);
5262 if not Assigned(aImage) then
5265 with aImage.DataDescription do begin
5266 Mask.r := (QWord(1 shl RedPrec )-1) shl RedShift;
5267 Mask.g := (QWord(1 shl GreenPrec)-1) shl GreenShift;
5268 Mask.b := (QWord(1 shl BluePrec )-1) shl BlueShift;
5269 Mask.a := (QWord(1 shl AlphaPrec)-1) shl AlphaShift;
5271 FormatDesc := TFormatDescriptor.GetFromMask(Mask);
5272 f := FormatDesc.Format;
5273 if (f = tfEmpty) then
5277 (FormatDesc.BitsPerPixel = aImage.DataDescription.Depth) and
5278 (aImage.DataDescription.BitsPerPixel = aImage.DataDescription.Depth);
5280 ImageSize := FormatDesc.GetSize(aImage.Width, aImage.Height);
5281 ImageData := GetMem(ImageSize);
5284 Move(aImage.PixelData^, ImageData^, ImageSize)
5287 SetDataPointer(ImageData, f, aImage.Width, aImage.Height); //be careful, Data could be freed by this method
5289 if Assigned(ImageData) then
5297 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5298 function TglBitmap.AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
5300 rid: TRawImageDescription;
5301 FormatDesc: TFormatDescriptor;
5302 Pixel: TglBitmapPixelData;
5308 if not Assigned(aImage) or (Format = tfEmpty) then
5310 FormatDesc := TFormatDescriptor.Get(Format);
5311 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
5314 FillChar(rid{%H-}, SizeOf(rid), 0);
5315 rid.Format := ricfGray;
5317 rid.Height := Height;
5318 rid.Depth := CountSetBits(FormatDesc.Range.a);
5319 rid.BitOrder := riboBitsInOrder;
5320 rid.ByteOrder := riboLSBFirst;
5321 rid.LineOrder := riloTopToBottom;
5322 rid.LineEnd := rileTight;
5323 rid.BitsPerPixel := 8 * Ceil(rid.Depth / 8);
5324 rid.RedPrec := CountSetBits(FormatDesc.Range.a);
5329 rid.GreenShift := 0;
5331 rid.AlphaShift := 0;
5333 rid.MaskBitsPerPixel := 0;
5334 rid.PaletteColorCount := 0;
5336 aImage.DataDescription := rid;
5339 srcMD := FormatDesc.CreateMappingData;
5341 FormatDesc.PreparePixel(Pixel);
5343 dst := aImage.PixelData;
5344 for y := 0 to Height-1 do
5345 for x := 0 to Width-1 do begin
5346 FormatDesc.Unmap(src, Pixel, srcMD);
5347 case rid.BitsPerPixel of
5349 dst^ := Pixel.Data.a;
5353 PWord(dst)^ := Pixel.Data.a;
5357 PByteArray(dst)^[0] := PByteArray(@Pixel.Data.a)^[0];
5358 PByteArray(dst)^[1] := PByteArray(@Pixel.Data.a)^[1];
5359 PByteArray(dst)^[2] := PByteArray(@Pixel.Data.a)^[2];
5363 PCardinal(dst)^ := Pixel.Data.a;
5367 raise EglBitmapUnsupportedFormat.Create(Format);
5371 FormatDesc.FreeMappingData(srcMD);
5376 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5377 function TglBitmap.AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5381 tex := TglBitmap2D.Create;
5383 tex.AssignFromLazIntfImage(aImage);
5384 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5391 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5392 function TglBitmap.AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar;
5393 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5395 rs: TResourceStream;
5397 PrepareResType(aResource, aResType);
5398 rs := TResourceStream.Create(aInstance, aResource, aResType);
5400 result := AddAlphaFromStream(rs, aFunc, aArgs);
5406 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5407 function TglBitmap.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
5408 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5410 rs: TResourceStream;
5412 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
5414 result := AddAlphaFromStream(rs, aFunc, aArgs);
5420 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5421 function TglBitmap.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5423 if TFormatDescriptor.Get(Format).IsCompressed then
5424 raise EglBitmapUnsupportedFormat.Create(Format);
5425 result := AddFunc(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs);
5428 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5429 function TglBitmap.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5433 FS := TFileStream.Create(aFileName, fmOpenRead);
5435 result := AddAlphaFromStream(FS, aFunc, aArgs);
5441 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5442 function TglBitmap.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5446 tex := TglBitmap2D.Create(aStream);
5448 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5454 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5455 function TglBitmap.AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5457 DestData, DestData2, SourceData: pByte;
5458 TempHeight, TempWidth: Integer;
5459 SourceFD, DestFD: TFormatDescriptor;
5460 SourceMD, DestMD, DestMD2: Pointer;
5462 FuncRec: TglBitmapFunctionRec;
5466 Assert(Assigned(Data));
5467 Assert(Assigned(aBitmap));
5468 Assert(Assigned(aBitmap.Data));
5470 if ((aBitmap.Width = Width) and (aBitmap.Height = Height)) then begin
5471 result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
5473 SourceFD := TFormatDescriptor.Get(aBitmap.Format);
5474 DestFD := TFormatDescriptor.Get(Format);
5476 if not Assigned(aFunc) then begin
5477 aFunc := glBitmapAlphaFunc;
5478 FuncRec.Args := {%H-}Pointer(SourceFD.HasAlpha);
5480 FuncRec.Args := aArgs;
5483 TempHeight := aBitmap.FileHeight;
5484 TempWidth := aBitmap.FileWidth;
5486 FuncRec.Sender := Self;
5487 FuncRec.Size := Dimension;
5488 FuncRec.Position.Fields := FuncRec.Size.Fields;
5492 SourceData := aBitmap.Data;
5495 SourceFD.PreparePixel(FuncRec.Source);
5496 DestFD.PreparePixel (FuncRec.Dest);
5498 SourceMD := SourceFD.CreateMappingData;
5499 DestMD := DestFD.CreateMappingData;
5500 DestMD2 := DestFD.CreateMappingData;
5502 FuncRec.Position.Y := 0;
5503 while FuncRec.Position.Y < TempHeight do begin
5504 FuncRec.Position.X := 0;
5505 while FuncRec.Position.X < TempWidth do begin
5506 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
5507 DestFD.Unmap (DestData, FuncRec.Dest, DestMD);
5509 DestFD.Map(FuncRec.Dest, DestData2, DestMD2);
5510 inc(FuncRec.Position.X);
5512 inc(FuncRec.Position.Y);
5515 SourceFD.FreeMappingData(SourceMD);
5516 DestFD.FreeMappingData(DestMD);
5517 DestFD.FreeMappingData(DestMD2);
5522 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5523 function TglBitmap.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
5525 result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
5528 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5529 function TglBitmap.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
5531 PixelData: TglBitmapPixelData;
5533 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5534 result := AddAlphaFromColorKeyFloat(
5535 aRed / PixelData.Range.r,
5536 aGreen / PixelData.Range.g,
5537 aBlue / PixelData.Range.b,
5538 aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b)));
5541 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5542 function TglBitmap.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
5544 values: array[0..2] of Single;
5547 PixelData: TglBitmapPixelData;
5549 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5550 with PixelData do begin
5552 values[1] := aGreen;
5555 for i := 0 to 2 do begin
5556 tmp := Trunc(Range.arr[i] * aDeviation);
5557 Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp));
5558 Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp));
5563 result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, @PixelData);
5566 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5567 function TglBitmap.AddAlphaFromValue(const aAlpha: Byte): Boolean;
5569 result := AddAlphaFromValueFloat(aAlpha / $FF);
5572 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5573 function TglBitmap.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
5575 PixelData: TglBitmapPixelData;
5577 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5578 result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
5581 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5582 function TglBitmap.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
5584 PixelData: TglBitmapPixelData;
5586 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5588 Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
5589 result := AddAlphaFromFunc(glBitmapValueAlphaFunc, @PixelData.Data.a);
5592 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5593 function TglBitmap.RemoveAlpha: Boolean;
5595 FormatDesc: TFormatDescriptor;
5598 FormatDesc := TFormatDescriptor.Get(Format);
5599 if Assigned(Data) then begin
5600 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
5601 raise EglBitmapUnsupportedFormat.Create(Format);
5602 result := ConvertTo(FormatDesc.WithoutAlpha);
5606 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5607 function TglBitmap.Clone: TglBitmap;
5614 Temp := (ClassType.Create as TglBitmap);
5616 // copy texture data if assigned
5617 if Assigned(Data) then begin
5618 Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
5619 GetMem(TempPtr, Size);
5621 Move(Data^, TempPtr^, Size);
5622 Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
5624 if Assigned(TempPtr) then
5630 Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
5635 Temp.fTarget := Target;
5636 Temp.fFormat := Format;
5637 Temp.fMipMap := MipMap;
5638 Temp.fAnisotropic := Anisotropic;
5639 Temp.fBorderColor := fBorderColor;
5640 Temp.fDeleteTextureOnFree := DeleteTextureOnFree;
5641 Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
5642 Temp.fFilterMin := fFilterMin;
5643 Temp.fFilterMag := fFilterMag;
5644 Temp.fWrapS := fWrapS;
5645 Temp.fWrapT := fWrapT;
5646 Temp.fWrapR := fWrapR;
5647 Temp.fFilename := fFilename;
5648 Temp.fCustomName := fCustomName;
5649 Temp.fCustomNameW := fCustomNameW;
5650 Temp.fCustomData := fCustomData;
5659 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5660 function TglBitmap.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
5662 SourceFD, DestFD: TFormatDescriptor;
5663 SourcePD, DestPD: TglBitmapPixelData;
5664 ShiftData: TShiftData;
5666 function DataIsIdentical: Boolean;
5668 result := SourceFD.MaskMatch(DestFD.Mask);
5671 function CanCopyDirect: Boolean;
5674 ((SourcePD.Range.r = DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
5675 ((SourcePD.Range.g = DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
5676 ((SourcePD.Range.b = DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
5677 ((SourcePD.Range.a = DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
5680 function CanShift: Boolean;
5683 ((SourcePD.Range.r >= DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
5684 ((SourcePD.Range.g >= DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
5685 ((SourcePD.Range.b >= DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
5686 ((SourcePD.Range.a >= DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
5689 function GetShift(aSource, aDest: Cardinal) : ShortInt;
5692 while (aSource > aDest) and (aSource > 0) do begin
5694 aSource := aSource shr 1;
5699 if (aFormat <> fFormat) and (aFormat <> tfEmpty) then begin
5700 SourceFD := TFormatDescriptor.Get(Format);
5701 DestFD := TFormatDescriptor.Get(aFormat);
5703 if DataIsIdentical then begin
5709 SourceFD.PreparePixel(SourcePD);
5710 DestFD.PreparePixel (DestPD);
5712 if CanCopyDirect then
5713 result := AddFunc(Self, glBitmapConvertCopyFunc, false, aFormat)
5714 else if CanShift then begin
5715 ShiftData.r := GetShift(SourcePD.Range.r, DestPD.Range.r);
5716 ShiftData.g := GetShift(SourcePD.Range.g, DestPD.Range.g);
5717 ShiftData.b := GetShift(SourcePD.Range.b, DestPD.Range.b);
5718 ShiftData.a := GetShift(SourcePD.Range.a, DestPD.Range.a);
5719 result := AddFunc(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, @ShiftData);
5721 result := AddFunc(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
5726 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5727 procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
5729 if aUseRGB or aUseAlpha then
5730 AddFunc(glBitmapInvertFunc, false, {%H-}Pointer(
5731 ((Byte(aUseAlpha) and 1) shl 1) or
5732 (Byte(aUseRGB) and 1) ));
5735 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5736 procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
5738 fBorderColor[0] := aRed;
5739 fBorderColor[1] := aGreen;
5740 fBorderColor[2] := aBlue;
5741 fBorderColor[3] := aAlpha;
5742 if (ID > 0) then begin
5744 glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
5748 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5749 procedure TglBitmap.FreeData;
5754 SetDataPointer(TempPtr, tfEmpty); //be careful, Data could be freed by this method
5757 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5758 procedure TglBitmap.FillWithColor(const aRed, aGreen, aBlue: Byte;
5759 const aAlpha: Byte);
5761 FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
5764 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5765 procedure TglBitmap.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
5767 PixelData: TglBitmapPixelData;
5769 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5771 aRed / PixelData.Range.r,
5772 aGreen / PixelData.Range.g,
5773 aBlue / PixelData.Range.b,
5774 aAlpha / PixelData.Range.a);
5777 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5778 procedure TglBitmap.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
5780 PixelData: TglBitmapPixelData;
5782 TFormatDescriptor.Get(Format).PreparePixel(PixelData);
5783 with PixelData do begin
5784 Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed)));
5785 Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen)));
5786 Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue)));
5787 Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha)));
5789 AddFunc(glBitmapFillWithColorFunc, false, @PixelData);
5792 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5793 procedure TglBitmap.SetFilter(const aMin, aMag: GLenum);
5798 fFilterMin := GL_NEAREST;
5800 fFilterMin := GL_LINEAR;
5801 GL_NEAREST_MIPMAP_NEAREST:
5802 fFilterMin := GL_NEAREST_MIPMAP_NEAREST;
5803 GL_LINEAR_MIPMAP_NEAREST:
5804 fFilterMin := GL_LINEAR_MIPMAP_NEAREST;
5805 GL_NEAREST_MIPMAP_LINEAR:
5806 fFilterMin := GL_NEAREST_MIPMAP_LINEAR;
5807 GL_LINEAR_MIPMAP_LINEAR:
5808 fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
5810 raise EglBitmap.Create('SetFilter - Unknow MIN filter.');
5816 fFilterMag := GL_NEAREST;
5818 fFilterMag := GL_LINEAR;
5820 raise EglBitmap.Create('SetFilter - Unknow MAG filter.');
5824 if (ID > 0) then begin
5826 glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
5828 if (MipMap = mmNone) or (Target = GL_TEXTURE_RECTANGLE) then begin
5830 GL_NEAREST, GL_LINEAR:
5831 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
5832 GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR:
5833 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5834 GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR:
5835 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5838 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
5842 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5843 procedure TglBitmap.SetWrap(const S: GLenum; const T: GLenum; const R: GLenum);
5845 procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
5849 aTarget := GL_CLAMP;
5852 aTarget := GL_REPEAT;
5854 GL_CLAMP_TO_EDGE: begin
5855 if GL_VERSION_1_2 or GL_EXT_texture_edge_clamp then
5856 aTarget := GL_CLAMP_TO_EDGE
5858 aTarget := GL_CLAMP;
5861 GL_CLAMP_TO_BORDER: begin
5862 if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
5863 aTarget := GL_CLAMP_TO_BORDER
5865 aTarget := GL_CLAMP;
5868 GL_MIRRORED_REPEAT: begin
5869 if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
5870 aTarget := GL_MIRRORED_REPEAT
5872 raise EglBitmap.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
5875 raise EglBitmap.Create('SetWrap - Unknow Texturewrap');
5880 CheckAndSetWrap(S, fWrapS);
5881 CheckAndSetWrap(T, fWrapT);
5882 CheckAndSetWrap(R, fWrapR);
5884 if (ID > 0) then begin
5886 glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
5887 glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
5888 glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
5892 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5893 procedure TglBitmap.SetSwizzle(const r, g, b, a: GLenum);
5895 procedure CheckAndSetValue(const aValue: GLenum; const aIndex: Integer);
5897 if (aValue = GL_ZERO) or (aValue = GL_ONE) or (aValue = GL_ALPHA) or
5898 (aValue = GL_RED) or (aValue = GL_GREEN) or (aValue = GL_BLUE) then
5899 fSwizzle[aIndex] := aValue
5901 raise EglBitmap.Create('SetSwizzle - Unknow Swizle Value');
5905 if not (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
5906 raise EglBitmapNotSupported.Create('texture swizzle is not supported');
5907 CheckAndSetValue(r, 0);
5908 CheckAndSetValue(g, 1);
5909 CheckAndSetValue(b, 2);
5910 CheckAndSetValue(a, 3);
5912 if (ID > 0) then begin
5914 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_RGBA, PGLint(@fSwizzle[0]));
5918 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5919 procedure TglBitmap.Bind(const aEnableTextureUnit: Boolean);
5921 if aEnableTextureUnit then
5924 glBindTexture(Target, ID);
5927 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5928 procedure TglBitmap.Unbind(const aDisableTextureUnit: Boolean);
5930 if aDisableTextureUnit then
5932 glBindTexture(Target, 0);
5935 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5936 constructor TglBitmap.Create;
5938 if (ClassType = TglBitmap) then
5939 raise EglBitmap.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
5940 {$IFDEF GLB_NATIVE_OGL}
5941 glbReadOpenGLExtensions;
5944 fFormat := glBitmapGetDefaultFormat;
5945 fFreeDataOnDestroy := true;
5948 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5949 constructor TglBitmap.Create(const aFileName: String);
5952 LoadFromFile(aFileName);
5955 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5956 constructor TglBitmap.Create(const aStream: TStream);
5959 LoadFromStream(aStream);
5962 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5963 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; aData: PByte);
5968 if not Assigned(aData) then begin
5969 ImageSize := TFormatDescriptor.Get(aFormat).GetSize(aSize);
5970 GetMem(aData, ImageSize);
5972 FillChar(aData^, ImageSize, #$FF);
5973 SetDataPointer(aData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
5975 if Assigned(aData) then
5980 SetDataPointer(aData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
5981 fFreeDataOnDestroy := false;
5985 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5986 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer);
5989 LoadFromFunc(aSize, aFunc, aFormat, aArgs);
5992 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5993 constructor TglBitmap.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
5996 LoadFromResource(aInstance, aResource, aResType);
5999 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6000 constructor TglBitmap.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
6003 LoadFromResourceID(aInstance, aResourceID, aResType);
6006 {$IFDEF GLB_SUPPORT_PNG_READ}
6007 {$IF DEFINED(GLB_LAZ_PNG)}
6008 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6009 //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6010 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6011 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6014 PNG_MAGIC: String[MAGIC_LEN] = #$89#$50#$4E#$47#$0D#$0A#$1A#$0A;
6016 reader: TLazReaderPNG;
6017 intf: TLazIntfImage;
6019 magic: String[MAGIC_LEN];
6022 StreamPos := aStream.Position;
6024 SetLength(magic, MAGIC_LEN);
6025 aStream.Read(magic[1], MAGIC_LEN);
6026 aStream.Position := StreamPos;
6027 if (magic <> PNG_MAGIC) then begin
6032 intf := TLazIntfImage.Create(0, 0);
6033 reader := TLazReaderPNG.Create;
6035 reader.UpdateDescription := true;
6036 reader.ImageRead(aStream, intf);
6037 AssignFromLazIntfImage(intf);
6040 aStream.Position := StreamPos;
6049 {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
6050 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6051 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6053 Surface: PSDL_Surface;
6057 RWops := glBitmapCreateRWops(aStream);
6059 if IMG_isPNG(RWops) > 0 then begin
6060 Surface := IMG_LoadPNG_RW(RWops);
6062 AssignFromSurface(Surface);
6065 SDL_FreeSurface(Surface);
6073 {$ELSEIF DEFINED(GLB_LIB_PNG)}
6074 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6075 procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
6077 TStream(png_get_io_ptr(png)).Read(buffer^, size);
6080 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6081 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6084 signature: array [0..7] of byte;
6086 png_info: png_infop;
6088 TempHeight, TempWidth: Integer;
6089 Format: TglBitmapFormat;
6092 png_rows: array of pByte;
6093 Row, LineSize: Integer;
6097 if not init_libPNG then
6098 raise Exception.Create('LoadPNG - unable to initialize libPNG.');
6102 StreamPos := aStream.Position;
6103 aStream.Read(signature{%H-}, 8);
6104 aStream.Position := StreamPos;
6106 if png_check_sig(@signature, 8) <> 0 then begin
6108 png := png_create_read_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
6110 raise EglBitmapException.Create('LoadPng - couldn''t create read struct.');
6113 png_info := png_create_info_struct(png);
6114 if png_info = nil then begin
6115 png_destroy_read_struct(@png, nil, nil);
6116 raise EglBitmapException.Create('LoadPng - couldn''t create info struct.');
6119 // set read callback
6120 png_set_read_fn(png, aStream, glBitmap_libPNG_read_func);
6122 // read informations
6123 png_read_info(png, png_info);
6126 TempHeight := png_get_image_height(png, png_info);
6127 TempWidth := png_get_image_width(png, png_info);
6130 case png_get_color_type(png, png_info) of
6131 PNG_COLOR_TYPE_GRAY:
6132 Format := tfLuminance8ub1;
6133 PNG_COLOR_TYPE_GRAY_ALPHA:
6134 Format := tfLuminance8Alpha8us1;
6136 Format := tfRGB8ub3;
6137 PNG_COLOR_TYPE_RGB_ALPHA:
6138 Format := tfRGBA8ub4;
6140 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6143 // cut upper 8 bit from 16 bit formats
6144 if png_get_bit_depth(png, png_info) > 8 then
6145 png_set_strip_16(png);
6147 // expand bitdepth smaller than 8
6148 if png_get_bit_depth(png, png_info) < 8 then
6149 png_set_expand(png);
6151 // allocating mem for scanlines
6152 LineSize := png_get_rowbytes(png, png_info);
6153 GetMem(png_data, TempHeight * LineSize);
6155 SetLength(png_rows, TempHeight);
6156 for Row := Low(png_rows) to High(png_rows) do begin
6157 png_rows[Row] := png_data;
6158 Inc(png_rows[Row], Row * LineSize);
6161 // read complete image into scanlines
6162 png_read_image(png, @png_rows[0]);
6165 png_read_end(png, png_info);
6167 // destroy read struct
6168 png_destroy_read_struct(@png, @png_info, nil);
6170 SetLength(png_rows, 0);
6173 SetDataPointer(png_data, Format, TempWidth, TempHeight); //be careful, Data could be freed by this method
6177 if Assigned(png_data) then
6187 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
6188 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6189 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6194 Row, Col, PixSize, LineSize: Integer;
6195 NewImage, pSource, pDest, pAlpha: pByte;
6196 PngFormat: TglBitmapFormat;
6197 FormatDesc: TFormatDescriptor;
6200 PngHeader: String[8] = #137#80#78#71#13#10#26#10;
6205 StreamPos := aStream.Position;
6206 aStream.Read(Header[0], SizeOf(Header));
6207 aStream.Position := StreamPos;
6209 {Test if the header matches}
6210 if Header = PngHeader then begin
6211 Png := TPNGObject.Create;
6213 Png.LoadFromStream(aStream);
6215 case Png.Header.ColorType of
6217 PngFormat := tfLuminance8ub1;
6218 COLOR_GRAYSCALEALPHA:
6219 PngFormat := tfLuminance8Alpha8us1;
6221 PngFormat := tfBGR8ub3;
6223 PngFormat := tfBGRA8ub4;
6225 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6228 FormatDesc := TFormatDescriptor.Get(PngFormat);
6229 PixSize := Round(FormatDesc.PixelSize);
6230 LineSize := FormatDesc.GetSize(Png.Header.Width, 1);
6232 GetMem(NewImage, LineSize * Integer(Png.Header.Height));
6236 case Png.Header.ColorType of
6237 COLOR_RGB, COLOR_GRAYSCALE:
6239 for Row := 0 to Png.Height -1 do begin
6240 Move (Png.Scanline[Row]^, pDest^, LineSize);
6241 Inc(pDest, LineSize);
6244 COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA:
6246 PixSize := PixSize -1;
6248 for Row := 0 to Png.Height -1 do begin
6249 pSource := Png.Scanline[Row];
6250 pAlpha := pByte(Png.AlphaScanline[Row]);
6252 for Col := 0 to Png.Width -1 do begin
6253 Move (pSource^, pDest^, PixSize);
6254 Inc(pSource, PixSize);
6255 Inc(pDest, PixSize);
6264 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6267 SetDataPointer(NewImage, PngFormat, Png.Header.Width, Png.Header.Height); //be careful, Data could be freed by this method
6271 if Assigned(NewImage) then
6283 {$IFDEF GLB_SUPPORT_PNG_WRITE}
6284 {$IFDEF GLB_LIB_PNG}
6285 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6286 procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
6288 TStream(png_get_io_ptr(png)).Write(buffer^, size);
6292 {$IF DEFINED(GLB_LAZ_PNG)}
6293 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6294 procedure TglBitmap.SavePNG(const aStream: TStream);
6296 png: TPortableNetworkGraphic;
6297 intf: TLazIntfImage;
6300 png := TPortableNetworkGraphic.Create;
6301 intf := TLazIntfImage.Create(0, 0);
6303 if not AssignToLazIntfImage(intf) then
6304 raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
6305 intf.GetRawImage(raw);
6306 png.LoadFromRawImage(raw, false);
6307 png.SaveToStream(aStream);
6314 {$ELSEIF DEFINED(GLB_LIB_PNG)}
6315 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6316 procedure TglBitmap.SavePNG(const aStream: TStream);
6319 png_info: png_infop;
6320 png_rows: array of pByte;
6324 FormatDesc: TFormatDescriptor;
6326 if not (ftPNG in FormatGetSupportedFiles(Format)) then
6327 raise EglBitmapUnsupportedFormat.Create(Format);
6329 if not init_libPNG then
6330 raise Exception.Create('unable to initialize libPNG.');
6334 tfAlpha8ub1, tfLuminance8ub1:
6335 ColorType := PNG_COLOR_TYPE_GRAY;
6336 tfLuminance8Alpha8us1:
6337 ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
6338 tfBGR8ub3, tfRGB8ub3:
6339 ColorType := PNG_COLOR_TYPE_RGB;
6340 tfBGRA8ub4, tfRGBA8ub4:
6341 ColorType := PNG_COLOR_TYPE_RGBA;
6343 raise EglBitmapUnsupportedFormat.Create(Format);
6346 FormatDesc := TFormatDescriptor.Get(Format);
6347 LineSize := FormatDesc.GetSize(Width, 1);
6349 // creating array for scanline
6350 SetLength(png_rows, Height);
6352 for Row := 0 to Height - 1 do begin
6353 png_rows[Row] := Data;
6354 Inc(png_rows[Row], Row * LineSize)
6358 png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
6360 raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
6363 png_info := png_create_info_struct(png);
6364 if png_info = nil then begin
6365 png_destroy_write_struct(@png, nil);
6366 raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
6369 // set read callback
6370 png_set_write_fn(png, aStream, glBitmap_libPNG_write_func, nil);
6373 png_set_compression_level(png, 6);
6375 if Format in [tfBGR8ub3, tfBGRA8ub4] then
6378 png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
6379 png_write_info(png, png_info);
6380 png_write_image(png, @png_rows[0]);
6381 png_write_end(png, png_info);
6382 png_destroy_write_struct(@png, @png_info);
6384 SetLength(png_rows, 0);
6391 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
6392 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6393 procedure TglBitmap.SavePNG(const aStream: TStream);
6397 pSource, pDest: pByte;
6398 X, Y, PixSize: Integer;
6399 ColorType: Cardinal;
6405 if not (ftPNG in FormatGetSupportedFiles (Format)) then
6406 raise EglBitmapUnsupportedFormat.Create(Format);
6409 tfAlpha8ub1, tfLuminance8ub1: begin
6410 ColorType := COLOR_GRAYSCALE;
6414 tfLuminance8Alpha8us1: begin
6415 ColorType := COLOR_GRAYSCALEALPHA;
6419 tfBGR8ub3, tfRGB8ub3: begin
6420 ColorType := COLOR_RGB;
6424 tfBGRA8ub4, tfRGBA8ub4: begin
6425 ColorType := COLOR_RGBALPHA;
6430 raise EglBitmapUnsupportedFormat.Create(Format);
6433 Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
6437 for Y := 0 to Height -1 do begin
6438 pDest := png.ScanLine[Y];
6439 for X := 0 to Width -1 do begin
6440 Move(pSource^, pDest^, PixSize);
6441 Inc(pDest, PixSize);
6442 Inc(pSource, PixSize);
6444 png.AlphaScanline[Y]^[X] := pSource^;
6449 // convert RGB line to BGR
6450 if Format in [tfRGB8ub3, tfRGBA8ub4] then begin
6451 pTemp := png.ScanLine[Y];
6452 for X := 0 to Width -1 do begin
6453 Temp := pByteArray(pTemp)^[0];
6454 pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
6455 pByteArray(pTemp)^[2] := Temp;
6462 Png.CompressionLevel := 6;
6463 Png.SaveToStream(aStream);
6471 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6472 //JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6473 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6474 {$IFDEF GLB_LIB_JPEG}
6476 glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
6477 glBitmap_libJPEG_source_mgr = record
6478 pub: jpeg_source_mgr;
6481 SrcBuffer: array [1..4096] of byte;
6484 glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
6485 glBitmap_libJPEG_dest_mgr = record
6486 pub: jpeg_destination_mgr;
6488 DestStream: TStream;
6489 DestBuffer: array [1..4096] of byte;
6492 procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
6498 procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
6504 procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
6509 procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
6515 procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
6521 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6522 function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
6524 src: glBitmap_libJPEG_source_mgr_ptr;
6527 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
6529 bytes := src^.SrcStream.Read(src^.SrcBuffer[1], 4096);
6530 if (bytes <= 0) then begin
6531 src^.SrcBuffer[1] := $FF;
6532 src^.SrcBuffer[2] := JPEG_EOI;
6536 src^.pub.next_input_byte := @(src^.SrcBuffer[1]);
6537 src^.pub.bytes_in_buffer := bytes;
6542 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6543 procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
6545 src: glBitmap_libJPEG_source_mgr_ptr;
6547 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
6549 if num_bytes > 0 then begin
6550 // wanted byte isn't in buffer so set stream position and read buffer
6551 if num_bytes > src^.pub.bytes_in_buffer then begin
6552 src^.SrcStream.Position := src^.SrcStream.Position + num_bytes - src^.pub.bytes_in_buffer;
6553 src^.pub.fill_input_buffer(cinfo);
6555 // wanted byte is in buffer so only skip
6556 inc(src^.pub.next_input_byte, num_bytes);
6557 dec(src^.pub.bytes_in_buffer, num_bytes);
6562 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6563 function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
6565 dest: glBitmap_libJPEG_dest_mgr_ptr;
6567 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
6569 if dest^.pub.free_in_buffer < Cardinal(Length(dest^.DestBuffer)) then begin
6570 // write complete buffer
6571 dest^.DestStream.Write(dest^.DestBuffer[1], SizeOf(dest^.DestBuffer));
6574 dest^.pub.next_output_byte := @dest^.DestBuffer[1];
6575 dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
6581 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6582 procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
6585 dest: glBitmap_libJPEG_dest_mgr_ptr;
6587 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
6589 for Idx := Low(dest^.DestBuffer) to High(dest^.DestBuffer) do begin
6590 // check for endblock
6591 if (Idx < High(dest^.DestBuffer)) and (dest^.DestBuffer[Idx] = $FF) and (dest^.DestBuffer[Idx +1] = JPEG_EOI) then begin
6593 dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
6598 dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
6603 {$IFDEF GLB_SUPPORT_JPEG_READ}
6604 {$IF DEFINED(GLB_LAZ_JPEG)}
6605 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6606 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6609 JPEG_MAGIC: String[MAGIC_LEN] = #$FF#$D8;
6611 intf: TLazIntfImage;
6612 reader: TFPReaderJPEG;
6614 magic: String[MAGIC_LEN];
6617 StreamPos := aStream.Position;
6619 SetLength(magic, MAGIC_LEN);
6620 aStream.Read(magic[1], MAGIC_LEN);
6621 aStream.Position := StreamPos;
6622 if (magic <> JPEG_MAGIC) then begin
6627 reader := TFPReaderJPEG.Create;
6628 intf := TLazIntfImage.Create(0, 0);
6630 intf.DataDescription := GetDescriptionFromDevice(0, 0, 0);
6631 reader.ImageRead(aStream, intf);
6632 AssignFromLazIntfImage(intf);
6635 aStream.Position := StreamPos;
6644 {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
6645 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6646 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6648 Surface: PSDL_Surface;
6653 RWops := glBitmapCreateRWops(aStream);
6655 if IMG_isJPG(RWops) > 0 then begin
6656 Surface := IMG_LoadJPG_RW(RWops);
6658 AssignFromSurface(Surface);
6661 SDL_FreeSurface(Surface);
6669 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
6670 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6671 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6674 Temp: array[0..1]of Byte;
6676 jpeg: jpeg_decompress_struct;
6677 jpeg_err: jpeg_error_mgr;
6679 IntFormat: TglBitmapFormat;
6681 TempHeight, TempWidth: Integer;
6686 FormatDesc: TFormatDescriptor;
6690 if not init_libJPEG then
6691 raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
6694 // reading first two bytes to test file and set cursor back to begin
6695 StreamPos := aStream.Position;
6696 aStream.Read({%H-}Temp[0], 2);
6697 aStream.Position := StreamPos;
6699 // if Bitmap then read file.
6700 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
6701 FillChar(jpeg{%H-}, SizeOf(jpeg_decompress_struct), $00);
6702 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
6705 jpeg.err := jpeg_std_error(@jpeg_err);
6706 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
6707 jpeg_err.output_message := glBitmap_libJPEG_output_message;
6709 // decompression struct
6710 jpeg_create_decompress(@jpeg);
6712 // allocation space for streaming methods
6713 jpeg.src := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_source_mgr));
6715 // seeting up custom functions
6716 with glBitmap_libJPEG_source_mgr_ptr(jpeg.src)^ do begin
6717 pub.init_source := glBitmap_libJPEG_init_source;
6718 pub.fill_input_buffer := glBitmap_libJPEG_fill_input_buffer;
6719 pub.skip_input_data := glBitmap_libJPEG_skip_input_data;
6720 pub.resync_to_restart := jpeg_resync_to_restart; // use default method
6721 pub.term_source := glBitmap_libJPEG_term_source;
6723 pub.bytes_in_buffer := 0; // forces fill_input_buffer on first read
6724 pub.next_input_byte := nil; // until buffer loaded
6726 SrcStream := aStream;
6729 // set global decoding state
6730 jpeg.global_state := DSTATE_START;
6732 // read header of jpeg
6733 jpeg_read_header(@jpeg, false);
6735 // setting output parameter
6736 case jpeg.jpeg_color_space of
6739 jpeg.out_color_space := JCS_GRAYSCALE;
6740 IntFormat := tfLuminance8ub1;
6743 jpeg.out_color_space := JCS_RGB;
6744 IntFormat := tfRGB8ub3;
6748 jpeg_start_decompress(@jpeg);
6750 TempHeight := jpeg.output_height;
6751 TempWidth := jpeg.output_width;
6753 FormatDesc := TFormatDescriptor.Get(IntFormat);
6755 // creating new image
6756 GetMem(pImage, FormatDesc.GetSize(TempWidth, TempHeight));
6760 for Row := 0 to TempHeight -1 do begin
6761 jpeg_read_scanlines(@jpeg, @pTemp, 1);
6762 Inc(pTemp, FormatDesc.GetSize(TempWidth, 1));
6765 // finish decompression
6766 jpeg_finish_decompress(@jpeg);
6768 // destroy decompression
6769 jpeg_destroy_decompress(@jpeg);
6771 SetDataPointer(pImage, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
6775 if Assigned(pImage) then
6785 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
6786 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6787 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6792 Temp: array[0..1]of Byte;
6796 // reading first two bytes to test file and set cursor back to begin
6797 StreamPos := aStream.Position;
6798 aStream.Read(Temp[0], 2);
6799 aStream.Position := StreamPos;
6801 // if Bitmap then read file.
6802 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
6803 bmp := TBitmap.Create;
6805 jpg := TJPEGImage.Create;
6807 jpg.LoadFromStream(aStream);
6809 result := AssignFromBitmap(bmp);
6821 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
6822 {$IF DEFINED(GLB_LAZ_JPEG)}
6823 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6824 procedure TglBitmap.SaveJPEG(const aStream: TStream);
6827 intf: TLazIntfImage;
6830 jpeg := TJPEGImage.Create;
6831 intf := TLazIntfImage.Create(0, 0);
6833 if not AssignToLazIntfImage(intf) then
6834 raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
6835 intf.GetRawImage(raw);
6836 jpeg.LoadFromRawImage(raw, false);
6837 jpeg.SaveToStream(aStream);
6844 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
6845 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6846 procedure TglBitmap.SaveJPEG(const aStream: TStream);
6848 jpeg: jpeg_compress_struct;
6849 jpeg_err: jpeg_error_mgr;
6851 pTemp, pTemp2: pByte;
6853 procedure CopyRow(pDest, pSource: pByte);
6857 for X := 0 to Width - 1 do begin
6858 pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
6859 pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
6860 pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
6867 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
6868 raise EglBitmapUnsupportedFormat.Create(Format);
6870 if not init_libJPEG then
6871 raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
6874 FillChar(jpeg{%H-}, SizeOf(jpeg_compress_struct), $00);
6875 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
6878 jpeg.err := jpeg_std_error(@jpeg_err);
6879 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
6880 jpeg_err.output_message := glBitmap_libJPEG_output_message;
6882 // compression struct
6883 jpeg_create_compress(@jpeg);
6885 // allocation space for streaming methods
6886 jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
6888 // seeting up custom functions
6889 with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
6890 pub.init_destination := glBitmap_libJPEG_init_destination;
6891 pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
6892 pub.term_destination := glBitmap_libJPEG_term_destination;
6894 pub.next_output_byte := @DestBuffer[1];
6895 pub.free_in_buffer := Length(DestBuffer);
6897 DestStream := aStream;
6900 // very important state
6901 jpeg.global_state := CSTATE_START;
6902 jpeg.image_width := Width;
6903 jpeg.image_height := Height;
6905 tfAlpha8ub1, tfLuminance8ub1: begin
6906 jpeg.input_components := 1;
6907 jpeg.in_color_space := JCS_GRAYSCALE;
6909 tfRGB8ub3, tfBGR8ub3: begin
6910 jpeg.input_components := 3;
6911 jpeg.in_color_space := JCS_RGB;
6915 jpeg_set_defaults(@jpeg);
6916 jpeg_set_quality(@jpeg, 95, true);
6917 jpeg_start_compress(@jpeg, true);
6920 if Format = tfBGR8ub3 then
6921 GetMem(pTemp2, fRowSize)
6926 for Row := 0 to jpeg.image_height -1 do begin
6928 if Format = tfBGR8ub3 then
6929 CopyRow(pTemp2, pTemp)
6934 jpeg_write_scanlines(@jpeg, @pTemp2, 1);
6935 inc(pTemp, fRowSize);
6939 if Format = tfBGR8ub3 then
6942 jpeg_finish_compress(@jpeg);
6943 jpeg_destroy_compress(@jpeg);
6949 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
6950 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6951 procedure TglBitmap.SaveJPEG(const aStream: TStream);
6956 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
6957 raise EglBitmapUnsupportedFormat.Create(Format);
6959 Bmp := TBitmap.Create;
6961 Jpg := TJPEGImage.Create;
6963 AssignToBitmap(Bmp);
6964 if (Format in [tfAlpha8ub1, tfLuminance8ub1]) then begin
6965 Jpg.Grayscale := true;
6966 Jpg.PixelFormat := jf8Bit;
6969 Jpg.SaveToStream(aStream);
6980 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6981 //BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6982 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6989 BMP_COMP_BITFIELDS = 3;
6992 TBMPHeader = packed record
6997 bfOffBits: Cardinal;
7000 TBMPInfo = packed record
7006 biCompression: Cardinal;
7007 biSizeImage: Cardinal;
7008 biXPelsPerMeter: Longint;
7009 biYPelsPerMeter: Longint;
7010 biClrUsed: Cardinal;
7011 biClrImportant: Cardinal;
7014 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7015 function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
7017 //////////////////////////////////////////////////////////////////////////////////////////////////
7018 function ReadInfo(out aInfo: TBMPInfo; out aMask: TglBitmapRec4ul): TglBitmapFormat;
7021 aStream.Read(aInfo{%H-}, SizeOf(aInfo));
7022 FillChar(aMask{%H-}, SizeOf(aMask), 0);
7025 case aInfo.biCompression of
7027 BMP_COMP_RLE8: begin
7028 raise EglBitmap.Create('RLE compression is not supported');
7030 BMP_COMP_BITFIELDS: begin
7031 if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
7032 aStream.Read(aMask.r, SizeOf(aMask.r));
7033 aStream.Read(aMask.g, SizeOf(aMask.g));
7034 aStream.Read(aMask.b, SizeOf(aMask.b));
7035 aStream.Read(aMask.a, SizeOf(aMask.a));
7037 raise EglBitmap.Create('Bitfields are only supported for 16bit and 32bit formats');
7041 //get suitable format
7042 case aInfo.biBitCount of
7043 8: result := tfLuminance8ub1;
7044 16: result := tfX1RGB5us1;
7045 24: result := tfBGR8ub3;
7046 32: result := tfXRGB8ui1;
7050 function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TbmpColorTableFormat;
7053 ColorTable: TbmpColorTable;
7056 if (aInfo.biBitCount >= 16) then
7058 aFormat := tfLuminance8ub1;
7059 c := aInfo.biClrUsed;
7061 c := 1 shl aInfo.biBitCount;
7062 SetLength(ColorTable, c);
7063 for i := 0 to c-1 do begin
7064 aStream.Read(ColorTable[i], SizeOf(TbmpColorTableEnty));
7065 if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then
7066 aFormat := tfRGB8ub3;
7069 result := TbmpColorTableFormat.Create;
7070 result.BitsPerPixel := aInfo.biBitCount;
7071 result.ColorTable := ColorTable;
7075 //////////////////////////////////////////////////////////////////////////////////////////////////
7076 function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapRec4ul; const aInfo: TBMPInfo): TbmpBitfieldFormat;
7078 FormatDesc: TFormatDescriptor;
7081 if (aMask.r <> 0) or (aMask.g <> 0) or (aMask.b <> 0) or (aMask.a <> 0) then begin
7082 FormatDesc := TFormatDescriptor.GetFromMask(aMask);
7083 if (FormatDesc.Format = tfEmpty) then
7085 aFormat := FormatDesc.Format;
7086 if (aMask.a = 0) and TFormatDescriptor.Get(aFormat).HasAlpha then
7087 aFormat := TFormatDescriptor.Get(aFormat).WithoutAlpha;
7088 if (aMask.a <> 0) and not TFormatDescriptor.Get(aFormat).HasAlpha then
7089 aFormat := TFormatDescriptor.Get(aFormat).WithAlpha;
7091 result := TbmpBitfieldFormat.Create;
7092 result.SetValues(aInfo.biBitCount, aMask);
7099 ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
7100 PaddingBuff: Cardinal;
7101 LineBuf, ImageData, TmpData: PByte;
7102 SourceMD, DestMD: Pointer;
7103 BmpFormat: TglBitmapFormat;
7106 Mask: TglBitmapRec4ul;
7111 SpecialFormat: TFormatDescriptor;
7112 FormatDesc: TFormatDescriptor;
7114 //////////////////////////////////////////////////////////////////////////////////////////////////
7115 procedure SpecialFormatReadLine(aData: PByte; aLineBuf: PByte);
7118 Pixel: TglBitmapPixelData;
7120 aStream.Read(aLineBuf^, rbLineSize);
7121 SpecialFormat.PreparePixel(Pixel);
7122 for i := 0 to Info.biWidth-1 do begin
7123 SpecialFormat.Unmap(aLineBuf, Pixel, SourceMD);
7124 glBitmapConvertPixel(Pixel, SpecialFormat, FormatDesc);
7125 FormatDesc.Map(Pixel, aData, DestMD);
7131 BmpFormat := tfEmpty;
7132 SpecialFormat := nil;
7138 StartPos := aStream.Position;
7139 aStream.Read(Header{%H-}, SizeOf(Header));
7141 if Header.bfType = BMP_MAGIC then begin
7143 BmpFormat := ReadInfo(Info, Mask);
7144 SpecialFormat := ReadColorTable(BmpFormat, Info);
7145 if not Assigned(SpecialFormat) then
7146 SpecialFormat := CheckBitfields(BmpFormat, Mask, Info);
7147 aStream.Position := StartPos + Header.bfOffBits;
7149 if (BmpFormat <> tfEmpty) then begin
7150 FormatDesc := TFormatDescriptor.Get(BmpFormat);
7151 rbLineSize := Round(Info.biWidth * Info.biBitCount / 8); //ReadBuffer LineSize
7152 wbLineSize := Trunc(Info.biWidth * FormatDesc.BytesPerPixel);
7153 Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
7156 DestMD := FormatDesc.CreateMappingData;
7157 ImageSize := FormatDesc.GetSize(Info.biWidth, abs(Info.biHeight));
7158 GetMem(ImageData, ImageSize);
7159 if Assigned(SpecialFormat) then begin
7160 GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
7161 SourceMD := SpecialFormat.CreateMappingData;
7166 FillChar(ImageData^, ImageSize, $FF);
7167 TmpData := ImageData;
7168 if (Info.biHeight > 0) then
7169 Inc(TmpData, wbLineSize * (Info.biHeight-1));
7170 for i := 0 to Abs(Info.biHeight)-1 do begin
7171 if Assigned(SpecialFormat) then
7172 SpecialFormatReadLine(TmpData, LineBuf) //if is special format read and convert data
7174 aStream.Read(TmpData^, wbLineSize); //else only read data
7175 if (Info.biHeight > 0) then
7176 dec(TmpData, wbLineSize)
7178 inc(TmpData, wbLineSize);
7179 aStream.Read(PaddingBuff{%H-}, Padding);
7181 SetDataPointer(ImageData, BmpFormat, Info.biWidth, abs(Info.biHeight)); //be careful, Data could be freed by this method
7184 if Assigned(LineBuf) then
7186 if Assigned(SourceMD) then
7187 SpecialFormat.FreeMappingData(SourceMD);
7188 FormatDesc.FreeMappingData(DestMD);
7191 if Assigned(ImageData) then
7196 raise EglBitmap.Create('LoadBMP - No suitable format found');
7198 aStream.Position := StartPos;
7202 FreeAndNil(SpecialFormat);
7205 else aStream.Position := StartPos;
7208 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7209 procedure TglBitmap.SaveBMP(const aStream: TStream);
7213 Converter: TFormatDescriptor;
7214 FormatDesc: TFormatDescriptor;
7215 SourceFD, DestFD: Pointer;
7216 pData, srcData, dstData, ConvertBuffer: pByte;
7218 Pixel: TglBitmapPixelData;
7219 ImageSize, wbLineSize, rbLineSize, Padding, LineIdx, PixelIdx: Integer;
7220 RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
7222 PaddingBuff: Cardinal;
7224 function GetLineWidth : Integer;
7226 result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
7230 if not (ftBMP in FormatGetSupportedFiles(Format)) then
7231 raise EglBitmapUnsupportedFormat.Create(Format);
7234 FormatDesc := TFormatDescriptor.Get(Format);
7235 ImageSize := FormatDesc.GetSize(Dimension);
7237 FillChar(Header{%H-}, SizeOf(Header), 0);
7238 Header.bfType := BMP_MAGIC;
7239 Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
7240 Header.bfReserved1 := 0;
7241 Header.bfReserved2 := 0;
7242 Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
7244 FillChar(Info{%H-}, SizeOf(Info), 0);
7245 Info.biSize := SizeOf(Info);
7246 Info.biWidth := Width;
7247 Info.biHeight := Height;
7249 Info.biCompression := BMP_COMP_RGB;
7250 Info.biSizeImage := ImageSize;
7254 tfAlpha4ub1, tfAlpha8ub1, tfLuminance4ub1, tfLuminance8ub1, tfR3G3B2ub1:
7256 Info.biBitCount := 8;
7257 Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
7258 Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal); //256 ColorTable entries
7259 Converter := TbmpColorTableFormat.Create;
7260 with (Converter as TbmpColorTableFormat) do begin
7261 SetValues(fFormat, 1, FormatDesc.Precision, FormatDesc.Shift);
7266 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
7267 tfRGBX4us1, tfXRGB4us1, tfRGB5X1us1, tfX1RGB5us1, tfR5G6B5us1, tfRGB5A1us1, tfA1RGB5us1, tfRGBA4us1, tfARGB4us1,
7268 tfBGRX4us1, tfXBGR4us1, tfBGR5X1us1, tfX1BGR5us1, tfB5G6R5us1, tfBGR5A1us1, tfA1BGR5us1, tfBGRA4us1, tfABGR4us1:
7270 Info.biBitCount := 16;
7271 Info.biCompression := BMP_COMP_BITFIELDS;
7274 tfBGR8ub3, tfRGB8ub3:
7276 Info.biBitCount := 24;
7277 if (Format = tfRGB8ub3) then
7278 Converter := TfdBGR8ub3.Create; //use BGR8 Format Descriptor to Swap RGB Values
7281 tfRGBX8ui1, tfXRGB8ui1, tfRGB10X2ui1, tfX2RGB10ui1, tfRGBA8ui1, tfARGB8ui1, tfRGBA8ub4, tfRGB10A2ui1, tfA2RGB10ui1,
7282 tfBGRX8ui1, tfXBGR8ui1, tfBGR10X2ui1, tfX2BGR10ui1, tfBGRA8ui1, tfABGR8ui1, tfBGRA8ub4, tfBGR10A2ui1, tfA2BGR10ui1:
7284 Info.biBitCount := 32;
7285 Info.biCompression := BMP_COMP_BITFIELDS;
7288 raise EglBitmapUnsupportedFormat.Create(Format);
7290 Info.biXPelsPerMeter := 2835;
7291 Info.biYPelsPerMeter := 2835;
7294 if Info.biCompression = BMP_COMP_BITFIELDS then begin
7295 Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
7296 Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
7298 RedMask := FormatDesc.Mask.r;
7299 GreenMask := FormatDesc.Mask.g;
7300 BlueMask := FormatDesc.Mask.b;
7301 AlphaMask := FormatDesc.Mask.a;
7305 aStream.Write(Header, SizeOf(Header));
7306 aStream.Write(Info, SizeOf(Info));
7309 if Assigned(Converter) and (Converter is TbmpColorTableFormat) then
7310 with (Converter as TbmpColorTableFormat) do
7311 aStream.Write(ColorTable[0].b,
7312 SizeOf(TbmpColorTableEnty) * Length(ColorTable));
7315 if Info.biCompression = BMP_COMP_BITFIELDS then begin
7316 aStream.Write(RedMask, SizeOf(Cardinal));
7317 aStream.Write(GreenMask, SizeOf(Cardinal));
7318 aStream.Write(BlueMask, SizeOf(Cardinal));
7319 aStream.Write(AlphaMask, SizeOf(Cardinal));
7323 rbLineSize := Round(Info.biWidth * FormatDesc.BytesPerPixel);
7324 wbLineSize := Round(Info.biWidth * Info.biBitCount / 8);
7325 Padding := GetLineWidth - wbLineSize;
7329 inc(pData, (Height-1) * rbLineSize);
7331 // prepare row buffer. But only for RGB because RGBA supports color masks
7332 // so it's possible to change color within the image.
7333 if Assigned(Converter) then begin
7334 FormatDesc.PreparePixel(Pixel);
7335 GetMem(ConvertBuffer, wbLineSize);
7336 SourceFD := FormatDesc.CreateMappingData;
7337 DestFD := Converter.CreateMappingData;
7339 ConvertBuffer := nil;
7342 for LineIdx := 0 to Height - 1 do begin
7344 if Assigned(Converter) then begin
7346 dstData := ConvertBuffer;
7347 for PixelIdx := 0 to Info.biWidth-1 do begin
7348 FormatDesc.Unmap(srcData, Pixel, SourceFD);
7349 glBitmapConvertPixel(Pixel, FormatDesc, Converter);
7350 Converter.Map(Pixel, dstData, DestFD);
7352 aStream.Write(ConvertBuffer^, wbLineSize);
7354 aStream.Write(pData^, rbLineSize);
7356 dec(pData, rbLineSize);
7357 if (Padding > 0) then
7358 aStream.Write(PaddingBuff, Padding);
7361 // destroy row buffer
7362 if Assigned(ConvertBuffer) then begin
7363 FormatDesc.FreeMappingData(SourceFD);
7364 Converter.FreeMappingData(DestFD);
7365 FreeMem(ConvertBuffer);
7369 if Assigned(Converter) then
7374 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7375 //TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7376 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7378 TTGAHeader = packed record
7382 //ColorMapSpec: Array[0..4] of Byte;
7383 ColorMapStart: Word;
7384 ColorMapLength: Word;
7385 ColorMapEntrySize: Byte;
7395 TGA_UNCOMPRESSED_RGB = 2;
7396 TGA_UNCOMPRESSED_GRAY = 3;
7397 TGA_COMPRESSED_RGB = 10;
7398 TGA_COMPRESSED_GRAY = 11;
7400 TGA_NONE_COLOR_TABLE = 0;
7402 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7403 function TglBitmap.LoadTGA(const aStream: TStream): Boolean;
7406 ImageData: System.PByte;
7407 StartPosition: Int64;
7408 PixelSize, LineSize: Integer;
7409 tgaFormat: TglBitmapFormat;
7410 FormatDesc: TFormatDescriptor;
7411 Counter: packed record
7413 low, high, dir: Integer;
7420 ////////////////////////////////////////////////////////////////////////////////////////
7421 procedure ReadUncompressed;
7424 buf, tmp1, tmp2: System.PByte;
7427 if (Counter.X.dir < 0) then
7428 GetMem(buf, LineSize);
7430 while (Counter.Y.low <> Counter.Y.high + counter.Y.dir) do begin
7432 inc(tmp1, (Counter.Y.low * LineSize)); //pointer to LineStart
7433 if (Counter.X.dir < 0) then begin //flip X
7434 aStream.Read(buf^, LineSize);
7436 inc(tmp2, LineSize - PixelSize); //pointer to last pixel in line
7437 for i := 0 to Header.Width-1 do begin //for all pixels in line
7438 for j := 0 to PixelSize-1 do begin //for all bytes in pixel
7443 dec(tmp2, 2*PixelSize); //move 2 backwards, because j-loop moved 1 forward
7446 aStream.Read(tmp1^, LineSize);
7447 inc(Counter.Y.low, Counter.Y.dir); //move to next line index
7450 if Assigned(buf) then
7455 ////////////////////////////////////////////////////////////////////////////////////////
7456 procedure ReadCompressed;
7458 /////////////////////////////////////////////////////////////////
7460 TmpData: System.PByte;
7461 LinePixelsRead: Integer;
7462 procedure CheckLine;
7464 if (LinePixelsRead >= Header.Width) then begin
7465 LinePixelsRead := 0;
7466 inc(Counter.Y.low, Counter.Y.dir); //next line index
7467 TmpData := ImageData;
7468 inc(TmpData, Counter.Y.low * LineSize); //set line
7469 if (Counter.X.dir < 0) then //if x flipped then
7470 inc(TmpData, LineSize - PixelSize); //set last pixel
7474 /////////////////////////////////////////////////////////////////
7477 CacheSize, CachePos: Integer;
7478 procedure CachedRead(out Buffer; Count: Integer);
7482 if (CachePos + Count > CacheSize) then begin
7483 //if buffer overflow save non read bytes
7485 if (CacheSize - CachePos > 0) then begin
7486 BytesRead := CacheSize - CachePos;
7487 Move(PByteArray(Cache)^[CachePos], Buffer{%H-}, BytesRead);
7488 inc(CachePos, BytesRead);
7491 //load cache from file
7492 CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
7493 aStream.Read(Cache^, CacheSize);
7496 //read rest of requested bytes
7497 if (Count - BytesRead > 0) then begin
7498 Move(PByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
7499 inc(CachePos, Count - BytesRead);
7502 //if no buffer overflow just read the data
7503 Move(PByteArray(Cache)^[CachePos], Buffer, Count);
7504 inc(CachePos, Count);
7508 procedure PixelToBuffer(const aData: PByte; var aBuffer: PByte);
7513 inc(aBuffer, Counter.X.dir);
7516 PWord(aBuffer)^ := PWord(aData)^;
7517 inc(aBuffer, 2 * Counter.X.dir);
7520 PByteArray(aBuffer)^[0] := PByteArray(aData)^[0];
7521 PByteArray(aBuffer)^[1] := PByteArray(aData)^[1];
7522 PByteArray(aBuffer)^[2] := PByteArray(aData)^[2];
7523 inc(aBuffer, 3 * Counter.X.dir);
7526 PCardinal(aBuffer)^ := PCardinal(aData)^;
7527 inc(aBuffer, 4 * Counter.X.dir);
7533 TotalPixelsToRead, TotalPixelsRead: Integer;
7535 buf: array [0..3] of Byte; //1 pixel is max 32bit long
7536 PixelRepeat: Boolean;
7537 PixelsToRead, PixelCount: Integer;
7542 TotalPixelsToRead := Header.Width * Header.Height;
7543 TotalPixelsRead := 0;
7544 LinePixelsRead := 0;
7546 GetMem(Cache, CACHE_SIZE);
7548 TmpData := ImageData;
7549 inc(TmpData, Counter.Y.low * LineSize); //set line
7550 if (Counter.X.dir < 0) then //if x flipped then
7551 inc(TmpData, LineSize - PixelSize); //set last pixel
7555 CachedRead(Temp, 1);
7556 PixelRepeat := (Temp and $80) > 0;
7557 PixelsToRead := (Temp and $7F) + 1;
7558 inc(TotalPixelsRead, PixelsToRead);
7561 CachedRead(buf[0], PixelSize);
7562 while (PixelsToRead > 0) do begin
7564 PixelCount := Min(Header.Width - LinePixelsRead, PixelsToRead); //max read to EOL or EOF
7565 while (PixelCount > 0) do begin
7566 if not PixelRepeat then
7567 CachedRead(buf[0], PixelSize);
7568 PixelToBuffer(@buf[0], TmpData);
7569 inc(LinePixelsRead);
7574 until (TotalPixelsRead >= TotalPixelsToRead);
7580 function IsGrayFormat: Boolean;
7582 result := Header.ImageType in [TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_GRAY];
7588 // reading header to test file and set cursor back to begin
7589 StartPosition := aStream.Position;
7590 aStream.Read(Header{%H-}, SizeOf(Header));
7592 // no colormapped files
7593 if (Header.ColorMapType = TGA_NONE_COLOR_TABLE) and (Header.ImageType in [
7594 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY]) then
7597 if Header.ImageID <> 0 then // skip image ID
7598 aStream.Position := aStream.Position + Header.ImageID;
7600 tgaFormat := tfEmpty;
7602 8: if IsGrayFormat then case (Header.ImageDesc and $F) of
7603 0: tgaFormat := tfLuminance8ub1;
7604 8: tgaFormat := tfAlpha8ub1;
7607 16: if IsGrayFormat then case (Header.ImageDesc and $F) of
7608 0: tgaFormat := tfLuminance16us1;
7609 8: tgaFormat := tfLuminance8Alpha8ub2;
7610 end else case (Header.ImageDesc and $F) of
7611 0: tgaFormat := tfX1RGB5us1;
7612 1: tgaFormat := tfA1RGB5us1;
7613 4: tgaFormat := tfARGB4us1;
7616 24: if not IsGrayFormat then case (Header.ImageDesc and $F) of
7617 0: tgaFormat := tfBGR8ub3;
7620 32: if IsGrayFormat then case (Header.ImageDesc and $F) of
7621 0: tgaFormat := tfDepth32ui1;
7622 end else case (Header.ImageDesc and $F) of
7623 0: tgaFormat := tfX2RGB10ui1;
7624 2: tgaFormat := tfA2RGB10ui1;
7625 8: tgaFormat := tfARGB8ui1;
7629 if (tgaFormat = tfEmpty) then
7630 raise EglBitmap.Create('LoadTga - unsupported format');
7632 FormatDesc := TFormatDescriptor.Get(tgaFormat);
7633 PixelSize := FormatDesc.GetSize(1, 1);
7634 LineSize := FormatDesc.GetSize(Header.Width, 1);
7636 GetMem(ImageData, LineSize * Header.Height);
7639 if ((Header.ImageDesc and (1 shl 4)) > 0) then begin
7640 Counter.X.low := Header.Height-1;;
7641 Counter.X.high := 0;
7642 Counter.X.dir := -1;
7645 Counter.X.high := Header.Height-1;
7650 if ((Header.ImageDesc and (1 shl 5)) > 0) then begin
7652 Counter.Y.high := Header.Height-1;
7655 Counter.Y.low := Header.Height-1;;
7656 Counter.Y.high := 0;
7657 Counter.Y.dir := -1;
7661 case Header.ImageType of
7662 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY:
7664 TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY:
7668 SetDataPointer(ImageData, tgaFormat, Header.Width, Header.Height); //be careful, Data could be freed by this method
7671 if Assigned(ImageData) then
7676 aStream.Position := StartPosition;
7679 else aStream.Position := StartPosition;
7682 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7683 procedure TglBitmap.SaveTGA(const aStream: TStream);
7687 FormatDesc: TFormatDescriptor;
7689 if not (ftTGA in FormatGetSupportedFiles(Format)) then
7690 raise EglBitmapUnsupportedFormat.Create(Format);
7693 FormatDesc := TFormatDescriptor.Get(Format);
7694 FillChar(Header{%H-}, SizeOf(Header), 0);
7695 Header.ImageDesc := CountSetBits(FormatDesc.Range.a) and $F;
7696 Header.Bpp := FormatDesc.BitsPerPixel;
7697 Header.Width := Width;
7698 Header.Height := Height;
7699 Header.ImageDesc := Header.ImageDesc or $20; //flip y
7700 if FormatDesc.IsGrayscale or (not FormatDesc.IsGrayscale and not FormatDesc.HasRed and FormatDesc.HasAlpha) then
7701 Header.ImageType := TGA_UNCOMPRESSED_GRAY
7703 Header.ImageType := TGA_UNCOMPRESSED_RGB;
7704 aStream.Write(Header, SizeOf(Header));
7707 Size := FormatDesc.GetSize(Dimension);
7708 aStream.Write(Data^, Size);
7711 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7712 //DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7713 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7715 DDS_MAGIC: Cardinal = $20534444;
7717 // DDS_header.dwFlags
7718 DDSD_CAPS = $00000001;
7719 DDSD_HEIGHT = $00000002;
7720 DDSD_WIDTH = $00000004;
7721 DDSD_PIXELFORMAT = $00001000;
7723 // DDS_header.sPixelFormat.dwFlags
7724 DDPF_ALPHAPIXELS = $00000001;
7725 DDPF_ALPHA = $00000002;
7726 DDPF_FOURCC = $00000004;
7727 DDPF_RGB = $00000040;
7728 DDPF_LUMINANCE = $00020000;
7730 // DDS_header.sCaps.dwCaps1
7731 DDSCAPS_TEXTURE = $00001000;
7733 // DDS_header.sCaps.dwCaps2
7734 DDSCAPS2_CUBEMAP = $00000200;
7736 D3DFMT_DXT1 = $31545844;
7737 D3DFMT_DXT3 = $33545844;
7738 D3DFMT_DXT5 = $35545844;
7741 TDDSPixelFormat = packed record
7745 dwRGBBitCount: Cardinal;
7746 dwRBitMask: Cardinal;
7747 dwGBitMask: Cardinal;
7748 dwBBitMask: Cardinal;
7749 dwABitMask: Cardinal;
7752 TDDSCaps = packed record
7756 dwReserved: Cardinal;
7759 TDDSHeader = packed record
7764 dwPitchOrLinearSize: Cardinal;
7766 dwMipMapCount: Cardinal;
7767 dwReserved: array[0..10] of Cardinal;
7768 PixelFormat: TDDSPixelFormat;
7770 dwReserved2: Cardinal;
7773 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7774 function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
7777 Converter: TbmpBitfieldFormat;
7779 function GetDDSFormat: TglBitmapFormat;
7781 fd: TFormatDescriptor;
7783 Mask: TglBitmapRec4ul;
7784 Range: TglBitmapRec4ui;
7788 with Header.PixelFormat do begin
7790 if ((dwFlags and DDPF_FOURCC) > 0) then begin
7791 case Header.PixelFormat.dwFourCC of
7792 D3DFMT_DXT1: result := tfS3tcDtx1RGBA;
7793 D3DFMT_DXT3: result := tfS3tcDtx3RGBA;
7794 D3DFMT_DXT5: result := tfS3tcDtx5RGBA;
7796 end else if ((dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE or DDPF_ALPHA)) > 0) then begin
7798 if ((dwFlags and DDPF_LUMINANCE) = 0) then begin
7799 Mask.r := dwRBitMask;
7800 Mask.g := dwGBitMask;
7801 Mask.b := dwBBitMask;
7803 Mask.r := dwRBitMask;
7804 Mask.g := dwRBitMask;
7805 Mask.b := dwRBitMask;
7807 if (dwFlags and DDPF_ALPHAPIXELS > 0) then
7808 Mask.a := dwABitMask
7812 //find matching format
7813 fd := TFormatDescriptor.GetFromMask(Mask, dwRGBBitCount);
7814 result := fd.Format;
7815 if (result <> tfEmpty) then
7818 //find format with same Range
7820 Range.arr[i] := (2 shl CountSetBits(Mask.arr[i])) - 1;
7821 for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
7822 fd := TFormatDescriptor.Get(result);
7825 if (fd.Range.arr[i] <> Range.arr[i]) then begin
7833 //no format with same range found -> use default
7834 if (result = tfEmpty) then begin
7835 if (dwABitMask > 0) then
7836 result := tfRGBA8ui1
7838 result := tfRGB8ub3;
7841 Converter := TbmpBitfieldFormat.Create;
7842 Converter.SetValues(dwRGBBitCount, glBitmapRec4ul(dwRBitMask, dwGBitMask, dwBBitMask, dwABitMask));
7849 x, y, LineSize, RowSize, Magic: Cardinal;
7850 NewImage, TmpData, RowData, SrcData: System.PByte;
7851 SourceMD, DestMD: Pointer;
7852 Pixel: TglBitmapPixelData;
7853 ddsFormat: TglBitmapFormat;
7854 FormatDesc: TFormatDescriptor;
7859 StreamPos := aStream.Position;
7862 aStream.Read(Magic{%H-}, sizeof(Magic));
7863 if (Magic <> DDS_MAGIC) then begin
7864 aStream.Position := StreamPos;
7869 aStream.Read(Header{%H-}, sizeof(Header));
7870 if (Header.dwSize <> SizeOf(Header)) or
7871 ((Header.dwFlags and (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) <>
7872 (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) then
7874 aStream.Position := StreamPos;
7878 if ((Header.Caps.dwCaps1 and DDSCAPS2_CUBEMAP) > 0) then
7879 raise EglBitmap.Create('LoadDDS - CubeMaps are not supported');
7881 ddsFormat := GetDDSFormat;
7883 if (ddsFormat = tfEmpty) then
7884 raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
7886 FormatDesc := TFormatDescriptor.Get(ddsFormat);
7887 LineSize := Trunc(Header.dwWidth * FormatDesc.BytesPerPixel);
7888 GetMem(NewImage, Header.dwHeight * LineSize);
7890 TmpData := NewImage;
7893 if Assigned(Converter) then begin
7894 RowSize := Round(Header.dwWidth * Header.PixelFormat.dwRGBBitCount / 8);
7895 GetMem(RowData, RowSize);
7896 SourceMD := Converter.CreateMappingData;
7897 DestMD := FormatDesc.CreateMappingData;
7899 for y := 0 to Header.dwHeight-1 do begin
7900 TmpData := NewImage;
7901 inc(TmpData, y * LineSize);
7903 aStream.Read(SrcData^, RowSize);
7904 for x := 0 to Header.dwWidth-1 do begin
7905 Converter.Unmap(SrcData, Pixel, SourceMD);
7906 glBitmapConvertPixel(Pixel, Converter, FormatDesc);
7907 FormatDesc.Map(Pixel, TmpData, DestMD);
7911 Converter.FreeMappingData(SourceMD);
7912 FormatDesc.FreeMappingData(DestMD);
7918 if ((Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0) then begin
7919 RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
7920 for Y := 0 to Header.dwHeight-1 do begin
7921 aStream.Read(TmpData^, RowSize);
7922 Inc(TmpData, LineSize);
7927 if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0 then begin
7928 RowSize := (Header.PixelFormat.dwRGBBitCount * Header.dwWidth) shr 3;
7929 for Y := 0 to Header.dwHeight-1 do begin
7930 aStream.Read(TmpData^, RowSize);
7931 Inc(TmpData, LineSize);
7934 raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
7936 SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight); //be careful, Data could be freed by this method
7939 if Assigned(NewImage) then
7944 FreeAndNil(Converter);
7948 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7949 procedure TglBitmap.SaveDDS(const aStream: TStream);
7952 FormatDesc: TFormatDescriptor;
7954 if not (ftDDS in FormatGetSupportedFiles(Format)) then
7955 raise EglBitmapUnsupportedFormat.Create(Format);
7957 FormatDesc := TFormatDescriptor.Get(Format);
7960 FillChar(Header{%H-}, SizeOf(Header), 0);
7961 Header.dwSize := SizeOf(Header);
7962 Header.dwFlags := DDSD_WIDTH or DDSD_HEIGHT or DDSD_CAPS or DDSD_PIXELFORMAT;
7964 Header.dwWidth := Max(1, Width);
7965 Header.dwHeight := Max(1, Height);
7968 Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
7971 Header.PixelFormat.dwSize := sizeof(Header);
7972 if (FormatDesc.IsCompressed) then begin
7973 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_FOURCC;
7975 tfS3tcDtx1RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT1;
7976 tfS3tcDtx3RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT3;
7977 tfS3tcDtx5RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT5;
7979 end else if not FormatDesc.HasColor and FormatDesc.HasAlpha then begin
7980 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHA;
7981 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
7982 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
7983 end else if FormatDesc.IsGrayscale then begin
7984 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_LUMINANCE;
7985 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
7986 Header.PixelFormat.dwRBitMask := FormatDesc.Mask.r;
7987 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
7989 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_RGB;
7990 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
7991 Header.PixelFormat.dwRBitMask := FormatDesc.Mask.r;
7992 Header.PixelFormat.dwGBitMask := FormatDesc.Mask.g;
7993 Header.PixelFormat.dwBBitMask := FormatDesc.Mask.b;
7994 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
7997 if (FormatDesc.HasAlpha) then
7998 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
8000 aStream.Write(DDS_MAGIC, sizeof(DDS_MAGIC));
8001 aStream.Write(Header, SizeOf(Header));
8002 aStream.Write(Data^, FormatDesc.GetSize(Dimension));
8005 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8006 //TglBitmap1D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8007 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8008 procedure TglBitmap1D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
8009 const aWidth: Integer; const aHeight: Integer);
8014 if (aHeight > 1) then begin
8015 Size := TFormatDescriptor.Get(aFormat).GetSize(aWidth, 1);
8016 GetMem(pTemp, Size);
8018 Move(aData^, pTemp^, Size);
8027 inherited SetDataPointer(pTemp, aFormat, aWidth);
8030 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8031 function TglBitmap1D.FlipHorz: Boolean;
8034 pTempDest, pDest, pSource: PByte;
8036 result := inherited FlipHorz;
8037 if Assigned(Data) and not TFormatDescriptor.Get(Format).IsCompressed then begin
8039 GetMem(pDest, fRowSize);
8042 Inc(pTempDest, fRowSize);
8043 for Col := 0 to Width-1 do begin
8044 dec(pTempDest, fPixelSize); //dec before, because ptr is behind last byte of data
8045 Move(pSource^, pTempDest^, fPixelSize);
8046 Inc(pSource, fPixelSize);
8048 SetDataPointer(pDest, Format, Width); //be careful, Data could be freed by this method
8051 if Assigned(pDest) then
8058 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8059 procedure TglBitmap1D.UploadData(const aBuildWithGlu: Boolean);
8061 FormatDesc: TFormatDescriptor;
8064 FormatDesc := TFormatDescriptor.Get(Format);
8065 if FormatDesc.IsCompressed then begin
8066 if not Assigned(glCompressedTexImage1D) then
8067 raise EglBitmap.Create('compressed formats not supported by video adapter');
8068 glCompressedTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.GetSize(Width, 1), Data)
8069 end else if aBuildWithGlu then
8070 gluBuild1DMipmaps(Target, FormatDesc.glInternalFormat, Width, FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
8072 glTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
8075 if (FreeDataAfterGenTexture) then
8079 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8080 procedure TglBitmap1D.GenTexture(const aTestTextureSize: Boolean);
8082 BuildWithGlu, TexRec: Boolean;
8085 if Assigned(Data) then begin
8086 // Check Texture Size
8087 if (aTestTextureSize) then begin
8088 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
8090 if (Width > TexSize) then
8091 raise EglBitmapSizeToLarge.Create('TglBitmap1D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
8093 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
8094 (Target = GL_TEXTURE_RECTANGLE);
8095 if not (IsPowerOfTwo(Width) or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
8096 raise EglBitmapNonPowerOfTwo.Create('TglBitmap1D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8100 SetupParameters(BuildWithGlu);
8101 UploadData(BuildWithGlu);
8102 glAreTexturesResident(1, @fID, @fIsResident);
8106 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8107 procedure TglBitmap1D.AfterConstruction;
8110 Target := GL_TEXTURE_1D;
8113 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8114 //TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8115 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8116 function TglBitmap2D.GetScanline(const aIndex: Integer): Pointer;
8118 if (aIndex >= Low(fLines)) and (aIndex <= High(fLines)) then
8119 result := fLines[aIndex]
8124 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8125 procedure TglBitmap2D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
8126 const aWidth: Integer; const aHeight: Integer);
8128 Idx, LineWidth: Integer;
8130 inherited SetDataPointer(aData, aFormat, aWidth, aHeight);
8132 if not TFormatDescriptor.Get(aFormat).IsCompressed then begin
8134 if Assigned(Data) then begin
8135 SetLength(fLines, GetHeight);
8136 LineWidth := Trunc(GetWidth * TFormatDescriptor.Get(Format).BytesPerPixel);
8138 for Idx := 0 to GetHeight-1 do begin
8139 fLines[Idx] := Data;
8140 Inc(fLines[Idx], Idx * LineWidth);
8143 else SetLength(fLines, 0);
8145 SetLength(fLines, 0);
8149 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8150 procedure TglBitmap2D.UploadData(const aTarget: GLenum; const aBuildWithGlu: Boolean);
8152 FormatDesc: TFormatDescriptor;
8154 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
8156 FormatDesc := TFormatDescriptor.Get(Format);
8157 if FormatDesc.IsCompressed then begin
8158 if not Assigned(glCompressedTexImage2D) then
8159 raise EglBitmap.Create('compressed formats not supported by video adapter');
8160 glCompressedTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0, FormatDesc.GetSize(fDimension), Data)
8161 end else if aBuildWithGlu then begin
8162 gluBuild2DMipmaps(aTarget, FormatDesc.ChannelCount, Width, Height,
8163 FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
8165 glTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0,
8166 FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
8170 if (FreeDataAfterGenTexture) then
8174 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8175 procedure TglBitmap2D.AfterConstruction;
8178 Target := GL_TEXTURE_2D;
8181 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8182 procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
8185 Size, w, h: Integer;
8186 FormatDesc: TFormatDescriptor;
8188 FormatDesc := TFormatDescriptor.Get(aFormat);
8189 if FormatDesc.IsCompressed then
8190 raise EglBitmapUnsupportedFormat.Create(aFormat);
8192 w := aRight - aLeft;
8193 h := aBottom - aTop;
8194 Size := FormatDesc.GetSize(w, h);
8197 glPixelStorei(GL_PACK_ALIGNMENT, 1);
8198 glReadPixels(aLeft, aTop, w, h, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
8199 SetDataPointer(Temp, aFormat, w, h); //be careful, Data could be freed by this method
8202 if Assigned(Temp) then
8208 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8209 procedure TglBitmap2D.GetDataFromTexture;
8212 TempWidth, TempHeight: Integer;
8213 TempIntFormat: GLint;
8214 IntFormat: TglBitmapFormat;
8215 FormatDesc: TFormatDescriptor;
8220 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
8221 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
8222 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
8224 IntFormat := tfEmpty;
8225 FormatDesc := (TglBitmapFormatDescriptor.GetByFormat(TempIntFormat) as TFormatDescriptor);
8226 IntFormat := FormatDesc.Format;
8228 // Getting data from OpenGL
8229 FormatDesc := TFormatDescriptor.Get(IntFormat);
8230 GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
8232 if FormatDesc.IsCompressed then begin
8233 if not Assigned(glGetCompressedTexImage) then
8234 raise EglBitmap.Create('compressed formats not supported by video adapter');
8235 glGetCompressedTexImage(Target, 0, Temp)
8237 glGetTexImage(Target, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
8238 SetDataPointer(Temp, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
8240 if Assigned(Temp) then
8246 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8247 procedure TglBitmap2D.GenTexture(const aTestTextureSize: Boolean);
8249 BuildWithGlu, PotTex, TexRec: Boolean;
8252 if Assigned(Data) then begin
8253 // Check Texture Size
8254 if (aTestTextureSize) then begin
8255 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
8257 if ((Height > TexSize) or (Width > TexSize)) then
8258 raise EglBitmapSizeToLarge.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
8260 PotTex := IsPowerOfTwo(Height) and IsPowerOfTwo(Width);
8261 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE);
8262 if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
8263 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8267 SetupParameters(BuildWithGlu);
8268 UploadData(Target, BuildWithGlu);
8269 glAreTexturesResident(1, @fID, @fIsResident);
8273 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8274 function TglBitmap2D.FlipHorz: Boolean;
8277 TempDestData, DestData, SourceData: PByte;
8280 result := inherited FlipHorz;
8281 if Assigned(Data) then begin
8283 ImgSize := Height * fRowSize;
8284 GetMem(DestData, ImgSize);
8286 TempDestData := DestData;
8287 Dec(TempDestData, fRowSize + fPixelSize);
8288 for Row := 0 to Height -1 do begin
8289 Inc(TempDestData, fRowSize * 2);
8290 for Col := 0 to Width -1 do begin
8291 Move(SourceData^, TempDestData^, fPixelSize);
8292 Inc(SourceData, fPixelSize);
8293 Dec(TempDestData, fPixelSize);
8296 SetDataPointer(DestData, Format, Width, Height); //be careful, Data could be freed by this method
8299 if Assigned(DestData) then
8306 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8307 function TglBitmap2D.FlipVert: Boolean;
8310 TempDestData, DestData, SourceData: PByte;
8312 result := inherited FlipVert;
8313 if Assigned(Data) then begin
8315 GetMem(DestData, Height * fRowSize);
8317 TempDestData := DestData;
8318 Inc(TempDestData, Width * (Height -1) * fPixelSize);
8319 for Row := 0 to Height -1 do begin
8320 Move(SourceData^, TempDestData^, fRowSize);
8321 Dec(TempDestData, fRowSize);
8322 Inc(SourceData, fRowSize);
8324 SetDataPointer(DestData, Format, Width, Height); //be careful, Data could be freed by this method
8327 if Assigned(DestData) then
8334 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8335 //TglBitmap2D - ToNormalMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8336 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8338 TMatrixItem = record
8343 PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
8344 TglBitmapToNormalMapRec = Record
8346 Heights: array of Single;
8347 MatrixU : array of TMatrixItem;
8348 MatrixV : array of TMatrixItem;
8352 ONE_OVER_255 = 1 / 255;
8354 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8355 procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
8359 with FuncRec do begin
8361 Source.Data.r * LUMINANCE_WEIGHT_R +
8362 Source.Data.g * LUMINANCE_WEIGHT_G +
8363 Source.Data.b * LUMINANCE_WEIGHT_B;
8364 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255;
8368 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8369 procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
8372 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
8375 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8376 procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
8378 TVec = Array[0..2] of Single;
8385 function GetHeight(X, Y: Integer): Single;
8387 with FuncRec do begin
8388 X := Max(0, Min(Size.X -1, X));
8389 Y := Max(0, Min(Size.Y -1, Y));
8390 result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
8395 with FuncRec do begin
8396 with PglBitmapToNormalMapRec(Args)^ do begin
8398 for Idx := Low(MatrixU) to High(MatrixU) do
8399 du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
8402 for Idx := Low(MatrixU) to High(MatrixU) do
8403 dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
8405 Vec[0] := -du * Scale;
8406 Vec[1] := -dv * Scale;
8411 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
8412 if Len <> 0 then begin
8413 Vec[0] := Vec[0] * Len;
8414 Vec[1] := Vec[1] * Len;
8415 Vec[2] := Vec[2] * Len;
8419 Dest.Data.r := Trunc((Vec[0] + 1) * 127.5);
8420 Dest.Data.g := Trunc((Vec[1] + 1) * 127.5);
8421 Dest.Data.b := Trunc((Vec[2] + 1) * 127.5);
8425 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8426 procedure TglBitmap2D.ToNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
8428 Rec: TglBitmapToNormalMapRec;
8430 procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
8432 if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
8433 Matrix[Index].X := X;
8434 Matrix[Index].Y := Y;
8435 Matrix[Index].W := W;
8440 if TFormatDescriptor.Get(Format).IsCompressed then
8441 raise EglBitmapUnsupportedFormat.Create(Format);
8443 if aScale > 100 then
8445 else if aScale < -100 then
8448 Rec.Scale := aScale;
8450 SetLength(Rec.Heights, Width * Height);
8454 SetLength(Rec.MatrixU, 2);
8455 SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
8456 SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
8458 SetLength(Rec.MatrixV, 2);
8459 SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
8460 SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
8464 SetLength(Rec.MatrixU, 6);
8465 SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
8466 SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
8467 SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
8468 SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
8469 SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
8470 SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
8472 SetLength(Rec.MatrixV, 6);
8473 SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
8474 SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
8475 SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
8476 SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
8477 SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
8478 SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
8482 SetLength(Rec.MatrixU, 6);
8483 SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
8484 SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
8485 SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
8486 SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
8487 SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
8488 SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
8490 SetLength(Rec.MatrixV, 6);
8491 SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
8492 SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
8493 SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
8494 SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
8495 SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
8496 SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
8500 SetLength(Rec.MatrixU, 20);
8501 SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
8502 SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
8503 SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
8504 SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
8505 SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
8506 SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
8507 SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
8508 SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
8509 SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
8510 SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
8511 SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
8512 SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
8513 SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
8514 SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
8515 SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
8516 SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
8517 SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
8518 SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
8519 SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
8520 SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
8522 SetLength(Rec.MatrixV, 20);
8523 SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
8524 SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
8525 SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
8526 SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
8527 SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
8528 SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
8529 SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
8530 SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
8531 SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
8532 SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
8533 SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
8534 SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
8535 SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
8536 SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
8537 SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
8538 SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
8539 SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
8540 SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
8541 SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
8542 SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
8547 if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
8548 AddFunc(glBitmapToNormalMapPrepareAlphaFunc, false, @Rec)
8550 AddFunc(glBitmapToNormalMapPrepareFunc, false, @Rec);
8551 AddFunc(glBitmapToNormalMapFunc, false, @Rec);
8553 SetLength(Rec.Heights, 0);
8557 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8558 //TglBitmapCubeMap////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8559 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8560 procedure TglBitmapCubeMap.GenTexture(const aTestTextureSize: Boolean);
8562 Assert(false, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
8565 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8566 procedure TglBitmapCubeMap.AfterConstruction;
8570 if not (GL_VERSION_1_3 or GL_ARB_texture_cube_map or GL_EXT_texture_cube_map) then
8571 raise EglBitmap.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
8574 Target := GL_TEXTURE_CUBE_MAP;
8575 fGenMode := GL_REFLECTION_MAP;
8578 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8579 procedure TglBitmapCubeMap.GenerateCubeMap(const aCubeTarget: Cardinal; const aTestTextureSize: Boolean);
8581 BuildWithGlu: Boolean;
8584 if (aTestTextureSize) then begin
8585 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @TexSize);
8587 if (Height > TexSize) or (Width > TexSize) then
8588 raise EglBitmapSizeToLarge.Create('TglBitmapCubeMap.GenTexture - The size for the Cubemap is to large. It''s may be not conform with the Hardware.');
8590 if not ((IsPowerOfTwo(Height) and IsPowerOfTwo(Width)) or GL_VERSION_2_0 or GL_ARB_texture_non_power_of_two) then
8591 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenTexture - Cubemaps dosn''t support non power of two texture.');
8596 SetupParameters(BuildWithGlu);
8597 UploadData(aCubeTarget, BuildWithGlu);
8600 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8601 procedure TglBitmapCubeMap.Bind(const aEnableTexCoordsGen: Boolean; const aEnableTextureUnit: Boolean);
8603 inherited Bind (aEnableTextureUnit);
8604 if aEnableTexCoordsGen then begin
8605 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, fGenMode);
8606 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, fGenMode);
8607 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, fGenMode);
8608 glEnable(GL_TEXTURE_GEN_S);
8609 glEnable(GL_TEXTURE_GEN_T);
8610 glEnable(GL_TEXTURE_GEN_R);
8614 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8615 procedure TglBitmapCubeMap.Unbind(const aDisableTexCoordsGen: Boolean; const aDisableTextureUnit: Boolean);
8617 inherited Unbind(aDisableTextureUnit);
8618 if aDisableTexCoordsGen then begin
8619 glDisable(GL_TEXTURE_GEN_S);
8620 glDisable(GL_TEXTURE_GEN_T);
8621 glDisable(GL_TEXTURE_GEN_R);
8625 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8626 //TglBitmapNormalMap//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8627 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8629 TVec = Array[0..2] of Single;
8630 TglBitmapNormalMapGetVectorFunc = procedure (out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8632 PglBitmapNormalMapRec = ^TglBitmapNormalMapRec;
8633 TglBitmapNormalMapRec = record
8635 Func: TglBitmapNormalMapGetVectorFunc;
8638 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8639 procedure glBitmapNormalMapPosX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8641 aVec[0] := aHalfSize;
8642 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8643 aVec[2] := - (aPosition.X + 0.5 - aHalfSize);
8646 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8647 procedure glBitmapNormalMapNegX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8649 aVec[0] := - aHalfSize;
8650 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8651 aVec[2] := aPosition.X + 0.5 - aHalfSize;
8654 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8655 procedure glBitmapNormalMapPosY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8657 aVec[0] := aPosition.X + 0.5 - aHalfSize;
8658 aVec[1] := aHalfSize;
8659 aVec[2] := aPosition.Y + 0.5 - aHalfSize;
8662 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8663 procedure glBitmapNormalMapNegY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8665 aVec[0] := aPosition.X + 0.5 - aHalfSize;
8666 aVec[1] := - aHalfSize;
8667 aVec[2] := - (aPosition.Y + 0.5 - aHalfSize);
8670 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8671 procedure glBitmapNormalMapPosZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8673 aVec[0] := aPosition.X + 0.5 - aHalfSize;
8674 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8675 aVec[2] := aHalfSize;
8678 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8679 procedure glBitmapNormalMapNegZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8681 aVec[0] := - (aPosition.X + 0.5 - aHalfSize);
8682 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8683 aVec[2] := - aHalfSize;
8686 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8687 procedure glBitmapNormalMapFunc(var FuncRec: TglBitmapFunctionRec);
8693 with FuncRec do begin
8694 with PglBitmapNormalMapRec(Args)^ do begin
8695 Func(Vec, Position, HalfSize);
8698 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
8699 if Len <> 0 then begin
8700 Vec[0] := Vec[0] * Len;
8701 Vec[1] := Vec[1] * Len;
8702 Vec[2] := Vec[2] * Len;
8705 // Scale Vector and AddVectro
8706 Vec[0] := Vec[0] * 0.5 + 0.5;
8707 Vec[1] := Vec[1] * 0.5 + 0.5;
8708 Vec[2] := Vec[2] * 0.5 + 0.5;
8713 Dest.Data.arr[i] := Round(Vec[i] * 255);
8717 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8718 procedure TglBitmapNormalMap.AfterConstruction;
8721 fGenMode := GL_NORMAL_MAP;
8724 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8725 procedure TglBitmapNormalMap.GenerateNormalMap(const aSize: Integer; const aTestTextureSize: Boolean);
8727 Rec: TglBitmapNormalMapRec;
8728 SizeRec: TglBitmapPixelPosition;
8730 Rec.HalfSize := aSize div 2;
8731 FreeDataAfterGenTexture := false;
8733 SizeRec.Fields := [ffX, ffY];
8738 Rec.Func := glBitmapNormalMapPosX;
8739 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
8740 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X, aTestTextureSize);
8743 Rec.Func := glBitmapNormalMapNegX;
8744 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
8745 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, aTestTextureSize);
8748 Rec.Func := glBitmapNormalMapPosY;
8749 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
8750 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, aTestTextureSize);
8753 Rec.Func := glBitmapNormalMapNegY;
8754 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
8755 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, aTestTextureSize);
8758 Rec.Func := glBitmapNormalMapPosZ;
8759 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
8760 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, aTestTextureSize);
8763 Rec.Func := glBitmapNormalMapNegZ;
8764 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
8765 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, aTestTextureSize);
8770 glBitmapSetDefaultFormat (tfEmpty);
8771 glBitmapSetDefaultMipmap (mmMipmap);
8772 glBitmapSetDefaultFilter (GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
8773 glBitmapSetDefaultWrap (GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
8774 glBitmapSetDefaultSwizzle(GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA);
8776 glBitmapSetDefaultFreeDataAfterGenTexture(true);
8777 glBitmapSetDefaultDeleteTextureOnFree (true);
8779 TFormatDescriptor.Init;
8781 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
8782 OpenGLInitialized := false;
8783 InitOpenGLCS := TCriticalSection.Create;
8787 TFormatDescriptor.Finalize;
8789 {$IFDEF GLB_NATIVE_OGL}
8790 if Assigned(GL_LibHandle) then
8791 glbFreeLibrary(GL_LibHandle);
8793 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
8794 if Assigned(GLU_LibHandle) then
8795 glbFreeLibrary(GLU_LibHandle);
8796 FreeAndNil(InitOpenGLCS);