1 {***********************************************************
2 glBitmap by Steffen Xonna aka Lossy eX (2003-2008)
3 http://www.opengl24.de/index.php?cat=header&file=glbitmap
4 ------------------------------------------------------------
5 The contents of this file are used with permission, subject to
6 the Mozilla Public License Version 1.1 (the "License"); you may
7 not use this file except in compliance with the License. You may
8 obtain a copy of the License at
9 http://www.mozilla.org/MPL/MPL-1.1.html
10 ------------------------------------------------------------
12 ------------------------------------------------------------
15 - The define GLB_DELPHI dosn't check versions anymore. If you say you are using delphi
16 then it's your problem if that isn't true. This prevents the unit for incompatibility
17 with newer versions of Delphi.
18 - Problems with D2009+ resolved (Thanks noeska and all i forgot)
19 - GetPixel isn't set if you are loading textures inside the constructor (Thanks Wilson)
21 - AddAlphaFromglBitmap used the custom pointer instead the imagedatapointer (Thanks Wilson)
22 - Additional Datapointer for functioninterface now has the name CustomData
24 - AssigneAlphaToBitmap overwrites his own palette (Thanks Wilson)
25 - If you load an texture from an file the property Filename will be set to the name of the file
26 - Three new properties to attach custom data to the Texture objects
27 - CustomName (free for use string)
28 - CustomNameW (free for use widestring)
29 - CustomDataPointer (free for use pointer to attach other objects or complex structures)
31 - RLE TGAs loaded much faster
33 - fixed some problem with reading RLE TGAs.
35 - function clone now only copys data if it's assigned and now it also copies the ID
36 - it seems that lazarus dont like comments in comments.
38 - It's possible to set the id of the texture
39 - define GLB_NO_NATIVE_GL deactivated by default
41 - Now supports the following libraries
45 - Linux compatibillity via free pascal compatibility (delphi sources optional)
46 - BMPs now loaded manuel
48 - Property DataPtr now has the name Data
49 - Functions are more flexible between RGB(A) and BGR(A). RGB can be saved as Bitmap and will be saved as BGR
50 - Unused Depth removed
51 - Function FreeData to freeing image data added
53 - ImageID flag of TGAs was ignored. (Thanks Zwoetzen)
55 - Function SetBorderColor implemented (only used by opengl if wrap is set to GL_CLAMP_TO_BORDER)
56 - Function AddAlphaFromValue implemented to use an fixed Value as Alphachannel
57 - Function ReadOpenGLExtension is now only intern
59 - pngimage now disabled by default like all other versions.
61 - Setting up an anisotropic filter of 0 isnt allowed by nvidia (Thanks Ogridi)
63 - Fixed some Problem with Delphi 5
64 - Now uses the newest version of pngimage. Makes saving pngs much easier.
66 - Property IsCompressed and Size removed. Not really supported by Spec (Thanks Ogridi)
68 - Internal Format ifDepth8 added
69 - function GrabScreen now supports all uncompressed formats
71 - AddAlphaFromglBitmap implemented
73 - LoadFromResource and LoadFromResourceId now needs an Instance and an ResourceType (for ID)
75 - Width, Height and Depth internal changed to TglBitmapPixelPosition.
76 property Width, Height, Depth are still existing and new property Dimension are avail
78 - Added native OpenGL Support. Breaking the dglOpenGL "barrier".
80 - Added function GrabScreen to class TglBitmap2D
82 - Added support to Save images
83 - Added function Clone to Clone Instance
85 - Functions now works with Cardinals for each channel. Up to 32 Bits per channel.
87 - Several speed optimizations
89 - Internal structure change. Loading of TGA, PNG and DDS improved.
90 Data, format and size will now set directly with SetDataPtr.
91 - AddFunc now works with all Types of Images and Formats
92 - Some Funtions moved to Baseclass TglBitmap
94 - Added Support to decompress DXT3 and DXT5 compressed Images.
95 - Added Mapping to convert data from one format into an other.
97 - Added method ConvertTo in Class TglBitmap2D. Method allows to convert every
98 supported Input format (supported by GetPixel) into any uncompresed Format
99 - Added Support to decompress DXT1 compressed Images.
100 - SwapColors replaced by ConvertTo
102 - Added Support for compressed DDSs
103 - Added new internal formats (DXT1, DXT3, DXT5)
105 - Parameter Components renamed to InternalFormat
107 - Some AllocMem replaced with GetMem (little speed change)
108 - better exception handling. Better protection from memory leaks.
110 - Added support for Direct Draw Surfaces (.DDS) (uncompressed images only)
111 - Added new internal formats (RGB8, RGBA8, RGBA4, RGB5A1, RGB10A2, R5G6B5)
113 - Added support for Grayscale textures
114 - Added internal formats (Alpha, Luminance, LuminanceAlpha, BGR8, BGRA8)
116 - Added support for GL_VERSION_2_0
117 - Added support for GL_EXT_texture_filter_anisotropic
119 - Function FillWithColor fills the Image with one Color
120 - Function LoadNormalMap added
122 - ToNormalMap allows to Create an NormalMap from the Alphachannel
123 - ToNormalMap now supports Sobel (nmSobel) function.
125 - support for RLE Compressed RGB TGAs added
127 - Class TglBitmapNormalMap added to support Normalmap generation
128 - Added function ToNormalMap in class TglBitmap2D to genereate normal maps from textures.
129 3 Filters are supported. (4 Samples, 3x3 and 5x5)
131 - Method LoadCubeMapClass removed
132 - LoadCubeMap returnvalue is now the Texture paramter. Such as LoadTextures
133 - virtual abstract method GenTexture in class TglBitmap now is protected
135 - now support DescriptionFlag in LoadTga. Allows vertical flipped images to be loaded as normal
137 - little enhancement for IsPowerOfTwo
138 - TglBitmap1D.GenTexture now tests NPOT Textures
140 - some little name changes. All properties or function with Texture in name are
141 now without texture in name. We have allways texture so we dosn't name it.
143 - GenTexture now tests if texture is NPOT and NPOT-Texture are supported or
144 TextureTarget is GL_TEXTURE_RECTANGLE. Else it raised an exception.
146 - added support for GL_ARB_texture_rectangle, GL_EXT_texture_rectangle and GL_NV_texture_rectangle
148 - Function Unbind added
149 - call of SetFilter or SetTextureWrap if TextureID exists results in setting properties to opengl texture.
151 - class TglBitmapCubeMap added (allows to Create Cubemaps)
153 - Added Support for PNG Images. (http://pngdelphi.sourceforge.net/)
154 To Enable png's use the define pngimage
156 - New Functioninterface added
157 - Function GetPixel added
159 - Property BuildMipMaps renamed to MipMap
161 - property Name removed.
162 - BuildMipMaps is now a set of 3 values. None, GluBuildMipmaps and SGIS_generate_mipmap
164 - property name added. Only used in glForms!
166 - property FreeDataAfterGenTexture is now available as default (default = true)
167 - BuildMipmaps now implemented in TglBitmap1D (i've forgotten it)
168 - function MoveMemory replaced with function Move (little speed change)
169 - several calculations stored in variables (little speed change)
171 - property BuildMipsMaps added (default = true)
172 if BuildMipMaps isn't set GenTextures uses glTexImage[12]D else it use gluBuild[12]dMipmaps
173 - property FreeDataAfterGenTexture added (default = true)
174 if FreeDataAfterGenTexture is set the texturedata were deleted after the texture was generated.
175 - parameter DisableOtherTextureUnits of Bind removed
176 - parameter FreeDataAfterGeneration of GenTextures removed
178 - TglBitmap dosn't delete data if class was destroyed (fixed)
180 - Bind now enables TextureUnits (by params)
181 - GenTextures can leave data (by param)
182 - LoadTextures now optimal
184 - Performance optimization in AddFunc
185 - procedure Bind moved to subclasses
186 - Added new Class TglBitmap1D to support real OpenGL 1D Textures
188 - Texturefilter and texturewrap now also as defaults
189 Minfilter = GL_LINEAR_MIPMAP_LINEAR
190 Magfilter = GL_LINEAR
191 Wrap(str) = GL_CLAMP_TO_EDGE
192 - Added new format tfCompressed to create a compressed texture.
193 - propertys IsCompressed, TextureSize and IsResident added
194 IsCompressed and TextureSize only contains data from level 0
196 - Added function AddFunc to add PerPixelEffects to Image
197 - LoadFromFunc now based on AddFunc
198 - Invert now based on AddFunc
199 - SwapColors now based on AddFunc
201 - Added function FlipHorz
203 - Added function LaodFromFunc to create images with function
204 - Added function FlipVert
205 - Added internal format RGB(A) if GL_EXT_bgra or OpenGL 1.2 isn't supported
207 - Added Alphafunctions to calculate alpha per function
208 - Added Alpha from ColorKey using alphafunctions
210 - First full functionally Version of glBitmap
211 - Support for 24Bit and 32Bit TGA Pictures added
213 - begin of programming
214 ***********************************************************}
217 {.$MESSAGE warn 'Hey. I''m the glBitmap.pas and i need to be configured. My master tell me your preferences! ;)'}
218 // Please uncomment the defines below to configure the glBitmap to your preferences.
219 // If you have configured the unit you can uncomment the warning above.
221 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
222 // Preferences ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
223 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
224 // activate to enable build-in OpenGL support with statically linked methods
225 // use dglOpenGL.pas if not enabled
226 {$DEFINE GLB_NATIVE_OGL_STATIC}
228 // activate to enable build-in OpenGL support with dynamically linked methods
229 // use dglOpenGL.pas if not enabled
230 {$DEFINE GLB_NATIVE_OGL_DYNAMIC}
232 // activate to enable the support for SDL_surfaces
235 // activate to enable the support for TBitmap from Delphi (not lazarus)
236 {.$DEFINE GLB_DELPHI}
239 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
240 // activate to enable the support of SDL_image to load files. (READ ONLY)
241 // If you enable SDL_image all other libraries will be ignored!
242 {.$DEFINE GLB_SDL_IMAGE}
244 // activate to enable png support with the unit pngimage. You can download it from http://pngdelphi.sourceforge.net/
245 // if you enable pngimage the libPNG will be ignored
246 {.$DEFINE GLB_PNGIMAGE}
248 // activate to use the libPNG http://www.libpng.org/
249 // You will need an aditional header.
250 // http://www.opengl24.de/index.php?cat=header&file=libpng
251 {.$DEFINE GLB_LIB_PNG}
253 // if you enable delphi jpegs the libJPEG will be ignored
254 {.$DEFINE GLB_DELPHI_JPEG}
256 // activateto use the libJPEG http://www.ijg.org/
257 // You will need an aditional header.
258 // http://www.opengl24.de/index.php?cat=header&file=libjpeg
259 {.$DEFINE GLB_LIB_JPEG}
262 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
263 // PRIVATE: DO not change anything! //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
264 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
280 {$IF DEFINED(WIN32) or DEFINED(WIN64)}
282 {$ELSEIF DEFINED(LINUX)}
286 // native OpenGL Support
287 {$IF DEFINED(GLB_NATIVE_OGL_STATIC) OR DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
288 {$DEFINE GLB_NATIVE_OGL}
291 // checking define combinations
293 {$IFDEF GLB_SDL_IMAGE}
295 {$MESSAGE warn 'SDL_image won''t work without SDL. SDL will be activated.'}
298 {$IFDEF GLB_PNGIMAGE}
299 {$MESSAGE warn 'The unit pngimage will be ignored because you are using SDL_image.'}
300 {$undef GLB_PNGIMAGE}
302 {$IFDEF GLB_DELPHI_JPEG}
303 {$MESSAGE warn 'The unit JPEG will be ignored because you are using SDL_image.'}
304 {$undef GLB_DELPHI_JPEG}
307 {$MESSAGE warn 'The library libPNG will be ignored because you are using SDL_image.'}
310 {$IFDEF GLB_LIB_JPEG}
311 {$MESSAGE warn 'The library libJPEG will be ignored because you are using SDL_image.'}
312 {$undef GLB_LIB_JPEG}
315 {$DEFINE GLB_SUPPORT_PNG_READ}
316 {$DEFINE GLB_SUPPORT_JPEG_READ}
320 {$IFDEF GLB_PNGIMAGE}
322 {$MESSAGE warn 'The library libPNG will be ignored if you are using pngimage.'}
326 {$DEFINE GLB_SUPPORT_PNG_READ}
327 {$DEFINE GLB_SUPPORT_PNG_WRITE}
332 {$DEFINE GLB_SUPPORT_PNG_READ}
333 {$DEFINE GLB_SUPPORT_PNG_WRITE}
337 {$IFDEF GLB_DELPHI_JPEG}
338 {$IFDEF GLB_LIB_JPEG}
339 {$MESSAGE warn 'The library libJPEG will be ignored if you are using the unit JPEG.'}
340 {$undef GLB_LIB_JPEG}
343 {$DEFINE GLB_SUPPORT_JPEG_READ}
344 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
348 {$IFDEF GLB_LIB_JPEG}
349 {$DEFINE GLB_SUPPORT_JPEG_READ}
350 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
354 {$IF DEFINED(GLB_NATIVE_OGL_STATIC) AND DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
355 {$MESSAGE warn 'GLB_NATIVE_OGL_STATIC will be ignored because you enabled GLB_NATIVE_OGL_DYNAMIC'}
369 {$IFNDEF GLB_NATIVE_OGL} dglOpenGL, {$ENDIF}
370 {$IF DEFINED(GLB_WIN) AND
371 DEFINED(GLB_NATIVE_OGL)} windows, {$IFEND}
373 {$IFDEF GLB_SDL} SDL, {$ENDIF}
374 {$IFDEF GLB_DELPHI} Dialogs, Graphics, {$ENDIF}
376 {$IFDEF GLB_SDL_IMAGE} SDL_image, {$ENDIF}
378 {$IFDEF GLB_PNGIMAGE} pngimage, {$ENDIF}
379 {$IFDEF GLB_LIB_PNG} libPNG, {$ENDIF}
381 {$IFDEF GLB_DELPHI_JPEG} JPEG, {$ENDIF}
382 {$IFDEF GLB_LIB_JPEG} libJPEG, {$ENDIF}
392 TRGBQuad = packed record
400 {$IFDEF GLB_NATIVE_OGL}
406 GL_EXTENSIONS = $1F03;
408 GL_TEXTURE_1D = $0DE0;
409 GL_TEXTURE_2D = $0DE1;
410 GL_TEXTURE_RECTANGLE = $84F5;
412 GL_TEXTURE_WIDTH = $1000;
413 GL_TEXTURE_HEIGHT = $1001;
414 GL_TEXTURE_INTERNAL_FORMAT = $1003;
422 GL_LUMINANCE = $1909;
423 GL_LUMINANCE4 = $803F;
424 GL_LUMINANCE8 = $8040;
425 GL_LUMINANCE12 = $8041;
426 GL_LUMINANCE16 = $8042;
428 GL_LUMINANCE_ALPHA = $190A;
429 GL_LUMINANCE4_ALPHA4 = $8043;
430 GL_LUMINANCE6_ALPHA2 = $8044;
431 GL_LUMINANCE8_ALPHA8 = $8045;
432 GL_LUMINANCE12_ALPHA4 = $8046;
433 GL_LUMINANCE12_ALPHA12 = $8047;
434 GL_LUMINANCE16_ALPHA16 = $8048;
457 GL_DEPTH_COMPONENT = $1902;
458 GL_DEPTH_COMPONENT16 = $81A5;
459 GL_DEPTH_COMPONENT24 = $81A6;
460 GL_DEPTH_COMPONENT32 = $81A7;
462 GL_COMPRESSED_RGB = $84ED;
463 GL_COMPRESSED_RGBA = $84EE;
464 GL_COMPRESSED_RGB_S3TC_DXT1_EXT = $83F0;
465 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = $83F1;
466 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = $83F2;
467 GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = $83F3;
469 GL_UNSIGNED_BYTE = $1401;
470 GL_UNSIGNED_BYTE_3_3_2 = $8032;
471 GL_UNSIGNED_BYTE_2_3_3_REV = $8362;
473 GL_UNSIGNED_SHORT = $1403;
474 GL_UNSIGNED_SHORT_5_6_5 = $8363;
475 GL_UNSIGNED_SHORT_4_4_4_4 = $8033;
476 GL_UNSIGNED_SHORT_5_5_5_1 = $8034;
477 GL_UNSIGNED_SHORT_5_6_5_REV = $8364;
478 GL_UNSIGNED_SHORT_4_4_4_4_REV = $8365;
479 GL_UNSIGNED_SHORT_1_5_5_5_REV = $8366;
481 GL_UNSIGNED_INT = $1405;
482 GL_UNSIGNED_INT_8_8_8_8 = $8035;
483 GL_UNSIGNED_INT_10_10_10_2 = $8036;
484 GL_UNSIGNED_INT_8_8_8_8_REV = $8367;
485 GL_UNSIGNED_INT_2_10_10_10_REV = $8368;
488 GL_TEXTURE_MAG_FILTER = $2800;
489 GL_TEXTURE_MIN_FILTER = $2801;
491 GL_NEAREST_MIPMAP_NEAREST = $2700;
492 GL_NEAREST_MIPMAP_LINEAR = $2702;
494 GL_LINEAR_MIPMAP_NEAREST = $2701;
495 GL_LINEAR_MIPMAP_LINEAR = $2703;
498 GL_TEXTURE_WRAP_S = $2802;
499 GL_TEXTURE_WRAP_T = $2803;
500 GL_TEXTURE_WRAP_R = $8072;
503 GL_CLAMP_TO_EDGE = $812F;
504 GL_CLAMP_TO_BORDER = $812D;
505 GL_MIRRORED_REPEAT = $8370;
508 GL_GENERATE_MIPMAP = $8191;
509 GL_TEXTURE_BORDER_COLOR = $1004;
510 GL_MAX_TEXTURE_SIZE = $0D33;
511 GL_PACK_ALIGNMENT = $0D05;
512 GL_UNPACK_ALIGNMENT = $0CF5;
514 GL_TEXTURE_MAX_ANISOTROPY_EXT = $84FE;
515 GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = $84FF;
518 libglu = 'libGLU.so.1';
519 libopengl = 'libGL.so.1';
521 libglu = 'glu32.dll';
522 libopengl = 'opengl32.dll';
526 GLboolean = BYTEBOOL;
534 PGLboolean = ^GLboolean;
539 TglCompressedTexImage1D = procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
540 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}
541 TglGetCompressedTexImage = procedure(target: GLenum; level: GLint; img: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
543 {$IF DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
544 TglEnable = procedure(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
545 TglDisable = procedure(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
547 TglGetString = function(name: GLenum): PAnsiChar; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
548 TglGetIntegerv = procedure(pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
550 TglTexParameteri = procedure(target: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
551 TglTexParameterfv = procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
552 TglGetTexParameteriv = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
553 TglGetTexParameterfv = procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
554 TglGetTexLevelParameteriv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
555 TglGetTexLevelParameterfv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
557 TglGenTextures = procedure(n: GLsizei; textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
558 TglBindTexture = procedure(target: GLenum; texture: GLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
559 TglDeleteTextures = procedure(n: GLsizei; const textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
561 TglAreTexturesResident = function(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
562 TglReadPixels = procedure(x: GLint; y: GLint; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
563 TglPixelStorei = procedure(pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
565 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}
566 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}
567 TglGetTexImage = procedure(target: GLenum; level: GLint; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
569 TgluBuild1DMipmaps = function(target: GLEnum; components, width: GLint; format, atype: GLEnum; const data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
570 TgluBuild2DMipmaps = function(target: GLEnum; components, width, height: GLint; format, atype: GLEnum; const Data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
573 TglXGetProcAddress = function(ProcName: PAnsiChar): Pointer; cdecl;
575 TwglGetProcAddress = function (ProcName: PAnsiChar): Pointer; stdcall;
578 {$ELSEIF DEFINED(GLB_NATIVE_OGL_STATIC)}
579 procedure glEnable(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
580 procedure glDisable(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
582 function glGetString(name: GLenum): PAnsiChar; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
583 procedure glGetIntegerv(pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
585 procedure glTexParameteri(target: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
586 procedure glTexParameterfv(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
587 procedure glGetTexParameteriv(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
588 procedure glGetTexParameterfv(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
589 procedure glGetTexLevelParameteriv(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
590 procedure glGetTexLevelParameterfv(target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
592 procedure glGenTextures(n: GLsizei; textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
593 procedure glBindTexture(target: GLenum; texture: GLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
594 procedure glDeleteTextures(n: GLsizei; const textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
596 function glAreTexturesResident(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
597 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;
598 procedure glPixelStorei(pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
600 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;
601 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;
602 procedure glGetTexImage(target: GLenum; level: GLint; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
604 function gluBuild1DMipmaps(target: GLEnum; components, width: GLint; format, atype: GLEnum; const data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libglu;
605 function gluBuild2DMipmaps(target: GLEnum; components, width, height: GLint; format, atype: GLEnum; const Data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libglu;
614 GL_SGIS_generate_mipmap,
616 GL_ARB_texture_border_clamp,
617 GL_ARB_texture_mirrored_repeat,
618 GL_ARB_texture_rectangle,
619 GL_ARB_texture_non_power_of_two,
621 GL_IBM_texture_mirrored_repeat,
623 GL_NV_texture_rectangle,
625 GL_EXT_texture_edge_clamp,
626 GL_EXT_texture_rectangle,
627 GL_EXT_texture_filter_anisotropic: Boolean;
629 glCompressedTexImage1D: TglCompressedTexImage1D;
630 glCompressedTexImage2D: TglCompressedTexImage2D;
631 glGetCompressedTexImage: TglGetCompressedTexImage;
633 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
635 glDisable: TglDisable;
637 glGetString: TglGetString;
638 glGetIntegerv: TglGetIntegerv;
640 glTexParameteri: TglTexParameteri;
641 glTexParameterfv: TglTexParameterfv;
642 glGetTexParameteriv: TglGetTexParameteriv;
643 glGetTexParameterfv: TglGetTexParameterfv;
644 glGetTexLevelParameteriv: TglGetTexLevelParameteriv;
645 glGetTexLevelParameterfv: TglGetTexLevelParameterfv;
647 glGenTextures: TglGenTextures;
648 glBindTexture: TglBindTexture;
649 glDeleteTextures: TglDeleteTextures;
651 glAreTexturesResident: TglAreTexturesResident;
652 glReadPixels: TglReadPixels;
653 glPixelStorei: TglPixelStorei;
655 glTexImage1D: TglTexImage1D;
656 glTexImage2D: TglTexImage2D;
657 glGetTexImage: TglGetTexImage;
659 gluBuild1DMipmaps: TgluBuild1DMipmaps;
660 gluBuild2DMipmaps: TgluBuild2DMipmaps;
662 {$IF DEFINED(GLB_WIN)}
663 wglGetProcAddress: TwglGetProcAddress;
664 {$ELSEIF DEFINED(GLB_LINUX)}
665 glXGetProcAddress: TglXGetProcAddress;
666 glXGetProcAddressARB: TglXGetProcAddressARB;
680 ////////////////////////////////////////////////////////////////////////////////////////////////////
681 EglBitmapException = class(Exception);
682 EglBitmapSizeToLargeException = class(EglBitmapException);
683 EglBitmapNonPowerOfTwoException = class(EglBitmapException);
684 EglBitmapUnsupportedFormatFormat = class(EglBitmapException);
686 ////////////////////////////////////////////////////////////////////////////////////////////////////
688 tfEmpty = 0, //must be smallest value!
704 tfLuminance12Alpha12,
705 tfLuminance16Alpha16,
749 TglBitmapFileType = (
750 {$IFDEF GLB_SUPPORT_PNG_WRITE} ftPNG, {$ENDIF}
751 {$IFDEF GLB_SUPPORT_JPEG_WRITE}ftJPEG, {$ENDIF}
755 TglBitmapFileTypes = set of TglBitmapFileType;
762 TglBitmapNormalMapFunc = (
768 ////////////////////////////////////////////////////////////////////////////////////////////////////
769 TglBitmapColorRec = packed record
771 0: (r, g, b, a: Cardinal);
772 1: (arr: array[0..3] of Cardinal);
775 TglBitmapPixelData = packed record
776 Data, Range: TglBitmapColorRec;
777 Format: TglBitmapFormat;
779 PglBitmapPixelData = ^TglBitmapPixelData;
781 ////////////////////////////////////////////////////////////////////////////////////////////////////
782 TglBitmapPixelPositionFields = set of (ffX, ffY);
783 TglBitmapPixelPosition = record
784 Fields : TglBitmapPixelPositionFields;
789 ////////////////////////////////////////////////////////////////////////////////////////////////////
791 TglBitmapFunctionRec = record
793 Size: TglBitmapPixelPosition;
794 Position: TglBitmapPixelPosition;
795 Source: TglBitmapPixelData;
796 Dest: TglBitmapPixelData;
799 TglBitmapFunction = procedure(var FuncRec: TglBitmapFunctionRec);
801 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
806 fAnisotropic: Integer;
807 fDeleteTextureOnFree: Boolean;
808 fFreeDataAfterGenTexture: Boolean;
810 fIsResident: Boolean;
811 fBorderColor: array[0..3] of Single;
813 fDimension: TglBitmapPixelPosition;
814 fMipMap: TglBitmapMipMap;
815 fFormat: TglBitmapFormat;
822 fFilterMin: Cardinal;
823 fFilterMag: Cardinal;
833 fCustomNameW: WideString;
834 fCustomData: Pointer;
837 function GetWidth: Integer; virtual;
838 function GetHeight: Integer; virtual;
840 function GetFileWidth: Integer; virtual;
841 function GetFileHeight: Integer; virtual;
844 procedure SetCustomData(const aValue: Pointer);
845 procedure SetCustomName(const aValue: String);
846 procedure SetCustomNameW(const aValue: WideString);
847 procedure SetDeleteTextureOnFree(const aValue: Boolean);
848 procedure SetFormat(const aValue: TglBitmapFormat);
849 procedure SetFreeDataAfterGenTexture(const aValue: Boolean);
850 procedure SetID(const aValue: Cardinal);
851 procedure SetMipMap(const aValue: TglBitmapMipMap);
852 procedure SetTarget(const aValue: Cardinal);
853 procedure SetAnisotropic(const aValue: Integer);
856 procedure SetupParameters(var aBuildWithGlu: Boolean);
857 procedure SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
858 const aWidth: Integer = -1; const aHeight: Integer = -1); virtual;
859 procedure GenTexture(const aTestTextureSize: Boolean = true); virtual; abstract;
861 function FlipHorz: Boolean; virtual;
862 function FlipVert: Boolean; virtual;
864 property Width: Integer read GetWidth;
865 property Height: Integer read GetHeight;
867 property FileWidth: Integer read GetFileWidth;
868 property FileHeight: Integer read GetFileHeight;
871 property ID: Cardinal read fID write SetID;
872 property Target: Cardinal read fTarget write SetTarget;
873 property Format: TglBitmapFormat read fFormat write SetFormat;
874 property MipMap: TglBitmapMipMap read fMipMap write SetMipMap;
875 property Anisotropic: Integer read fAnisotropic write SetAnisotropic;
877 property Filename: String read fFilename;
878 property CustomName: String read fCustomName write SetCustomName;
879 property CustomNameW: WideString read fCustomNameW write SetCustomNameW;
880 property CustomData: Pointer read fCustomData write SetCustomData;
882 property DeleteTextureOnFree: Boolean read fDeleteTextureOnFree write SetDeleteTextureOnFree;
883 property FreeDataAfterGenTexture: Boolean read fFreeDataAfterGenTexture write SetFreeDataAfterGenTexture;
885 property Dimension: TglBitmapPixelPosition read fDimension;
886 property Data: PByte read fData;
887 property IsResident: Boolean read fIsResident;
889 procedure AfterConstruction; override;
890 procedure BeforeDestruction; override;
893 procedure LoadFromFile(const aFilename: String);
894 procedure LoadFromStream(const aStream: TStream); virtual;
895 procedure LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
896 const aFormat: TglBitmapFormat; const aArgs: PtrInt = 0);
898 procedure LoadFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil);
899 procedure LoadFromResourceID(const sInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
903 procedure SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
904 procedure SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType); virtual;
907 function AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: PtrInt = 0): Boolean; overload;
908 function AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
909 const aFormat: TglBitmapFormat; const aArgs: PtrInt = 0): Boolean; overload;
913 function AssignToSurface(out aSurface: PSDL_Surface): Boolean;
914 function AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
915 function AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
916 function AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil;
917 const aArgs: PtrInt = 0): Boolean;
921 function AssignToBitmap(const aBitmap: TBitmap): Boolean;
922 function AssignFromBitmap(const aBitmap: TBitmap): Boolean;
923 function AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
924 function AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction = nil;
925 const aArgs: PtrInt = 0): Boolean;
926 function AddAlphaFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil;
927 const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
928 function AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
929 const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
932 function AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: PtrInt = 0): Boolean; virtual;
933 function AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
934 function AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
935 function AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
937 function AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte = 0): Boolean;
938 function AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal = 0): Boolean;
939 function AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single = 0): Boolean;
941 function AddAlphaFromValue(const aAlpha: Byte): Boolean;
942 function AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
943 function AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
945 function RemoveAlpha: Boolean; virtual;
948 function Clone: TglBitmap;
949 function ConvertTo(const aFormat: TglBitmapFormat): Boolean; virtual;
950 procedure Invert(const aUseRGB: Boolean = true; const aUseAlpha: Boolean = false);
951 procedure SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
955 procedure FillWithColor(const aRed, aGreen, aBlue: Byte; const aAlpha: Byte = 255);
956 procedure FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal = $FFFFFFFF);
957 procedure FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha : Single = 1);
960 procedure SetFilter(const aMin, aMag: Cardinal);
962 const S: Cardinal = GL_CLAMP_TO_EDGE;
963 const T: Cardinal = GL_CLAMP_TO_EDGE;
964 const R: Cardinal = GL_CLAMP_TO_EDGE);
966 procedure GetPixel(const aPos: TglBitmapPixelPosition; var aPixel: TglBitmapPixelData); virtual;
967 procedure SetPixel(const aPos: TglBitmapPixelPosition; const aPixel: TglBitmapPixelData); virtual;
969 procedure Bind(const aEnableTextureUnit: Boolean = true); virtual;
970 procedure Unbind(const aDisableTextureUnit: Boolean = true); virtual;
973 constructor Create; overload;
974 constructor Create(const aFileName: String); overload;
975 constructor Create(const aStream: TStream); overload;
976 constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat); overload;
977 constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: PtrInt = 0); overload;
979 constructor Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil); overload;
980 constructor Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar); overload;
983 {$IFDEF GLB_SUPPORT_PNG_READ}
984 function LoadPNG(const aStream: TStream): Boolean; virtual;
985 procedure SavePNG(const aStream: TStream); virtual;
987 {$IFDEF GLB_SUPPORT_JPEG_READ}
988 function LoadJPEG(const aStream: TStream): Boolean; virtual;
989 procedure SaveJPEG(const aStream: TStream); virtual;
991 function LoadBMP(const aStream: TStream): Boolean; virtual;
992 procedure SaveBMP(const aStream: TStream); virtual;
994 function LoadTGA(const aStream: TStream): Boolean; virtual;
995 procedure SaveTGA(const aStream: TStream); virtual;
997 function LoadDDS(const aStream: TStream): Boolean; virtual;
998 procedure SaveDDS(const aStream: TStream); virtual;
1001 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1002 TglBitmap2D = class(TglBitmap)
1004 // Bildeinstellungen
1005 fLines: array of PByte;
1008 procedure GetDXTColorBlock(pData: pByte; relX, relY: Integer; var Pixel: TglBitmapPixelData);
1009 procedure GetPixel2DDXT1(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
1010 procedure GetPixel2DDXT3(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
1011 procedure GetPixel2DDXT5(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
1012 procedure GetPixel2DUnmap(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
1013 procedure SetPixel2DUnmap(const Pos: TglBitmapPixelPosition; const Pixel: TglBitmapPixelData);
1016 function GetScanline(const aIndex: Integer): Pointer;
1017 procedure SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
1018 const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
1019 procedure UploadData(const aTarget: Cardinal; const aBuildWithGlu: Boolean);
1023 property Scanline[const aIndex: Integer]: Pointer read GetScanline;
1025 procedure AfterConstruction; override;
1027 procedure GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
1028 procedure GetDataFromTexture;
1029 procedure GenTexture(const aTestTextureSize: Boolean = true); override;
1031 function FlipHorz: Boolean; override;
1032 function FlipVert: Boolean; override;
1034 procedure ToNormalMap(const aFunc: TglBitmapNormalMapFunc = nm3x3;
1035 const aScale: Single = 2; const aUseAlpha: Boolean = false);
1039 TglBitmapCubeMap = class(TglBitmap2D)
1044 procedure GenTexture(TestTextureSize: Boolean = true); reintroduce;
1046 procedure AfterConstruction; override;
1048 procedure GenerateCubeMap(CubeTarget: Cardinal; TestTextureSize: Boolean = true);
1050 procedure Unbind(DisableTexCoordsGen: Boolean = true; DisableTextureUnit: Boolean = true); reintroduce; virtual;
1051 procedure Bind(EnableTexCoordsGen: Boolean = true; EnableTextureUnit: Boolean = true); reintroduce; virtual;
1055 TglBitmapNormalMap = class(TglBitmapCubeMap)
1057 procedure AfterConstruction; override;
1059 procedure GenerateNormalMap(Size: Integer = 32; TestTextureSize: Boolean = true);
1063 TglBitmap1D = class(TglBitmap)
1065 procedure GetPixel1DUnmap(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
1067 procedure SetDataPointer(Data: pByte; Format: TglBitmapInternalFormat; Width: Integer = -1; Height: Integer = -1); override;
1068 procedure UploadData (Target, Format, InternalFormat, Typ: Cardinal; BuildWithGlu: Boolean);
1073 procedure AfterConstruction; override;
1076 function FlipHorz: Boolean; override;
1079 procedure GenTexture(TestTextureSize: Boolean = true); override;
1084 NULL_SIZE: TglBitmapPixelPosition = (Fields: []; X: 0; Y: 0);
1086 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
1087 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
1088 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
1089 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
1090 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
1091 procedure glBitmapSetDefaultWrap(
1092 const S: Cardinal = GL_CLAMP_TO_EDGE;
1093 const T: Cardinal = GL_CLAMP_TO_EDGE;
1094 const R: Cardinal = GL_CLAMP_TO_EDGE);
1096 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
1097 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
1098 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
1099 function glBitmapGetDefaultFormat: TglBitmapFormat;
1100 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
1101 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
1103 function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
1104 function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
1105 function glBitmapColorRecCmp(const r1, r2: TglBitmapColorRec): Boolean;
1108 glBitmapDefaultDeleteTextureOnFree: Boolean;
1109 glBitmapDefaultFreeDataAfterGenTextures: Boolean;
1110 glBitmapDefaultFormat: TglBitmapFormat;
1111 glBitmapDefaultMipmap: TglBitmapMipMap;
1112 glBitmapDefaultFilterMin: Cardinal;
1113 glBitmapDefaultFilterMag: Cardinal;
1114 glBitmapDefaultWrapS: Cardinal;
1115 glBitmapDefaultWrapT: Cardinal;
1116 glBitmapDefaultWrapR: Cardinal;
1119 function CreateGrayPalette: HPALETTE;
1126 function FormatIsCompressed(Format: TglBitmapInternalFormat): boolean;
1127 function FormatIsUncompressed(Format: TglBitmapInternalFormat): boolean;
1128 function LoadTexture(Filename: String; var Texture: Cardinal{$IFDEF GLB_DELPHI}; LoadFromRes : Boolean; Instance: Cardinal = 0{$ENDIF}): Boolean;
1129 function LoadCubeMap(PositiveX, NegativeX, PositiveY, NegativeY, PositiveZ, NegativeZ: String; var Texture: Cardinal{$IFDEF GLB_DELPHI}; LoadFromRes : Boolean; Instance: Cardinal = 0{$ENDIF}): Boolean;
1130 function LoadNormalMap(Size: Integer; var Texture: Cardinal): Boolean;
1137 ////////////////////////////////////////////////////////////////////////////////////////////////////
1138 TShiftRec = packed record
1140 0: (r, g, b, a: Byte);
1141 1: (arr: array[0..3] of Byte);
1144 TFormatDescriptor = class(TObject)
1146 function GetRedMask: UInt64;
1147 function GetGreenMask: UInt64;
1148 function GetBlueMask: UInt64;
1149 function GetAlphaMask: UInt64;
1151 fFormat: TglBitmapFormat;
1152 fWithAlpha: TglBitmapFormat;
1153 fWithoutAlpha: TglBitmapFormat;
1154 fRGBInverted: TglBitmapFormat;
1155 fUncompressed: TglBitmapFormat;
1157 fIsCompressed: Boolean;
1159 fRange: TglBitmapColorRec;
1162 fglFormat: Cardinal;
1163 fglInternalFormat: Cardinal;
1164 fglDataFormat: Cardinal;
1166 function GetComponents: Integer; virtual;
1168 property Format: TglBitmapFormat read fFormat;
1169 property WithAlpha: TglBitmapFormat read fWithAlpha;
1170 property WithoutAlpha: TglBitmapFormat read fWithoutAlpha;
1171 property RGBInverted: TglBitmapFormat read fRGBInverted;
1172 property Components: Integer read GetComponents;
1173 property PixelSize: Single read fPixelSize;
1174 property IsCompressed: Boolean read fIsCompressed;
1176 property glFormat: Cardinal read fglFormat;
1177 property glInternalFormat: Cardinal read fglInternalFormat;
1178 property glDataFormat: Cardinal read fglDataFormat;
1180 property Range: TglBitmapColorRec read fRange;
1181 property Shift: TShiftRec read fShift;
1183 property RedMask: UInt64 read GetRedMask;
1184 property GreenMask: UInt64 read GetGreenMask;
1185 property BlueMask: UInt64 read GetBlueMask;
1186 property AlphaMask: UInt64 read GetAlphaMask;
1188 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); virtual; abstract;
1189 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract;
1191 function GetSize(const aSize: TglBitmapPixelPosition): Integer; virtual; overload;
1192 function GetSize(const aWidth, aHeight: Integer): Integer; virtual; overload;
1194 function CreateMappingData: Pointer; virtual;
1195 procedure FreeMappingData(var aMappingData: Pointer); virtual;
1197 function IsEmpty: Boolean; virtual;
1198 function HasAlpha: Boolean; virtual;
1199 function MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: UInt64): Boolean; virtual;
1201 procedure PreparePixel(out aPixel: TglBitmapPixelData); virtual;
1203 constructor Create; virtual;
1205 class procedure Init;
1206 class function Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
1207 class function GetWithAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
1208 class procedure Clear;
1209 class procedure Finalize;
1211 TFormatDescriptorClass = class of TFormatDescriptor;
1213 TfdEmpty = class(TFormatDescriptor);
1215 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1216 TfdAlpha_UB1 = class(TFormatDescriptor) //1* unsigned byte
1217 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1218 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1219 constructor Create; override;
1222 TfdLuminance_UB1 = class(TFormatDescriptor) //1* unsigned byte
1223 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1224 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1225 constructor Create; override;
1228 TfdUniversal_UB1 = class(TFormatDescriptor) //1* unsigned byte
1229 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1230 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1231 constructor Create; override;
1234 TfdLuminanceAlpha_UB2 = class(TfdLuminance_UB1) //2* unsigned byte
1235 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1236 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1237 constructor Create; override;
1240 TfdRGB_UB3 = class(TFormatDescriptor) //3* unsigned byte
1241 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1242 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1243 constructor Create; override;
1246 TfdBGR_UB3 = class(TFormatDescriptor) //3* unsigned byte (inverse)
1247 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1248 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1249 constructor Create; override;
1252 TfdRGBA_UB4 = class(TfdRGB_UB3) //4* unsigned byte
1253 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1254 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1255 constructor Create; override;
1258 TfdBGRA_UB4 = class(TfdBGR_UB3) //4* unsigned byte (inverse)
1259 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1260 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1261 constructor Create; override;
1264 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1265 TfdAlpha_US1 = class(TFormatDescriptor) //1* unsigned short
1266 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1267 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1268 constructor Create; override;
1271 TfdLuminance_US1 = class(TFormatDescriptor) //1* unsigned short
1272 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1273 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1274 constructor Create; override;
1277 TfdUniversal_US1 = class(TFormatDescriptor) //1* unsigned short
1278 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1279 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1280 constructor Create; override;
1283 TfdDepth_US1 = class(TFormatDescriptor) //1* unsigned short
1284 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1285 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1286 constructor Create; override;
1289 TfdLuminanceAlpha_US2 = class(TfdLuminance_US1) //2* unsigned short
1290 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1291 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1292 constructor Create; override;
1295 TfdRGB_US3 = class(TFormatDescriptor) //3* unsigned short
1296 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1297 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1298 constructor Create; override;
1301 TfdBGR_US3 = class(TFormatDescriptor) //3* unsigned short (inverse)
1302 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1303 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1304 constructor Create; override;
1307 TfdRGBA_US4 = class(TfdRGB_US3) //4* unsigned short
1308 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1309 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1310 constructor Create; override;
1313 TfdBGRA_US4 = class(TfdBGR_US3) //4* unsigned short (inverse)
1314 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1315 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1316 constructor Create; override;
1319 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1320 TfdUniversal_UI1 = class(TFormatDescriptor) //1* unsigned int
1321 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1322 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1323 constructor Create; override;
1326 TfdDepth_UI1 = class(TFormatDescriptor) //1* unsigned int
1327 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1328 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1329 constructor Create; override;
1332 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1333 TfdAlpha4 = class(TfdAlpha_UB1)
1334 constructor Create; override;
1337 TfdAlpha8 = class(TfdAlpha_UB1)
1338 constructor Create; override;
1341 TfdAlpha12 = class(TfdAlpha_US1)
1342 constructor Create; override;
1345 TfdAlpha16 = class(TfdAlpha_US1)
1346 constructor Create; override;
1349 TfdLuminance4 = class(TfdLuminance_UB1)
1350 constructor Create; override;
1353 TfdLuminance8 = class(TfdLuminance_UB1)
1354 constructor Create; override;
1357 TfdLuminance12 = class(TfdLuminance_US1)
1358 constructor Create; override;
1361 TfdLuminance16 = class(TfdLuminance_US1)
1362 constructor Create; override;
1365 TfdLuminance4Alpha4 = class(TfdLuminanceAlpha_UB2)
1366 constructor Create; override;
1369 TfdLuminance6Alpha2 = class(TfdLuminanceAlpha_UB2)
1370 constructor Create; override;
1373 TfdLuminance8Alpha8 = class(TfdLuminanceAlpha_UB2)
1374 constructor Create; override;
1377 TfdLuminance12Alpha4 = class(TfdLuminanceAlpha_US2)
1378 constructor Create; override;
1381 TfdLuminance12Alpha12 = class(TfdLuminanceAlpha_US2)
1382 constructor Create; override;
1385 TfdLuminance16Alpha16 = class(TfdLuminanceAlpha_US2)
1386 constructor Create; override;
1389 TfdR3G3B2 = class(TfdUniversal_UB1)
1390 constructor Create; override;
1393 TfdRGB4 = class(TfdUniversal_US1)
1394 constructor Create; override;
1397 TfdR5G6B5 = class(TfdUniversal_US1)
1398 constructor Create; override;
1401 TfdRGB5 = class(TfdUniversal_US1)
1402 constructor Create; override;
1405 TfdRGB8 = class(TfdRGB_UB3)
1406 constructor Create; override;
1409 TfdRGB10 = class(TfdUniversal_UI1)
1410 constructor Create; override;
1413 TfdRGB12 = class(TfdRGB_US3)
1414 constructor Create; override;
1417 TfdRGB16 = class(TfdRGB_US3)
1418 constructor Create; override;
1421 TfdRGBA2 = class(TfdRGBA_UB4)
1422 constructor Create; override;
1425 TfdRGBA4 = class(TfdUniversal_US1)
1426 constructor Create; override;
1429 TfdRGB5A1 = class(TfdUniversal_US1)
1430 constructor Create; override;
1433 TfdRGBA8 = class(TfdRGBA_UB4)
1434 constructor Create; override;
1437 TfdRGB10A2 = class(TfdUniversal_UI1)
1438 constructor Create; override;
1441 TfdRGBA12 = class(TfdRGBA_US4)
1442 constructor Create; override;
1445 TfdRGBA16 = class(TfdRGBA_US4)
1446 constructor Create; override;
1449 TfdBGR4 = class(TfdUniversal_US1)
1450 constructor Create; override;
1453 TfdB5G6R5 = class(TfdUniversal_US1)
1454 constructor Create; override;
1457 TfdBGR5 = class(TfdUniversal_US1)
1458 constructor Create; override;
1461 TfdBGR8 = class(TfdBGR_UB3)
1462 constructor Create; override;
1465 TfdBGR10 = class(TfdUniversal_UI1)
1466 constructor Create; override;
1469 TfdBGR12 = class(TfdBGR_US3)
1470 constructor Create; override;
1473 TfdBGR16 = class(TfdBGR_US3)
1474 constructor Create; override;
1477 TfdBGRA2 = class(TfdBGRA_UB4)
1478 constructor Create; override;
1481 TfdBGRA4 = class(TfdUniversal_US1)
1482 constructor Create; override;
1485 TfdBGR5A1 = class(TfdUniversal_US1)
1486 constructor Create; override;
1489 TfdBGRA8 = class(TfdBGRA_UB4)
1490 constructor Create; override;
1493 TfdBGR10A2 = class(TfdUniversal_UI1)
1494 constructor Create; override;
1497 TfdBGRA12 = class(TfdBGRA_US4)
1498 constructor Create; override;
1501 TfdBGRA16 = class(TfdBGRA_US4)
1502 constructor Create; override;
1505 TfdDepth16 = class(TfdDepth_US1)
1506 constructor Create; override;
1509 TfdDepth24 = class(TfdDepth_UI1)
1510 constructor Create; override;
1513 TfdDepth32 = class(TfdDepth_UI1)
1514 constructor Create; override;
1517 TfdS3tcDtx1RGBA = class(TFormatDescriptor)
1518 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1519 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1520 constructor Create; override;
1523 TfdS3tcDtx3RGBA = class(TFormatDescriptor)
1524 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1525 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1526 constructor Create; override;
1529 TfdS3tcDtx5RGBA = class(TFormatDescriptor)
1530 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1531 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1532 constructor Create; override;
1535 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1536 TbmpBitfieldFormat = class(TFormatDescriptor)
1538 procedure SetRedMask (const aValue: UInt64);
1539 procedure SetGreenMask(const aValue: UInt64);
1540 procedure SetBlueMask (const aValue: UInt64);
1541 procedure SetAlphaMask(const aValue: UInt64);
1543 procedure Update(aMask: UInt64; out aRange: Cardinal; out aShift: Byte);
1545 property RedMask: UInt64 read GetRedMask write SetRedMask;
1546 property GreenMask: UInt64 read GetGreenMask write SetGreenMask;
1547 property BlueMask: UInt64 read GetBlueMask write SetBlueMask;
1548 property AlphaMask: UInt64 read GetAlphaMask write SetAlphaMask;
1550 property PixelSize: Single read fPixelSize write fPixelSize;
1552 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1553 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1556 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1557 TbmpColorTableEnty = packed record
1560 TbmpColorTable = array of TbmpColorTableEnty;
1561 TbmpColorTableFormat = class(TFormatDescriptor)
1563 fColorTable: TbmpColorTable;
1565 property PixelSize: Single read fPixelSize write fPixelSize;
1566 property ColorTable: TbmpColorTable read fColorTable write fColorTable;
1567 property Range: TglBitmapColorRec read fRange write fRange;
1568 property Shift: TShiftRec read fShift write fShift;
1569 property Format: TglBitmapFormat read fFormat write fFormat;
1571 procedure CreateColorTable;
1573 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1574 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1575 destructor Destroy; override;
1579 LUMINANCE_WEIGHT_R = 0.30;
1580 LUMINANCE_WEIGHT_G = 0.59;
1581 LUMINANCE_WEIGHT_B = 0.11;
1583 ALPHA_WEIGHT_R = 0.30;
1584 ALPHA_WEIGHT_G = 0.59;
1585 ALPHA_WEIGHT_B = 0.11;
1587 DEPTH_WEIGHT_R = 0.333333333;
1588 DEPTH_WEIGHT_G = 0.333333333;
1589 DEPTH_WEIGHT_B = 0.333333333;
1591 UNSUPPORTED_FORMAT = 'the given format isn''t supported by this function.';
1593 FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
1606 TfdLuminance4Alpha4,
1607 TfdLuminance6Alpha2,
1608 TfdLuminance8Alpha8,
1609 TfdLuminance12Alpha4,
1610 TfdLuminance12Alpha12,
1611 TfdLuminance16Alpha16,
1656 FormatDescriptorCS: TCriticalSection;
1657 FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
1659 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1660 function glBitmapPosition(X, Y: Integer): TglBitmapPixelPosition;
1662 result.Fields := [];
1665 result.Fields := result.Fields + [ffX];
1667 result.Fields := result.Fields + [ffY];
1669 result.X := Max(0, X);
1670 result.Y := Max(0, Y);
1673 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1674 function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
1682 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1683 function glBitmapColorRecCmp(const r1, r2: TglBitmapColorRec): Boolean;
1688 for i := 0 to high(r1.arr) do
1689 if (r1.arr[i] <> r2.arr[i]) then
1694 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1695 function glBitmapShiftRec(const r, g, b, a: Byte): TShiftRec;
1703 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1704 function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
1713 tfR3G3B2, tfLuminance8,
1716 tfRGB4, tfRGB5, tfR5G6B5, tfRGB5A1, tfRGBA4,
1717 tfBGR4, tfBGR5, tfB5G6R5, tfBGR5A1, tfBGRA4,
1723 tfRGB10, tfRGB10A2, tfRGBA8,
1724 tfBGR10, tfBGR10A2, tfBGRA8]) then
1725 result := result + [ftBMP];
1729 tfLuminance8, tfAlpha8,
1732 tfLuminance16, tfLuminance8Alpha8,
1733 tfRGB5, tfRGB5A1, tfRGBA4,
1734 tfBGR5, tfBGR5A1, tfBGRA4,
1740 tfRGB10A2, tfRGBA8, tfBGR10A2, tfBGRA8]) then
1741 result := result + [ftTGA];
1745 tfAlpha8, tfLuminance8, tfLuminance4Alpha4, tfLuminance6Alpha2,
1746 tfR3G3B2, tfRGBA2, tfBGRA2,
1749 tfAlpha16, tfLuminance16, tfLuminance8Alpha8, tfLuminance12Alpha4,
1750 tfRGB4, tfR5G6B5, tfRGB5, tfRGBA4, tfRGB5A1,
1751 tfBGR4, tfB5G6R5, tfBGR5, tfBGRA4, tfBGR5A1,
1757 tfLuminance16Alpha16,
1762 tfS3tcDtx1RGBA, tfS3tcDtx3RGBA, tfS3tcDtx5RGBA]) then
1763 result := result + [ftDDS];
1766 {$IFDEF GLB_SUPPORT_PNG_WRITE}
1768 tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16,
1769 tfLuminance4, tfLuminance8, tfLuminance12, tfLuminance16,
1770 tfuminance4Alpha4, tfLuminance6Alpha2, tfLuminance8Alpha8, tfLuminance12Alpha4, tfLuminance12Alpha12, tfLuminance16Alpha16,
1771 tfR3G3B2, tfRGB4, tfRGB5, tfRGB8, tfRGB10, tfRGB12, tfRGB16,
1772 tfRGBA2, tfRGBA4, tfRGB5A1, tfRGBA8, tfRGB10A2, tfRGBA12, tfRGBA16,
1773 tfDepth16, tfDepth24, tfDepth32]
1775 result := result + [ftPNG];
1778 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
1780 tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16,
1781 tfLuminance4, tfLuminance8, tfLuminance12, tfLuminance16,
1782 tfR3G3B2, tfRGB4, tfRGB5, tfRGB8, tfRGB10, tfRGB12, tfRGB16,
1783 tfDepth16, tfDepth24, tfDepth32]
1785 result := result + [ftJPEG];
1789 tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16,
1790 tfLuminance4, tfLuminance8, tfLuminance12, tfLuminance16,
1791 tfuminance4Alpha4, tfLuminance6Alpha2, tfLuminance8Alpha8, tfLuminance12Alpha4, tfLuminance12Alpha12, tfLuminance16Alpha16,
1792 tfR3G3B2, tfRGB4, tfRGB5, tfRGB8, tfRGB10, tfRGB12, tfRGB16,
1793 tfRGBA2, tfRGBA4, tfRGB5A1, tfRGBA8, tfRGB10A2, tfRGBA12, tfRGBA16,
1794 tfDepth16, tfDepth24, tfDepth32]
1796 result := result + [ftDDS, ftTGA, ftBMP];
1800 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1801 function IsPowerOfTwo(aNumber: Integer): Boolean;
1803 while (aNumber and 1) = 0 do
1804 aNumber := aNumber shr 1;
1805 result := aNumber = 1;
1808 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1809 function GetTopMostBit(aBitSet: UInt64): Integer;
1812 while aBitSet > 0 do begin
1814 aBitSet := aBitSet shr 1;
1818 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1819 function CountSetBits(aBitSet: UInt64): Integer;
1822 while aBitSet > 0 do begin
1823 if (aBitSet and 1) = 1 then
1825 aBitSet := aBitSet shr 1;
1829 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1830 function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
1833 LUMINANCE_WEIGHT_R * aPixel.Data.r +
1834 LUMINANCE_WEIGHT_G * aPixel.Data.g +
1835 LUMINANCE_WEIGHT_B * aPixel.Data.b);
1838 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1839 function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
1842 DEPTH_WEIGHT_R * aPixel.Data.r +
1843 DEPTH_WEIGHT_G * aPixel.Data.g +
1844 DEPTH_WEIGHT_B * aPixel.Data.b);
1847 {$IFDEF GLB_NATIVE_OGL}
1848 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1849 //OpenGLInitialization///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1850 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1852 GL_LibHandle: Pointer = nil;
1854 function glbGetProcAddress(aProcName: PChar; aLibHandle: Pointer = nil): Pointer;
1858 if not Assigned(aLibHandle) then
1859 aLibHandle := GL_LibHandle;
1861 {$IF DEFINED(GLB_WIN)}
1862 result := GetProcAddress(HMODULE(aLibHandle), aProcName);
1863 if Assigned(result) then
1866 if Assigned(wglGetProcAddress) then
1867 result := wglGetProcAddress(aProcName);
1868 {$ELSEIF DEFINED(GLB_LINUX)}
1869 if Assigned(glXGetProcAddress) then begin
1870 result := glXGetProcAddress(aProcName);
1871 if Assigned(result) then
1875 if Assigned(glXGetProcAddressARB) then begin
1876 result := glXGetProcAddressARB(aProcName);
1877 if Assigned(result) then
1881 result := dlsym(aLibHandle, aProcName);
1883 if not Assigned(result) then
1884 raise EglBitmapException.Create('unable to load procedure form library: ' + aProcName);
1887 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
1889 GLU_LibHandle: Pointer = nil;
1890 OpenGLInitialized: Boolean;
1891 InitOpenGLCS: TCriticalSection;
1893 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1894 procedure glbInitOpenGL;
1896 ////////////////////////////////////////////////////////////////////////////////
1897 function glbLoadLibrary(const aName: PChar): Pointer;
1899 {$IF DEFINED(GLB_WIN)}
1900 result := Pointer(LoadLibrary(aName));
1901 {$ELSEIF DEFINED(GLB_LINUX)}
1902 result := dlopen(Name, RTLD_LAZY);
1908 ////////////////////////////////////////////////////////////////////////////////
1909 function glbFreeLibrary(const aLibHandle: Pointer): Boolean;
1912 if not Assigned(aLibHandle) then
1915 {$IF DEFINED(GLB_WIN)}
1916 Result := FreeLibrary(HINST(aLibHandle));
1917 {$ELSEIF DEFINED(GLB_LINUX)}
1918 Result := dlclose(aLibHandle) = 0;
1925 if Assigned(GL_LibHandle) then
1926 glbFreeLibrary(GL_LibHandle);
1928 if Assigned(GLU_LibHandle) then
1929 glbFreeLibrary(GLU_LibHandle);
1931 GL_LibHandle := glbLoadLibrary(libopengl);
1932 if not Assigned(GL_LibHandle) then
1933 raise EglBitmapException.Create('unable to load library: ' + libopengl);
1935 GLU_LibHandle := glbLoadLibrary(libglu);
1936 if not Assigned(GLU_LibHandle) then
1937 raise EglBitmapException.Create('unable to load library: ' + libglu);
1940 {$IF DEFINED(GLB_WIN)}
1941 wglGetProcAddress := glbGetProcAddress('wglGetProcAddress');
1942 {$ELSEIF DEFINED(GLB_LINUX)}
1943 glXGetProcAddress := glbGetProcAddress('glXGetProcAddress');
1944 glXGetProcAddressARB := dglGetProcAddress('glXGetProcAddressARB');
1947 glEnable := glbGetProcAddress('glEnable');
1948 glDisable := glbGetProcAddress('glDisable');
1949 glGetString := glbGetProcAddress('glGetString');
1950 glGetIntegerv := glbGetProcAddress('glGetIntegerv');
1951 glTexParameteri := glbGetProcAddress('glTexParameteri');
1952 glTexParameterfv := glbGetProcAddress('glTexParameterfv');
1953 glGetTexParameteriv := glbGetProcAddress('glGetTexParameteriv');
1954 glGetTexParameterfv := glbGetProcAddress('glGetTexParameterfv');
1955 glGetTexLevelParameteriv := glbGetProcAddress('glGetTexLevelParameteriv');
1956 glGetTexLevelParameterfv := glbGetProcAddress('glGetTexLevelParameterfv');
1957 glGenTextures := glbGetProcAddress('glGenTextures');
1958 glBindTexture := glbGetProcAddress('glBindTexture');
1959 glDeleteTextures := glbGetProcAddress('glDeleteTextures');
1960 glAreTexturesResident := glbGetProcAddress('glAreTexturesResident');
1961 glReadPixels := glbGetProcAddress('glReadPixels');
1962 glPixelStorei := glbGetProcAddress('glPixelStorei');
1963 glTexImage1D := glbGetProcAddress('glTexImage1D');
1964 glTexImage2D := glbGetProcAddress('glTexImage2D');
1965 glGetTexImage := glbGetProcAddress('glGetTexImage');
1967 gluBuild1DMipmaps := glbGetProcAddress('gluBuild1DMipmaps', GLU_LibHandle);
1968 gluBuild2DMipmaps := glbGetProcAddress('gluBuild2DMipmaps', GLU_LibHandle);
1970 glbFreeLibrary(GL_LibHandle);
1971 glbFreeLibrary(GLU_LibHandle);
1976 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1977 procedure glbReadOpenGLExtensions;
1983 MajorVersion, MinorVersion: Integer;
1985 ///////////////////////////////////////////////////////////////////////////////////////////
1986 procedure TrimVersionString(Buffer: AnsiString; var Major, Minor: Integer);
1993 Separator := Pos(AnsiString('.'), Buffer);
1994 if (Separator > 1) and (Separator < Length(Buffer)) and
1995 (Buffer[Separator - 1] in ['0'..'9']) and
1996 (Buffer[Separator + 1] in ['0'..'9']) then begin
1999 while (Separator > 0) and (Buffer[Separator] in ['0'..'9']) do
2002 Delete(Buffer, 1, Separator);
2003 Separator := Pos(AnsiString('.'), Buffer) + 1;
2005 while (Separator <= Length(Buffer)) and (AnsiChar(Buffer[Separator]) in ['0'..'9']) do
2008 Delete(Buffer, Separator, 255);
2009 Separator := Pos(AnsiString('.'), Buffer);
2011 Major := StrToInt(Copy(String(Buffer), 1, Separator - 1));
2012 Minor := StrToInt(Copy(String(Buffer), Separator + 1, 1));
2016 ///////////////////////////////////////////////////////////////////////////////////////////
2017 function CheckExtension(const Extension: AnsiString): Boolean;
2021 ExtPos := Pos(Extension, Buffer);
2022 result := ExtPos > 0;
2024 result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
2028 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
2031 if not OpenGLInitialized then begin
2033 OpenGLInitialized := true;
2041 Context := wglGetCurrentContext;
2042 if (Context <> gLastContext) then begin
2043 gLastContext := Context;
2047 Buffer := glGetString(GL_VERSION);
2048 TrimVersionString(Buffer, MajorVersion, MinorVersion);
2050 GL_VERSION_1_2 := false;
2051 GL_VERSION_1_3 := false;
2052 GL_VERSION_1_4 := false;
2053 GL_VERSION_2_0 := false;
2054 if MajorVersion = 1 then begin
2055 if MinorVersion >= 2 then
2056 GL_VERSION_1_2 := true;
2058 if MinorVersion >= 3 then
2059 GL_VERSION_1_3 := true;
2061 if MinorVersion >= 4 then
2062 GL_VERSION_1_4 := true;
2063 end else if MajorVersion >= 2 then begin
2064 GL_VERSION_1_2 := true;
2065 GL_VERSION_1_3 := true;
2066 GL_VERSION_1_4 := true;
2067 GL_VERSION_2_0 := true;
2071 Buffer := glGetString(GL_EXTENSIONS);
2072 GL_ARB_texture_border_clamp := CheckExtension('GL_ARB_texture_border_clamp');
2073 GL_ARB_texture_non_power_of_two := CheckExtension('GL_ARB_texture_non_power_of_two');
2074 GL_ARB_texture_rectangle := CheckExtension('GL_ARB_texture_rectangle');
2075 GL_ARB_texture_mirrored_repeat := CheckExtension('GL_ARB_texture_mirrored_repeat');
2076 GL_EXT_texture_edge_clamp := CheckExtension('GL_EXT_texture_edge_clamp');
2077 GL_EXT_texture_filter_anisotropic := CheckExtension('GL_EXT_texture_filter_anisotropic');
2078 GL_EXT_texture_rectangle := CheckExtension('GL_EXT_texture_rectangle');
2079 GL_NV_texture_rectangle := CheckExtension('GL_NV_texture_rectangle');
2080 GL_IBM_texture_mirrored_repeat := CheckExtension('GL_IBM_texture_mirrored_repeat');
2081 GL_SGIS_generate_mipmap := CheckExtension('GL_SGIS_generate_mipmap');
2083 if GL_VERSION_1_3 then begin
2084 glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1D');
2085 glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2D');
2086 glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImage');
2088 glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1DARB');
2089 glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2DARB');
2090 glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImageARB');
2100 function CreateGrayPalette: HPALETTE;
2105 GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
2107 Pal.palVersion := $300;
2108 Pal.palNumEntries := 256;
2111 {$DEFINE GLB_TEMPRANGECHECK}
2115 for Idx := 0 to 256 - 1 do begin
2116 Pal.palPalEntry[Idx].peRed := Idx;
2117 Pal.palPalEntry[Idx].peGreen := Idx;
2118 Pal.palPalEntry[Idx].peBlue := Idx;
2119 Pal.palPalEntry[Idx].peFlags := 0;
2122 {$IFDEF GLB_TEMPRANGECHECK}
2123 {$UNDEF GLB_TEMPRANGECHECK}
2127 result := CreatePalette(Pal^);
2134 (* TODO GLB_SDL_IMAGE
2135 {$IFDEF GLB_SDL_IMAGE}
2136 function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
2138 result := TStream(context^.unknown.data1).Seek(offset, whence);
2141 function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
2143 result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
2146 function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
2148 result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
2151 function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
2156 function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
2158 result := SDL_AllocRW;
2160 if result = nil then
2161 raise EglBitmapException.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
2163 result^.seek := glBitmapRWseek;
2164 result^.read := glBitmapRWread;
2165 result^.write := glBitmapRWwrite;
2166 result^.close := glBitmapRWclose;
2167 result^.unknown.data1 := Stream;
2173 function LoadTexture(Filename: String; var Texture: Cardinal{$IFDEF GLB_DELPHI}; LoadFromRes : Boolean; Instance: Cardinal{$ENDIF}): Boolean;
2175 glBitmap: TglBitmap2D;
2181 if Instance = 0 then
2182 Instance := HInstance;
2184 if (LoadFromRes) then
2185 glBitmap := TglBitmap2D.CreateFromResourceName(Instance, FileName)
2188 glBitmap := TglBitmap2D.Create(FileName);
2191 glBitmap.DeleteTextureOnFree := false;
2192 glBitmap.FreeDataAfterGenTexture := false;
2193 glBitmap.GenTexture(true);
2194 if (glBitmap.ID > 0) then begin
2195 Texture := glBitmap.ID;
2203 function LoadCubeMap(PositiveX, NegativeX, PositiveY, NegativeY, PositiveZ, NegativeZ: String; var Texture: Cardinal{$IFDEF GLB_DELPHI}; LoadFromRes : Boolean; Instance: Cardinal{$ENDIF}): Boolean;
2205 CM: TglBitmapCubeMap;
2210 if Instance = 0 then
2211 Instance := HInstance;
2214 CM := TglBitmapCubeMap.Create;
2216 CM.DeleteTextureOnFree := false;
2220 if (LoadFromRes) then
2221 CM.LoadFromResource(Instance, PositiveX)
2224 CM.LoadFromFile(PositiveX);
2225 CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X);
2228 if (LoadFromRes) then
2229 CM.LoadFromResource(Instance, NegativeX)
2232 CM.LoadFromFile(NegativeX);
2233 CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X);
2236 if (LoadFromRes) then
2237 CM.LoadFromResource(Instance, PositiveY)
2240 CM.LoadFromFile(PositiveY);
2241 CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y);
2244 if (LoadFromRes) then
2245 CM.LoadFromResource(Instance, NegativeY)
2248 CM.LoadFromFile(NegativeY);
2249 CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
2252 if (LoadFromRes) then
2253 CM.LoadFromResource(Instance, PositiveZ)
2256 CM.LoadFromFile(PositiveZ);
2257 CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
2260 if (LoadFromRes) then
2261 CM.LoadFromResource(Instance, NegativeZ)
2264 CM.LoadFromFile(NegativeZ);
2265 CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
2274 function LoadNormalMap(Size: Integer; var Texture: Cardinal): Boolean;
2276 NM: TglBitmapNormalMap;
2280 NM := TglBitmapNormalMap.Create;
2282 NM.DeleteTextureOnFree := false;
2283 NM.GenerateNormalMap(Size);
2293 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2294 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
2296 glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
2299 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2300 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
2302 glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
2305 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2306 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
2308 glBitmapDefaultMipmap := aValue;
2311 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2312 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
2314 glBitmapDefaultFormat := aFormat;
2317 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2318 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
2320 glBitmapDefaultFilterMin := aMin;
2321 glBitmapDefaultFilterMag := aMag;
2324 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2325 procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
2327 glBitmapDefaultWrapS := S;
2328 glBitmapDefaultWrapT := T;
2329 glBitmapDefaultWrapR := R;
2332 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2333 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
2335 result := glBitmapDefaultDeleteTextureOnFree;
2338 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2339 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
2341 result := glBitmapDefaultFreeDataAfterGenTextures;
2344 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2345 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
2347 result := glBitmapDefaultMipmap;
2350 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2351 function glBitmapGetDefaultFormat: TglBitmapFormat;
2353 result := glBitmapDefaultFormat;
2356 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2357 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
2359 aMin := glBitmapDefaultFilterMin;
2360 aMag := glBitmapDefaultFilterMag;
2363 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2364 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
2366 S := glBitmapDefaultWrapS;
2367 T := glBitmapDefaultWrapT;
2368 R := glBitmapDefaultWrapR;
2371 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2372 //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2373 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2374 function TFormatDescriptor.GetRedMask: UInt64;
2376 result := fRange.r shl fShift.r;
2379 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2380 function TFormatDescriptor.GetGreenMask: UInt64;
2382 result := fRange.g shl fShift.g;
2385 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2386 function TFormatDescriptor.GetBlueMask: UInt64;
2388 result := fRange.b shl fShift.b;
2391 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2392 function TFormatDescriptor.GetAlphaMask: UInt64;
2394 result := fRange.a shl fShift.a;
2397 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2398 function TFormatDescriptor.GetComponents: Integer;
2404 if (fRange.arr[i] > 0) then
2408 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2409 function TFormatDescriptor.GetSize(const aSize: TglBitmapPixelPosition): Integer;
2413 if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
2414 w := Max(1, aSize.X);
2415 h := Max(1, aSize.Y);
2416 result := GetSize(w, h);
2421 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2422 function TFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer;
2425 if (aWidth <= 0) or (aHeight <= 0) then
2427 result := Ceil(aWidth * aHeight * fPixelSize);
2430 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2431 function TFormatDescriptor.CreateMappingData: Pointer;
2436 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2437 procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
2442 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2443 function TFormatDescriptor.IsEmpty: Boolean;
2445 result := (fFormat = tfEmpty);
2448 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2449 function TFormatDescriptor.HasAlpha: Boolean;
2451 result := (fRange.a > 0);
2454 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2455 function TFormatDescriptor.MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: UInt64): Boolean;
2459 if (aRedMask = 0) and (aGreenMask = 0) and (aBlueMask = 0) and (aAlphaMask = 0) then
2460 raise EglBitmapException.Create('FormatCheckFormat - All Masks are 0');
2462 if (aRedMask <> RedMask) then
2464 if (aGreenMask <> GreenMask) then
2466 if (aBlueMask <> BlueMask) then
2468 if (aAlphaMask <> AlphaMask) then
2473 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2474 procedure TFormatDescriptor.PreparePixel(out aPixel: TglBitmapPixelData);
2476 FillChar(aPixel, SizeOf(aPixel), 0);
2477 aPixel.Data := fRange;
2478 aPixel.Range := fRange;
2479 aPixel.Format := fFormat;
2482 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2483 constructor TFormatDescriptor.Create;
2488 fWithAlpha := tfEmpty;
2489 fWithoutAlpha := tfEmpty;
2490 fRGBInverted := tfEmpty;
2491 fUncompressed := tfEmpty;
2493 fIsCompressed := false;
2496 fglInternalFormat := 0;
2499 FillChar(fRange, 0, SizeOf(fRange));
2500 FillChar(fShift, 0, SizeOf(fShift));
2503 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2504 //TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2505 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2506 procedure TfdAlpha_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2508 aData^ := aPixel.Data.a;
2512 procedure TfdAlpha_UB1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2517 aPixel.Data.a := aData^;
2521 constructor TfdAlpha_UB1.Create;
2526 fglFormat := GL_ALPHA;
2527 fglDataFormat := GL_UNSIGNED_BYTE;
2530 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2531 //TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2532 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2533 procedure TfdLuminance_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2535 aData^ := LuminanceWeight(aPixel);
2539 procedure TfdLuminance_UB1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2541 aPixel.Data.r := aData^;
2542 aPixel.Data.g := aData^;
2543 aPixel.Data.b := aData^;
2548 constructor TfdLuminance_UB1.Create;
2555 fglFormat := GL_LUMINANCE;
2556 fglDataFormat := GL_UNSIGNED_BYTE;
2559 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2560 //TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2561 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2562 procedure TfdUniversal_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2568 if (fRange.arr[i] > 0) then
2569 aData^ := aData^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2573 procedure TfdUniversal_UB1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2578 aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and fRange.arr[i];
2582 constructor TfdUniversal_UB1.Create;
2588 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2589 //TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2590 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2591 procedure TfdLuminanceAlpha_UB2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2593 inherited Map(aPixel, aData, aMapData);
2594 aData^ := aPixel.Data.a;
2598 procedure TfdLuminanceAlpha_UB2.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2600 inherited Unmap(aData, aPixel, aMapData);
2601 aPixel.Data.a := aData^;
2605 constructor TfdLuminanceAlpha_UB2.Create;
2611 fglFormat := GL_LUMINANCE_ALPHA;
2612 fglDataFormat := GL_UNSIGNED_BYTE;
2615 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2616 //TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2617 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2618 procedure TfdRGB_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2620 aData^ := aPixel.Data.r;
2622 aData^ := aPixel.Data.g;
2624 aData^ := aPixel.Data.b;
2628 procedure TfdRGB_UB3.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2630 aPixel.Data.r := aData^;
2632 aPixel.Data.g := aData^;
2634 aPixel.Data.b := aData^;
2639 constructor TfdRGB_UB3.Create;
2649 fglFormat := GL_RGB;
2650 fglDataFormat := GL_UNSIGNED_BYTE;
2653 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2654 //TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2655 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2656 procedure TfdBGR_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2658 aData^ := aPixel.Data.b;
2660 aData^ := aPixel.Data.g;
2662 aData^ := aPixel.Data.r;
2666 procedure TfdBGR_UB3.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2668 aPixel.Data.b := aData^;
2670 aPixel.Data.g := aData^;
2672 aPixel.Data.r := aData^;
2677 constructor TfdBGR_UB3.Create;
2686 fglFormat := GL_BGR;
2687 fglDataFormat := GL_UNSIGNED_BYTE;
2690 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2691 //TdfRGBA_UB4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2692 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2693 procedure TfdRGBA_UB4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2695 inherited Map(aPixel, aData, aMapData);
2696 aData^ := aPixel.Data.a;
2700 procedure TfdRGBA_UB4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2702 inherited Unmap(aData, aPixel, aMapData);
2703 aPixel.Data.a := aData^;
2707 constructor TfdRGBA_UB4.Create;
2713 fglFormat := GL_RGBA;
2714 fglDataFormat := GL_UNSIGNED_BYTE;
2717 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2718 //TfdBGRA_UB4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2719 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2720 procedure TfdBGRA_UB4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2722 inherited Map(aPixel, aData, aMapData);
2723 aData^ := aPixel.Data.a;
2727 procedure TfdBGRA_UB4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2729 inherited Unmap(aData, aPixel, aMapData);
2730 aPixel.Data.a := aData^;
2734 constructor TfdBGRA_UB4.Create;
2740 fglFormat := GL_BGRA;
2741 fglDataFormat := GL_UNSIGNED_BYTE;
2744 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2745 //TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2746 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2747 procedure TfdAlpha_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2749 PWord(aData)^ := aPixel.Data.a;
2753 procedure TfdAlpha_US1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2758 aPixel.Data.a := PWord(aData)^;
2762 constructor TfdAlpha_US1.Create;
2767 fglFormat := GL_ALPHA;
2768 fglDataFormat := GL_UNSIGNED_SHORT;
2771 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2772 //TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2773 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2774 procedure TfdLuminance_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2776 PWord(aData)^ := LuminanceWeight(aPixel);
2780 procedure TfdLuminance_US1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2782 aPixel.Data.r := PWord(aData)^;
2783 aPixel.Data.g := PWord(aData)^;
2784 aPixel.Data.b := PWord(aData)^;
2789 constructor TfdLuminance_US1.Create;
2796 fglFormat := GL_LUMINANCE;
2797 fglDataFormat := GL_UNSIGNED_SHORT;
2800 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2801 //TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2802 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2803 procedure TfdUniversal_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2809 if (fRange.arr[i] > 0) then
2810 PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2814 procedure TfdUniversal_US1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2819 aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and fRange.arr[i];
2823 constructor TfdUniversal_US1.Create;
2829 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2830 //TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2831 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2832 procedure TfdDepth_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2834 PWord(aData)^ := DepthWeight(aPixel);
2838 procedure TfdDepth_US1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2840 aPixel.Data.r := PWord(aData)^;
2841 aPixel.Data.g := PWord(aData)^;
2842 aPixel.Data.b := PWord(aData)^;
2847 constructor TfdDepth_US1.Create;
2854 fglFormat := GL_DEPTH_COMPONENT;
2855 fglDataFormat := GL_UNSIGNED_SHORT;
2858 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2859 //TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2860 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2861 procedure TfdLuminanceAlpha_US2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2863 inherited Map(aPixel, aData, aMapData);
2864 PWord(aData)^ := aPixel.Data.a;
2868 procedure TfdLuminanceAlpha_US2.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2870 inherited Unmap(aData, aPixel, aMapData);
2871 aPixel.Data.a := PWord(aData)^;
2875 constructor TfdLuminanceAlpha_US2.Create;
2881 fglFormat := GL_LUMINANCE_ALPHA;
2882 fglDataFormat := GL_UNSIGNED_SHORT;
2885 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2886 //TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2887 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2888 procedure TfdRGB_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2890 PWord(aData)^ := aPixel.Data.r;
2892 PWord(aData)^ := aPixel.Data.g;
2894 PWord(aData)^ := aPixel.Data.b;
2898 procedure TfdRGB_US3.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2900 aPixel.Data.r := PWord(aData)^;
2902 aPixel.Data.g := PWord(aData)^;
2904 aPixel.Data.b := PWord(aData)^;
2909 constructor TfdRGB_US3.Create;
2919 fglFormat := GL_RGB;
2920 fglDataFormat := GL_UNSIGNED_SHORT;
2923 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2924 //TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2925 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2926 procedure TfdBGR_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2928 PWord(aData)^ := aPixel.Data.b;
2930 PWord(aData)^ := aPixel.Data.g;
2932 PWord(aData)^ := aPixel.Data.r;
2936 procedure TfdBGR_US3.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2938 aPixel.Data.b := PWord(aData)^;
2940 aPixel.Data.g := PWord(aData)^;
2942 aPixel.Data.r := PWord(aData)^;
2947 constructor TfdBGR_US3.Create;
2957 fglFormat := GL_BGR;
2958 fglDataFormat := GL_UNSIGNED_SHORT;
2961 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2962 //TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2963 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2964 procedure TfdRGBA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2966 inherited Map(aPixel, aData, aMapData);
2967 PWord(aData)^ := aPixel.Data.a;
2971 procedure TfdRGBA_US4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2973 inherited Unmap(aData, aPixel, aMapData);
2974 aPixel.Data.a := PWord(aData)^;
2978 constructor TfdRGBA_US4.Create;
2984 fglFormat := GL_RGBA;
2985 fglDataFormat := GL_UNSIGNED_SHORT;
2988 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2989 //TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2990 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2991 procedure TfdBGRA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2993 inherited Map(aPixel, aData, aMapData);
2994 PWord(aData)^ := aPixel.Data.a;
2998 procedure TfdBGRA_US4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
3000 inherited Unmap(aData, aPixel, aMapData);
3001 aPixel.Data.a := PWord(aData)^;
3005 constructor TfdBGRA_US4.Create;
3011 fglFormat := GL_BGRA;
3012 fglDataFormat := GL_UNSIGNED_SHORT;
3015 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3016 //TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3017 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3018 procedure TfdUniversal_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3022 PCardinal(aData)^ := 0;
3024 if (fRange.arr[i] > 0) then
3025 PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
3029 procedure TfdUniversal_UI1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
3034 aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and fRange.arr[i];
3038 constructor TfdUniversal_UI1.Create;
3044 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3045 //TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3046 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3047 procedure TfdDepth_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3049 PCardinal(aData)^ := DepthWeight(aPixel);
3053 procedure TfdDepth_UI1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
3055 aPixel.Data.r := PCardinal(aData)^;
3056 aPixel.Data.g := PCardinal(aData)^;
3057 aPixel.Data.b := PCardinal(aData)^;
3062 constructor TfdDepth_UI1.Create;
3066 fRange.r := $FFFFFFFF;
3067 fRange.g := $FFFFFFFF;
3068 fRange.b := $FFFFFFFF;
3069 fglFormat := GL_DEPTH_COMPONENT;
3070 fglDataFormat := GL_UNSIGNED_INT;
3073 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3074 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3075 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3076 constructor TfdAlpha4.Create;
3079 fFormat := tfAlpha4;
3080 fWithAlpha := tfAlpha4;
3081 fglInternalFormat := GL_ALPHA4;
3084 constructor TfdAlpha8.Create;
3087 fFormat := tfAlpha8;
3088 fWithAlpha := tfAlpha8;
3089 fglInternalFormat := GL_ALPHA8;
3092 constructor TfdAlpha12.Create;
3095 fFormat := tfAlpha12;
3096 fWithAlpha := tfAlpha12;
3097 fglInternalFormat := GL_ALPHA12;
3100 constructor TfdAlpha16.Create;
3103 fFormat := tfAlpha16;
3104 fWithAlpha := tfAlpha16;
3105 fglInternalFormat := GL_ALPHA16;
3108 constructor TfdLuminance4.Create;
3111 fFormat := tfLuminance4;
3112 fWithAlpha := tfLuminance4Alpha4;
3113 fWithoutAlpha := tfLuminance4;
3114 fglInternalFormat := GL_LUMINANCE4;
3117 constructor TfdLuminance8.Create;
3120 fFormat := tfLuminance8;
3121 fWithAlpha := tfLuminance8Alpha8;
3122 fWithoutAlpha := tfLuminance8;
3123 fglInternalFormat := GL_LUMINANCE8;
3126 constructor TfdLuminance12.Create;
3129 fFormat := tfLuminance12;
3130 fWithAlpha := tfLuminance12Alpha12;
3131 fWithoutAlpha := tfLuminance12;
3132 fglInternalFormat := GL_LUMINANCE12;
3135 constructor TfdLuminance16.Create;
3138 fFormat := tfLuminance16;
3139 fWithAlpha := tfLuminance16Alpha16;
3140 fWithoutAlpha := tfLuminance16;
3141 fglInternalFormat := GL_LUMINANCE16;
3144 constructor TfdLuminance4Alpha4.Create;
3147 fFormat := tfLuminance4Alpha4;
3148 fWithAlpha := tfLuminance4Alpha4;
3149 fWithoutAlpha := tfLuminance4;
3150 fglInternalFormat := GL_LUMINANCE4_ALPHA4;
3153 constructor TfdLuminance6Alpha2.Create;
3156 fFormat := tfLuminance6Alpha2;
3157 fWithAlpha := tfLuminance6Alpha2;
3158 fWithoutAlpha := tfLuminance8;
3159 fglInternalFormat := GL_LUMINANCE6_ALPHA2;
3162 constructor TfdLuminance8Alpha8.Create;
3165 fFormat := tfLuminance8Alpha8;
3166 fWithAlpha := tfLuminance8Alpha8;
3167 fWithoutAlpha := tfLuminance8;
3168 fglInternalFormat := GL_LUMINANCE8_ALPHA8;
3171 constructor TfdLuminance12Alpha4.Create;
3174 fFormat := tfLuminance12Alpha4;
3175 fWithAlpha := tfLuminance12Alpha4;
3176 fWithoutAlpha := tfLuminance12;
3177 fglInternalFormat := GL_LUMINANCE12_ALPHA4;
3180 constructor TfdLuminance12Alpha12.Create;
3183 fFormat := tfLuminance12Alpha12;
3184 fWithAlpha := tfLuminance12Alpha12;
3185 fWithoutAlpha := tfLuminance12;
3186 fglInternalFormat := GL_LUMINANCE12_ALPHA12;
3189 constructor TfdLuminance16Alpha16.Create;
3192 fFormat := tfLuminance16Alpha16;
3193 fWithAlpha := tfLuminance16Alpha16;
3194 fWithoutAlpha := tfLuminance16;
3195 fglInternalFormat := GL_LUMINANCE16_ALPHA16;
3198 constructor TfdR3G3B2.Create;
3201 fFormat := tfR3G3B2;
3202 fWithAlpha := tfRGBA2;
3203 fWithoutAlpha := tfR3G3B2;
3210 fglFormat := GL_RGB;
3211 fglInternalFormat := GL_R3_G3_B2;
3212 fglDataFormat := GL_UNSIGNED_BYTE_2_3_3_REV;
3215 constructor TfdRGB4.Create;
3219 fWithAlpha := tfRGBA4;
3220 fWithoutAlpha := tfRGB4;
3221 fRGBInverted := tfBGR4;
3228 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3229 fglInternalFormat := GL_RGB4;
3230 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3233 constructor TfdR5G6B5.Create;
3236 fFormat := tfR5G6B5;
3237 fWithAlpha := tfRGBA4;
3238 fWithoutAlpha := tfR5G6B5;
3239 fRGBInverted := tfB5G6R5;
3246 fglFormat := GL_RGB;
3247 fglInternalFormat := GL_RGB565;
3248 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5_REV;
3251 constructor TfdRGB5.Create;
3255 fWithAlpha := tfRGB5A1;
3256 fWithoutAlpha := tfRGB5;
3257 fRGBInverted := tfBGR5;
3264 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3265 fglInternalFormat := GL_RGB5;
3266 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3269 constructor TfdRGB8.Create;
3273 fWithAlpha := tfRGBA8;
3274 fWithoutAlpha := tfRGB8;
3275 fRGBInverted := tfBGR8;
3276 fglInternalFormat := GL_RGB8;
3279 constructor TfdRGB10.Create;
3283 fWithAlpha := tfRGB10A2;
3284 fWithoutAlpha := tfRGB10;
3285 fRGBInverted := tfBGR10;
3292 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3293 fglInternalFormat := GL_RGB10;
3294 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3297 constructor TfdRGB12.Create;
3301 fWithAlpha := tfRGBA12;
3302 fWithoutAlpha := tfRGB12;
3303 fRGBInverted := tfBGR12;
3304 fglInternalFormat := GL_RGB12;
3307 constructor TfdRGB16.Create;
3311 fWithAlpha := tfRGBA16;
3312 fWithoutAlpha := tfRGB16;
3313 fRGBInverted := tfBGR16;
3314 fglInternalFormat := GL_RGB16;
3317 constructor TfdRGBA2.Create;
3321 fWithAlpha := tfRGBA2;
3322 fWithoutAlpha := tfR3G3B2;
3323 fRGBInverted := tfBGRA2;
3324 fglInternalFormat := GL_RGBA2;
3327 constructor TfdRGBA4.Create;
3331 fWithAlpha := tfRGBA4;
3332 fWithoutAlpha := tfRGB4;
3333 fRGBInverted := tfBGRA4;
3342 fglFormat := GL_RGBA;
3343 fglInternalFormat := GL_RGBA4;
3344 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3347 constructor TfdRGB5A1.Create;
3350 fFormat := tfRGB5A1;
3351 fWithAlpha := tfRGB5A1;
3352 fWithoutAlpha := tfRGB5;
3353 fRGBInverted := tfBGR5A1;
3362 fglFormat := GL_RGBA;
3363 fglInternalFormat := GL_RGB5_A1;
3364 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3367 constructor TfdRGBA8.Create;
3371 fWithAlpha := tfRGBA8;
3372 fWithoutAlpha := tfRGB8;
3373 fRGBInverted := tfBGRA8;
3374 fglInternalFormat := GL_RGBA8;
3377 constructor TfdRGB10A2.Create;
3380 fFormat := tfRGB10A2;
3381 fWithAlpha := tfRGB10A2;
3382 fWithoutAlpha := tfRGB10;
3383 fRGBInverted := tfBGR10A2;
3392 fglFormat := GL_RGBA;
3393 fglInternalFormat := GL_RGB10_A2;
3394 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3397 constructor TfdRGBA12.Create;
3400 fFormat := tfRGBA12;
3401 fWithAlpha := tfRGBA12;
3402 fWithoutAlpha := tfRGB12;
3403 fRGBInverted := tfBGRA12;
3404 fglInternalFormat := GL_RGBA12;
3407 constructor TfdRGBA16.Create;
3410 fFormat := tfRGBA16;
3411 fWithAlpha := tfRGBA16;
3412 fWithoutAlpha := tfRGB16;
3413 fRGBInverted := tfBGRA16;
3414 fglInternalFormat := GL_RGBA16;
3417 constructor TfdBGR4.Create;
3422 fWithAlpha := tfBGRA4;
3423 fWithoutAlpha := tfBGR4;
3424 fRGBInverted := tfRGB4;
3433 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3434 fglInternalFormat := GL_RGB4;
3435 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3438 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3439 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3440 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3441 constructor TfdB5G6R5.Create;
3444 fFormat := tfB5G6R5;
3445 fWithAlpha := tfBGRA4;
3446 fWithoutAlpha := tfB5G6R5;
3447 fRGBInverted := tfR5G6B5;
3454 fglFormat := GL_RGB; //B5G6R5 is only possible as R5G6B5 -> use reverted dataformat
3455 fglInternalFormat := GL_RGB8;
3456 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5;
3459 constructor TfdBGR5.Create;
3464 fWithAlpha := tfBGR5A1;
3465 fWithoutAlpha := tfBGR5;
3466 fRGBInverted := tfRGB5;
3475 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3476 fglInternalFormat := GL_RGB5;
3477 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3480 constructor TfdBGR8.Create;
3484 fWithAlpha := tfBGRA8;
3485 fWithoutAlpha := tfBGR8;
3486 fRGBInverted := tfRGB8;
3487 fglInternalFormat := GL_RGB8;
3490 constructor TfdBGR10.Create;
3494 fWithAlpha := tfBGR10A2;
3495 fWithoutAlpha := tfBGR10;
3496 fRGBInverted := tfRGB10;
3505 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3506 fglInternalFormat := GL_RGB10;
3507 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3510 constructor TfdBGR12.Create;
3514 fWithAlpha := tfBGRA12;
3515 fWithoutAlpha := tfBGR12;
3516 fRGBInverted := tfRGB12;
3517 fglInternalFormat := GL_RGB12;
3520 constructor TfdBGR16.Create;
3524 fWithAlpha := tfBGRA16;
3525 fWithoutAlpha := tfBGR16;
3526 fRGBInverted := tfRGB16;
3527 fglInternalFormat := GL_RGB16;
3530 constructor TfdBGRA2.Create;
3534 fWithAlpha := tfBGRA4;
3535 fWithoutAlpha := tfBGR4;
3536 fRGBInverted := tfRGBA2;
3537 fglInternalFormat := GL_RGBA2;
3540 constructor TfdBGRA4.Create;
3544 fWithAlpha := tfBGRA4;
3545 fWithoutAlpha := tfBGR4;
3546 fRGBInverted := tfRGBA4;
3555 fglFormat := GL_BGRA;
3556 fglInternalFormat := GL_RGBA4;
3557 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3560 constructor TfdBGR5A1.Create;
3563 fFormat := tfBGR5A1;
3564 fWithAlpha := tfBGR5A1;
3565 fWithoutAlpha := tfBGR5;
3566 fRGBInverted := tfRGB5A1;
3575 fglFormat := GL_BGRA;
3576 fglInternalFormat := GL_RGB5_A1;
3577 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3580 constructor TfdBGRA8.Create;
3584 fWithAlpha := tfBGRA8;
3585 fWithoutAlpha := tfBGR8;
3586 fRGBInverted := tfRGBA8;
3587 fglInternalFormat := GL_RGBA8;
3590 constructor TfdBGR10A2.Create;
3593 fFormat := tfBGR10A2;
3594 fWithAlpha := tfBGR10A2;
3595 fWithoutAlpha := tfBGR10;
3596 fRGBInverted := tfRGB10A2;
3605 fglFormat := GL_BGRA;
3606 fglInternalFormat := GL_RGB10_A2;
3607 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3610 constructor TfdBGRA12.Create;
3613 fFormat := tfBGRA12;
3614 fWithAlpha := tfBGRA12;
3615 fWithoutAlpha := tfBGR12;
3616 fRGBInverted := tfRGBA12;
3617 fglInternalFormat := GL_RGBA12;
3620 constructor TfdBGRA16.Create;
3623 fFormat := tfBGRA16;
3624 fWithAlpha := tfBGRA16;
3625 fWithoutAlpha := tfBGR16;
3626 fRGBInverted := tfRGBA16;
3627 fglInternalFormat := GL_RGBA16;
3630 constructor TfdDepth16.Create;
3633 fFormat := tfDepth16;
3634 fWithAlpha := tfEmpty;
3635 fWithoutAlpha := tfDepth16;
3636 fglInternalFormat := GL_DEPTH_COMPONENT16;
3639 constructor TfdDepth24.Create;
3642 fFormat := tfDepth24;
3643 fWithAlpha := tfEmpty;
3644 fWithoutAlpha := tfDepth24;
3645 fglInternalFormat := GL_DEPTH_COMPONENT24;
3648 constructor TfdDepth32.Create;
3651 fFormat := tfDepth32;
3652 fWithAlpha := tfEmpty;
3653 fWithoutAlpha := tfDepth32;
3654 fglInternalFormat := GL_DEPTH_COMPONENT32;
3657 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3658 //TfdS3tcDtx1RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3659 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3660 procedure TfdS3tcDtx1RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3662 raise EglBitmapException.Create('mapping for compressed formats is not supported');
3665 procedure TfdS3tcDtx1RGBA.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
3667 raise EglBitmapException.Create('mapping for compressed formats is not supported');
3670 constructor TfdS3tcDtx1RGBA.Create;
3673 fFormat := tfS3tcDtx1RGBA;
3674 fWithAlpha := tfS3tcDtx1RGBA;
3675 fUncompressed := tfRGB5A1;
3677 fIsCompressed := true;
3678 fglFormat := GL_COMPRESSED_RGBA;
3679 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
3680 fglDataFormat := GL_UNSIGNED_BYTE;
3683 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3684 //TfdS3tcDtx3RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3685 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3686 procedure TfdS3tcDtx3RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3688 raise EglBitmapException.Create('mapping for compressed formats is not supported');
3691 procedure TfdS3tcDtx3RGBA.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
3693 raise EglBitmapException.Create('mapping for compressed formats is not supported');
3696 constructor TfdS3tcDtx3RGBA.Create;
3699 fFormat := tfS3tcDtx3RGBA;
3700 fWithAlpha := tfS3tcDtx3RGBA;
3701 fUncompressed := tfRGBA8;
3703 fIsCompressed := true;
3704 fglFormat := GL_COMPRESSED_RGBA;
3705 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
3706 fglDataFormat := GL_UNSIGNED_BYTE;
3709 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3710 //TfdS3tcDtx5RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3711 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3712 procedure TfdS3tcDtx5RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3714 raise EglBitmapException.Create('mapping for compressed formats is not supported');
3717 procedure TfdS3tcDtx5RGBA.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
3719 raise EglBitmapException.Create('mapping for compressed formats is not supported');
3722 constructor TfdS3tcDtx5RGBA.Create;
3725 fFormat := tfS3tcDtx3RGBA;
3726 fWithAlpha := tfS3tcDtx3RGBA;
3727 fUncompressed := tfRGBA8;
3729 fIsCompressed := true;
3730 fglFormat := GL_COMPRESSED_RGBA;
3731 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
3732 fglDataFormat := GL_UNSIGNED_BYTE;
3735 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3736 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3737 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3738 class procedure TFormatDescriptor.Init;
3740 if not Assigned(FormatDescriptorCS) then
3741 FormatDescriptorCS := TCriticalSection.Create;
3744 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3745 class function TFormatDescriptor.Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
3747 FormatDescriptorCS.Enter;
3749 result := FormatDescriptors[aFormat];
3750 if not Assigned(result) then begin
3751 result := FORMAT_DESCRIPTOR_CLASSES[aFormat].Create;
3752 FormatDescriptors[aFormat] := result;
3755 FormatDescriptorCS.Leave;
3759 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3760 class function TFormatDescriptor.GetWithAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
3762 result := Get(Get(aFormat).WithAlpha);
3765 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3766 class procedure TFormatDescriptor.Clear;
3770 FormatDescriptorCS.Enter;
3772 for f := low(FormatDescriptors) to high(FormatDescriptors) do
3773 FreeAndNil(FormatDescriptors[f]);
3775 FormatDescriptorCS.Leave;
3779 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3780 class procedure TFormatDescriptor.Finalize;
3783 FreeAndNil(FormatDescriptorCS);
3786 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3787 //TBitfieldFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3788 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3789 procedure TbmpBitfieldFormat.SetRedMask(const aValue: UInt64);
3791 Update(aValue, fRange.r, fShift.r);
3794 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3795 procedure TbmpBitfieldFormat.SetGreenMask(const aValue: UInt64);
3797 Update(aValue, fRange.g, fShift.g);
3800 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3801 procedure TbmpBitfieldFormat.SetBlueMask(const aValue: UInt64);
3803 Update(aValue, fRange.b, fShift.b);
3806 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3807 procedure TbmpBitfieldFormat.SetAlphaMask(const aValue: UInt64);
3809 Update(aValue, fRange.a, fShift.a);
3812 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3813 procedure TbmpBitfieldFormat.Update(aMask: UInt64; out aRange: Cardinal; out
3820 while (aMask > 0) and ((aMask and 1) = 0) do begin
3822 aMask := aMask shr 1;
3825 while (aMask > 0) do begin
3826 aRange := aRange shl 1;
3827 aMask := aMask shr 1;
3831 fPixelSize := Round(GetTopMostBit(RedMask or GreenMask or BlueMask or AlphaMask) / 8);
3834 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3835 procedure TbmpBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3843 ((aPixel.Data.r and fRange.r) shl fShift.r) or
3844 ((aPixel.Data.g and fRange.g) shl fShift.g) or
3845 ((aPixel.Data.b and fRange.b) shl fShift.b) or
3846 ((aPixel.Data.a and fRange.a) shl fShift.a);
3847 s := Round(fPixelSize);
3850 2: PWord(aData)^ := data;
3851 4: PCardinal(aData)^ := data;
3852 8: PUInt64(aData)^ := data;
3854 raise EglBitmapException.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
3859 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3860 procedure TbmpBitfieldFormat.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
3867 s := Round(fPixelSize);
3870 2: data := PWord(aData)^;
3871 4: data := PCardinal(aData)^;
3872 8: data := PUInt64(aData)^;
3874 raise EglBitmapException.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
3877 aPixel.Data.arr[i] := (data shr fShift.arr[i]) and fRange.arr[i];
3881 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3882 //TColorTableFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3883 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3884 procedure TbmpColorTableFormat.CreateColorTable;
3890 if not (Format in [tfLuminance4, tfLuminance8, tfR3G3B2]) then
3891 raise EglBitmapException.Create(UNSUPPORTED_FORMAT);
3893 if (Format = tfLuminance4) then
3894 SetLength(fColorTable, 16)
3896 SetLength(fColorTable, 256);
3900 for i := 0 to High(fColorTable) do begin
3901 fColorTable[i].r := 16 * i;
3902 fColorTable[i].g := 16 * i;
3903 fColorTable[i].b := 16 * i;
3904 fColorTable[i].a := 0;
3909 for i := 0 to High(fColorTable) do begin
3910 fColorTable[i].r := i;
3911 fColorTable[i].g := i;
3912 fColorTable[i].b := i;
3913 fColorTable[i].a := 0;
3918 for i := 0 to High(fColorTable) do begin
3919 fColorTable[i].r := Round(((i shr Shift.r) and Range.r) / Range.r * 255);
3920 fColorTable[i].g := Round(((i shr Shift.g) and Range.g) / Range.g * 255);
3921 fColorTable[i].b := Round(((i shr Shift.b) and Range.b) / Range.b * 255);
3922 fColorTable[i].a := 0;
3928 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3929 procedure TbmpColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3933 if not (Format in [tfLuminance4, tfLuminance8, tfR3G3B2]) then
3934 raise EglBitmapException.Create(UNSUPPORTED_FORMAT);
3938 if (aMapData = nil) then
3940 d := LuminanceWeight(aPixel) and Range.r;
3941 aData^ := aData^ or (d shl (4 - PtrInt(aMapData)));
3943 if (PtrInt(aMapData) >= 8) then begin
3950 aData^ := LuminanceWeight(aPixel) and Range.r;
3956 ((aPixel.Data.r and Range.r) shl Shift.r) or
3957 ((aPixel.Data.g and Range.g) shl Shift.g) or
3958 ((aPixel.Data.b and Range.b) shl Shift.b));
3964 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3965 procedure TbmpColorTableFormat.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
3974 s := Trunc(fPixelSize);
3975 f := fPixelSize - s;
3976 bits := Round(8 * f);
3978 0: idx := (aData^ shr (8 - bits - PtrInt(aMapData))) and ((1 shl bits) - 1);
3980 2: idx := PWord(aData)^;
3981 4: idx := PCardinal(aData)^;
3982 8: idx := PUInt64(aData)^;
3984 raise EglBitmapException.CreateFmt('invalid pixel size: %.3f', [fPixelSize]);
3986 if (idx >= Length(fColorTable)) then
3987 raise EglBitmapException.CreateFmt('invalid color index: %d', [idx]);
3988 with fColorTable[idx] do begin
3994 inc(aMapData, bits);
3995 if (PtrInt(aMapData) >= 8) then begin
4002 destructor TbmpColorTableFormat.Destroy;
4004 SetLength(fColorTable, 0);
4008 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4009 //TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4010 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4011 procedure glBitmapConvertPixel(var aPixel: TglBitmapPixelData; const aSourceFD, aDestFD: TFormatDescriptor);
4015 for i := 0 to 3 do begin
4016 if (aSourceFD.Range.arr[i] <> aDestFD.Range.arr[i]) then begin
4017 if (aSourceFD.Range.arr[i] > 0) then
4018 aPixel.Data.arr[i] := Round(aPixel.Data.arr[i] / aSourceFD.Range.arr[i] * aDestFD.Range.arr[i])
4020 aPixel.Data.arr[i] := aDestFD.Range.arr[i];
4025 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4026 procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
4028 with aFuncRec do begin
4029 if (Source.Range.r > 0) then
4030 Dest.Data.r := Source.Data.r;
4031 if (Source.Range.g > 0) then
4032 Dest.Data.g := Source.Data.g;
4033 if (Source.Range.b > 0) then
4034 Dest.Data.b := Source.Data.b;
4035 if (Source.Range.a > 0) then
4036 Dest.Data.a := Source.Data.a;
4040 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4041 procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
4045 with aFuncRec do begin
4047 if (Source.Range.arr[i] > 0) then
4048 Dest.Data.arr[i] := Round(Dest.Range.arr[i] * Source.Data.arr[i] / Source.Range.arr[i]);
4053 TShiftData = packed record
4055 0: (r, g, b, a: SmallInt);
4056 1: (arr: array[0..3] of SmallInt);
4058 PShiftData = ^TShiftData;
4060 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4061 procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
4067 if (Source.Range.arr[i] > 0) then
4068 Dest.Data.arr[i] := Source.Data.arr[i] shr PShiftData(Args)^.arr[i];
4071 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4072 procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
4074 with aFuncRec do begin
4075 Dest.Data := Source.Data;
4076 if (Args and $1 > 0) then begin
4077 Dest.Data.r := Dest.Data.r xor Dest.Range.r;
4078 Dest.Data.g := Dest.Data.g xor Dest.Range.g;
4079 Dest.Data.b := Dest.Data.b xor Dest.Range.b;
4081 if (Args and $2 > 0) then begin
4082 Dest.Data.a := Dest.Data.a xor Dest.Range.a;
4087 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4088 procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
4092 with aFuncRec do begin
4094 Dest.Data.arr[i] := PglBitmapPixelData(Args)^.Data.arr[i];
4098 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4099 procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4103 with FuncRec do begin
4104 if (FuncRec.Args = 0) then begin //source has no alpha
4106 Source.Data.r / Source.Range.r * ALPHA_WEIGHT_R +
4107 Source.Data.g / Source.Range.g * ALPHA_WEIGHT_G +
4108 Source.Data.b / Source.Range.b * ALPHA_WEIGHT_B;
4109 Dest.Data.a := Round(Dest.Range.a * Temp);
4111 Dest.Data.a := Round(Source.Data.a / Source.Range.a * Dest.Range.a);
4115 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4116 procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4118 PglBitmapPixelData = ^TglBitmapPixelData;
4120 with FuncRec do begin
4121 Dest.Data.r := Source.Data.r;
4122 Dest.Data.g := Source.Data.g;
4123 Dest.Data.b := Source.Data.b;
4125 with PglBitmapPixelData(Args)^ do
4126 if ((Dest.Data.r <= Data.r) and (Dest.Data.r >= Range.r) and
4127 (Dest.Data.g <= Data.g) and (Dest.Data.g >= Range.g) and
4128 (Dest.Data.b <= Data.b) and (Dest.Data.b >= Range.b)) then
4131 Dest.Data.a := Dest.Range.a;
4135 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4136 procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4138 PglBitmapPixelData = ^TglBitmapPixelData;
4140 with FuncRec do begin
4141 Dest.Data.r := Source.Data.r;
4142 Dest.Data.g := Source.Data.g;
4143 Dest.Data.b := Source.Data.b;
4144 Dest.Data.a := PCardinal(Args)^;
4148 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4149 procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
4152 TRGBPix = array [0..2] of byte;
4156 while aWidth > 0 do begin
4157 Temp := PRGBPix(aData)^[0];
4158 PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
4159 PRGBPix(aData)^[2] := Temp;
4169 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4170 //TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4171 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4172 function TglBitmap.GetWidth: Integer;
4174 if (ffX in fDimension.Fields) then
4175 result := fDimension.X
4180 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4181 function TglBitmap.GetHeight: Integer;
4183 if (ffY in fDimension.Fields) then
4184 result := fDimension.Y
4189 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4190 function TglBitmap.GetFileWidth: Integer;
4192 result := Max(1, Width);
4195 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4196 function TglBitmap.GetFileHeight: Integer;
4198 result := Max(1, Height);
4201 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4202 procedure TglBitmap.SetCustomData(const aValue: Pointer);
4204 if fCustomData = aValue then
4206 fCustomData := aValue;
4209 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4210 procedure TglBitmap.SetCustomName(const aValue: String);
4212 if fCustomName = aValue then
4214 fCustomName := aValue;
4217 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4218 procedure TglBitmap.SetCustomNameW(const aValue: WideString);
4220 if fCustomNameW = aValue then
4222 fCustomNameW := aValue;
4225 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4226 procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
4228 if fDeleteTextureOnFree = aValue then
4230 fDeleteTextureOnFree := aValue;
4233 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4234 procedure TglBitmap.SetFormat(const aValue: TglBitmapFormat);
4236 if fFormat = aValue then
4238 if TFormatDescriptor.Get(Format).PixelSize <> TFormatDescriptor.Get(aValue).PixelSize then
4239 raise EglBitmapUnsupportedFormatFormat.Create('SetInternalFormat - ' + UNSUPPORTED_FORMAT);
4240 SetDataPointer(Data, aValue, Width, Height);
4243 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4244 procedure TglBitmap.SetFreeDataAfterGenTexture(const aValue: Boolean);
4246 if fFreeDataAfterGenTexture = aValue then
4248 fFreeDataAfterGenTexture := aValue;
4251 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4252 procedure TglBitmap.SetID(const aValue: Cardinal);
4254 if fID = aValue then
4259 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4260 procedure TglBitmap.SetMipMap(const aValue: TglBitmapMipMap);
4262 if fMipMap = aValue then
4267 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4268 procedure TglBitmap.SetTarget(const aValue: Cardinal);
4270 if fTarget = aValue then
4275 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4276 procedure TglBitmap.SetAnisotropic(const aValue: Integer);
4278 MaxAnisotropic: Integer;
4280 fAnisotropic := aValue;
4281 if (ID > 0) then begin
4282 if GL_EXT_texture_filter_anisotropic then begin
4283 if fAnisotropic > 0 then begin
4285 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
4286 if aValue > MaxAnisotropic then
4287 fAnisotropic := MaxAnisotropic;
4288 glTexParameteri(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, fAnisotropic);
4296 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4297 procedure TglBitmap.CreateID;
4300 glDeleteTextures(1, @fID);
4301 glGenTextures(1, @fID);
4305 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4306 procedure TglBitmap.SetupParameters(var aBuildWithGlu: Boolean);
4308 // Set Up Parameters
4309 SetWrap(fWrapS, fWrapT, fWrapR);
4310 SetFilter(fFilterMin, fFilterMag);
4311 SetAnisotropic(fAnisotropic);
4312 SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
4314 // Mip Maps Generation Mode
4315 aBuildWithGlu := false;
4316 if (MipMap = mmMipmap) then begin
4317 if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
4318 glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
4320 aBuildWithGlu := true;
4321 end else if (MipMap = mmMipmapGlu) then
4322 aBuildWithGlu := true;
4325 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4326 procedure TglBitmap.SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
4327 const aWidth: Integer; const aHeight: Integer);
4331 if (Data <> aData) then begin
4332 if (Assigned(Data)) then
4337 FillChar(fDimension, SizeOf(fDimension), 0);
4338 if not Assigned(fData) then begin
4343 if aWidth <> -1 then begin
4344 fDimension.Fields := fDimension.Fields + [ffX];
4345 fDimension.X := aWidth;
4348 if aHeight <> -1 then begin
4349 fDimension.Fields := fDimension.Fields + [ffY];
4350 fDimension.Y := aHeight;
4353 s := TFormatDescriptor.Get(aFormat).PixelSize;
4355 fPixelSize := Ceil(s);
4356 fRowSize := Ceil(s * aWidth);
4360 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4361 function TglBitmap.FlipHorz: Boolean;
4366 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4367 function TglBitmap.FlipVert: Boolean;
4372 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4373 //TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4374 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4375 procedure TglBitmap.AfterConstruction;
4377 inherited AfterConstruction;
4381 fIsResident := false;
4383 fFormat := glBitmapGetDefaultFormat;
4384 fMipMap := glBitmapDefaultMipmap;
4385 fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
4386 fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
4388 glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
4389 glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
4392 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4393 procedure TglBitmap.BeforeDestruction;
4395 SetDataPointer(nil, tfEmpty);
4396 if (fID > 0) and fDeleteTextureOnFree then
4397 glDeleteTextures(1, @fID);
4398 inherited BeforeDestruction;
4401 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4402 procedure TglBitmap.LoadFromFile(const aFilename: String);
4406 if not FileExists(aFilename) then
4407 raise EglBitmapException.Create('file does not exist: ' + aFilename);
4408 fFilename := aFilename;
4409 fs := TFileStream.Create(fFilename, fmOpenRead);
4418 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4419 procedure TglBitmap.LoadFromStream(const aStream: TStream);
4421 {$IFDEF GLB_SUPPORT_PNG_READ}
4422 if not LoadPNG(aStream) then
4424 {$IFDEF GLB_SUPPORT_JPEG_READ}
4425 if not LoadJPEG(aStream) then
4427 if not LoadDDS(aStream) then
4428 if not LoadTGA(aStream) then
4429 if not LoadBMP(aStream) then
4430 raise EglBitmapException.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
4433 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4434 procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
4435 const aFormat: TglBitmapFormat; const aArgs: PtrInt);
4440 size := TFormatDescriptor.Get(aFormat).GetSize(aSize);
4441 GetMem(tmpData, size);
4443 FillChar(tmpData^, size, #$FF);
4444 SetDataPointer(tmpData, aFormat, aSize.X, aSize.Y);
4449 AddFunc(Self, aFunc, false, Format, aArgs);
4453 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4454 procedure TglBitmap.LoadFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil);
4456 rs: TResourceStream;
4461 if not Assigned(ResType) then begin
4462 TempPos := Pos('.', Resource);
4463 ResTypeStr := UpperCase(Copy(Resource, TempPos + 1, Length(Resource) - TempPos));
4464 Resource := UpperCase(Copy(Resource, 0, TempPos -1));
4465 TempResType := PChar(ResTypeStr);
4467 TempResType := ResType
4469 rs := TResourceStream.Create(Instance, Resource, TempResType);
4477 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4478 procedure TglBitmap.LoadFromResourceID(const sInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
4480 rs: TResourceStream;
4482 rs := TResourceStream.CreateFromID(Instance, ResourceID, ResType);
4491 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4492 procedure TglBitmap.SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
4496 fs := TFileStream.Create(aFileName, fmCreate);
4499 SaveToStream(fs, aFileType);
4505 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4506 procedure TglBitmap.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
4509 {$IFDEF GLB_SUPPORT_PNG_WRITE}
4510 ftPNG: SavePng(aStream);
4512 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
4513 ftJPEG: SaveJPEG(aStream);
4515 ftDDS: SaveDDS(aStream);
4516 ftTGA: SaveTGA(aStream);
4517 ftBMP: SaveBMP(aStream);
4521 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4522 function TglBitmap.AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: PtrInt): Boolean;
4524 result := AddFunc(Self, aFunc, aCreateTemp, Format, aArgs);
4527 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4528 function TglBitmap.AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
4529 const aFormat: TglBitmapFormat; const aArgs: PtrInt): Boolean;
4531 DestData, TmpData, SourceData: pByte;
4532 TempHeight, TempWidth: Integer;
4533 SourceFD, DestFD: TFormatDescriptor;
4534 SourceMD, DestMD: Pointer;
4536 FuncRec: TglBitmapFunctionRec;
4538 Assert(Assigned(Data));
4539 Assert(Assigned(aSource));
4540 Assert(Assigned(aSource.Data));
4543 if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
4544 SourceFD := TFormatDescriptor.Get(aSource.Format);
4545 DestFD := TFormatDescriptor.Get(aFormat);
4547 // inkompatible Formats so CreateTemp
4548 if (SourceFD.PixelSize <> DestFD.PixelSize) then
4549 aCreateTemp := true;
4552 TempHeight := Max(1, aSource.Height);
4553 TempWidth := Max(1, aSource.Width);
4555 FuncRec.Sender := Self;
4556 FuncRec.Args := aArgs;
4559 if aCreateTemp then begin
4560 GetMem(TmpData, TFormatDescriptor.Get(aFormat).GetSize(TempWidth, TempHeight));
4561 DestData := TmpData;
4566 SourceFD.PreparePixel(FuncRec.Source);
4567 DestFD.PreparePixel (FuncRec.Dest);
4569 SourceMD := SourceFD.CreateMappingData;
4570 DestMD := DestFD.CreateMappingData;
4572 FuncRec.Size := aSource.Dimension;
4573 FuncRec.Position.Fields := FuncRec.Size.Fields;
4576 SourceData := aSource.Data;
4577 FuncRec.Position.Y := 0;
4578 while FuncRec.Position.Y < TempHeight do begin
4579 FuncRec.Position.X := 0;
4580 while FuncRec.Position.X < TempWidth do begin
4581 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
4583 DestFD.Map(FuncRec.Dest, DestData, DestMD);
4584 inc(FuncRec.Position.X);
4586 inc(FuncRec.Position.Y);
4589 // Updating Image or InternalFormat
4591 SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height)
4592 else if (aFormat <> fFormat) then
4597 SourceFD.FreeMappingData(SourceMD);
4598 DestFD.FreeMappingData(DestMD);
4609 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4610 function TglBitmap.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
4612 Row, RowSize: Integer;
4613 SourceData, TmpData: PByte;
4615 Pix: TglBitmapPixelData;
4616 FormatDesc: TglBitmapFormatDescriptor;
4618 function GetRowPointer(Row: Integer): pByte;
4620 result := Surface.pixels;
4621 Inc(result, Row * RowSize);
4628 if not FormatIsUncompressed(InternalFormat) then
4629 raise EglBitmapUnsupportedInternalFormat.Create('AssignToSurface - ' + UNSUPPORTED_INTERNAL_FORMAT);
4632 FormatDesc := FORMAT_DESCRIPTORS[Format];
4633 if Assigned(Data) then begin
4634 case Trunc(FormatDesc.GetSize) of
4640 raise EglBitmapException.Create('AssignToSurface - ' + UNSUPPORTED_INTERNAL_FORMAT);
4642 FormatDesc.PreparePixel(Pix);
4643 with Pix.PixelDesc do
4644 Surface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
4645 RedRange shl RedShift, GreenRange shl GreenShift, BlueRange shl BlueShift, AlphaRange shl AlphaShift);
4648 RowSize := Ceil(FileWidth * FormatDesc.GetSize);
4650 for Row := 0 to FileHeight -1 do begin
4651 TmpData := GetRowPointer(Row);
4652 if Assigned(TmpData) then begin
4653 Move(SourceData^, TmpData^, RowSize);
4654 inc(SourceData, RowSize);
4661 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4662 function TglBitmap.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
4664 pSource, pData, pTempData: PByte;
4665 Row, RowSize, TempWidth, TempHeight: Integer;
4666 IntFormat, f: TglBitmapInternalFormat;
4667 FormatDesc: TglBitmapFormatDescriptor;
4669 function GetRowPointer(Row: Integer): pByte;
4671 result := Surface^.pixels;
4672 Inc(result, Row * RowSize);
4677 if (Assigned(Surface)) then begin
4678 with Surface^.format^ do begin
4679 IntFormat := tfEmpty;
4680 for f := Low(f) to High(f) do begin
4681 if FORMAT_DESCRIPTORS[f].MaskMatch(RMask, GMask, BMask, AMask) then begin
4686 if (IntFormat = tfEmpty) then
4687 raise EglBitmapException.Create('AssignFromSurface - Invalid Pixelformat.');
4690 FormatDesc := FORMAT_DESCRIPTORS[IntFormat];
4691 TempWidth := Surface^.w;
4692 TempHeight := Surface^.h;
4693 RowSize := Trunc(TempWidth * FormatDesc.GetSize);
4694 GetMem(pData, TempHeight * RowSize);
4697 for Row := 0 to TempHeight -1 do begin
4698 pSource := GetRowPointer(Row);
4699 if (Assigned(pSource)) then begin
4700 Move(pSource^, pTempData^, RowSize);
4701 Inc(pTempData, RowSize);
4704 SetDataPointer(pData, IntFormat, TempWidth, TempHeight);
4713 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4714 function TglBitmap.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
4716 Row, Col, AlphaInterleave: Integer;
4717 pSource, pDest: PByte;
4719 function GetRowPointer(Row: Integer): pByte;
4721 result := aSurface.pixels;
4722 Inc(result, Row * Width);
4727 if Assigned(Data) then begin
4728 if Format in [tfAlpha8, tfLuminance8Alpha8, tfBGRA8, tfRGBA8] then begin
4729 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
4731 AlphaInterleave := 0;
4734 AlphaInterleave := 1;
4736 AlphaInterleave := 3;
4740 for Row := 0 to Height -1 do begin
4741 pDest := GetRowPointer(Row);
4742 if Assigned(pDest) then begin
4743 for Col := 0 to Width -1 do begin
4744 Inc(pSource, AlphaInterleave);
4756 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4757 function TglBitmap.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4761 bmp := TglBitmap2D.Create;
4763 bmp.AssignFromSurface(Surface);
4764 result := AddAlphaFromGlBitmap(bmp, Func, CustomData);
4772 //TODO rework & test
4773 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4774 function TglBitmap.AssignToBitmap(const aBitmap: TBitmap): Boolean;
4777 pSource, pData: PByte;
4780 if Assigned(Data) then begin
4781 if Assigned(aBitmap) then begin
4782 aBitmap.Width := Width;
4783 aBitmap.Height := Height;
4786 tfAlpha8, ifLuminance, ifDepth8:
4788 Bitmap.PixelFormat := pf8bit;
4789 Bitmap.Palette := CreateGrayPalette;
4792 Bitmap.PixelFormat := pf15bit;
4794 Bitmap.PixelFormat := pf16bit;
4796 Bitmap.PixelFormat := pf24bit;
4798 Bitmap.PixelFormat := pf32bit;
4800 raise EglBitmapException.Create('AssignToBitmap - Invalid Pixelformat.');
4804 for Row := 0 to FileHeight -1 do begin
4805 pData := Bitmap.Scanline[Row];
4807 Move(pSource^, pData^, fRowSize);
4808 Inc(pSource, fRowSize);
4810 // swap RGB(A) to BGR(A)
4811 if InternalFormat in [ifRGB8, ifRGBA8] then
4812 SwapRGB(pData, FileWidth, InternalFormat = ifRGBA8);
4820 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4821 function TglBitmap.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
4823 pSource, pData, pTempData: PByte;
4824 Row, RowSize, TempWidth, TempHeight: Integer;
4825 IntFormat: TglBitmapInternalFormat;
4829 if (Assigned(Bitmap)) then begin
4830 case Bitmap.PixelFormat of
4832 IntFormat := ifLuminance;
4834 IntFormat := ifRGB5A1;
4836 IntFormat := ifR5G6B5;
4838 IntFormat := ifBGR8;
4840 IntFormat := ifBGRA8;
4842 raise EglBitmapException.Create('AssignFromBitmap - Invalid Pixelformat.');
4845 TempWidth := Bitmap.Width;
4846 TempHeight := Bitmap.Height;
4848 RowSize := Trunc(TempWidth * FormatGetSize(IntFormat));
4850 GetMem(pData, TempHeight * RowSize);
4854 for Row := 0 to TempHeight -1 do begin
4855 pSource := Bitmap.Scanline[Row];
4857 if (Assigned(pSource)) then begin
4858 Move(pSource^, pTempData^, RowSize);
4859 Inc(pTempData, RowSize);
4863 SetDataPointer(pData, IntFormat, TempWidth, TempHeight);
4873 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4874 function TglBitmap.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
4876 Row, Col, AlphaInterleave: Integer;
4877 pSource, pDest: PByte;
4881 if Assigned(Data) then begin
4882 if InternalFormat in [ifAlpha, ifLuminanceAlpha, ifRGBA8, ifBGRA8] then begin
4883 if Assigned(Bitmap) then begin
4884 Bitmap.PixelFormat := pf8bit;
4885 Bitmap.Palette := CreateGrayPalette;
4886 Bitmap.Width := Width;
4887 Bitmap.Height := Height;
4889 case InternalFormat of
4891 AlphaInterleave := 1;
4893 AlphaInterleave := 3;
4895 AlphaInterleave := 0;
4901 for Row := 0 to Height -1 do begin
4902 pDest := Bitmap.Scanline[Row];
4904 if Assigned(pDest) then begin
4905 for Col := 0 to Width -1 do begin
4906 Inc(pSource, AlphaInterleave);
4920 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4921 function TglBitmap.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4925 tex := TglBitmap2D.Create;
4927 tex.AssignFromBitmap(Bitmap);
4928 result := AddAlphaFromglBitmap(tex, Func, CustomData);
4934 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4935 function TglBitmap.AddAlphaFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar;
4936 const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4938 RS: TResourceStream;
4943 if Assigned(ResType) then
4944 TempResType := ResType
4947 TempPos := Pos('.', Resource);
4948 ResTypeStr := UpperCase(Copy(Resource, TempPos + 1, Length(Resource) - TempPos));
4949 Resource := UpperCase(Copy(Resource, 0, TempPos -1));
4950 TempResType := PChar(ResTypeStr);
4953 RS := TResourceStream.Create(Instance, Resource, TempResType);
4955 result := AddAlphaFromStream(RS, Func, CustomData);
4961 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4962 function TglBitmap.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
4963 const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4965 RS: TResourceStream;
4967 RS := TResourceStream.CreateFromID(Instance, ResourceID, ResType);
4969 result := AddAlphaFromStream(RS, Func, CustomData);
4976 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4977 function TglBitmap.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4980 if not FormatIsUncompressed(InternalFormat) then
4981 raise EglBitmapUnsupportedFormatFormat.Create('AddAlphaFromFunc - ' + UNSUPPORTED_FORMAT);
4983 result := AddFunc(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs);
4986 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4987 function TglBitmap.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4991 FS := TFileStream.Create(FileName, fmOpenRead);
4993 result := AddAlphaFromStream(FS, aFunc, aArgs);
4999 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5000 function TglBitmap.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
5004 tex := TglBitmap2D.Create(aStream);
5006 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5012 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5013 function TglBitmap.AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
5015 DestData, DestData2, SourceData: pByte;
5016 TempHeight, TempWidth: Integer;
5017 SourceFD, DestFD: TFormatDescriptor;
5018 SourceMD, DestMD, DestMD2: Pointer;
5020 FuncRec: TglBitmapFunctionRec;
5024 Assert(Assigned(Data));
5025 Assert(Assigned(aBitmap));
5026 Assert(Assigned(aBitmap.Data));
5028 if ((aBitmap.Width = Width) and (aBitmap.Height = Height)) then begin
5029 result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
5030 if not Assigned(aFunc) then
5031 aFunc := glBitmapAlphaFunc;
5033 SourceFD := TFormatDescriptor.Get(aBitmap.Format);
5034 DestFD := TFormatDescriptor.Get(Format);
5037 TempHeight := aBitmap.FileHeight;
5038 TempWidth := aBitmap.FileWidth;
5040 FuncRec.Sender := Self;
5041 FuncRec.Args := aArgs;
5042 FuncRec.Size := Dimension;
5043 FuncRec.Position.Fields := FuncRec.Size.Fields;
5044 FuncRec.Args := PtrInt(SourceFD.HasAlpha) and 1;
5048 SourceData := aBitmap.Data;
5051 SourceFD.PreparePixel(FuncRec.Source);
5052 DestFD.PreparePixel (FuncRec.Dest);
5054 SourceMD := SourceFD.CreateMappingData;
5055 DestMD := DestFD.CreateMappingData;
5056 DestMD2 := DestFD.CreateMappingData;
5058 FuncRec.Position.Y := 0;
5059 while FuncRec.Position.Y < TempHeight do begin
5060 FuncRec.Position.X := 0;
5061 while FuncRec.Position.X < TempWidth do begin
5062 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
5063 DestFD.Unmap (DestData, FuncRec.Dest, DestMD);
5065 DestFD.Map(FuncRec.Dest, DestData2, DestMD2);
5066 inc(FuncRec.Position.X);
5068 inc(FuncRec.Position.Y);
5071 SourceFD.FreeMappingData(SourceMD);
5072 DestFD.FreeMappingData(DestMD);
5073 DestFD.FreeMappingData(DestMD2);
5078 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5079 function TglBitmap.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
5081 result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
5084 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5085 function TglBitmap.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
5087 PixelData: TglBitmapPixelData;
5089 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
5090 result := AddAlphaFromColorKeyFloat(
5091 aRed / PixelData.Range.r,
5092 aGreen / PixelData.Range.g,
5093 aBlue / PixelData.Range.b,
5094 aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b)));
5097 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5098 function TglBitmap.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
5100 values: array[0..2] of Single;
5103 PixelData: TglBitmapPixelData;
5105 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
5106 with PixelData do begin
5108 values[1] := aGreen;
5111 for i := 0 to 2 do begin
5112 tmp := Trunc(Range.arr[i] * aDeviation);
5113 Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp));
5114 Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp));
5119 result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, PtrInt(@PixelData));
5122 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5123 function TglBitmap.AddAlphaFromValue(const aAlpha: Byte): Boolean;
5125 result := AddAlphaFromValueFloat(aAlpha / $FF);
5128 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5129 function TglBitmap.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
5131 PixelData: TglBitmapPixelData;
5133 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
5134 result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
5137 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5138 function TglBitmap.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
5140 PixelData: TglBitmapPixelData;
5142 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
5144 Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
5145 result := AddAlphaFromFunc(glBitmapValueAlphaFunc, PtrInt(@PixelData.Data.a));
5148 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5149 function TglBitmap.RemoveAlpha: Boolean;
5151 FormatDesc: TFormatDescriptor;
5154 FormatDesc := TFormatDescriptor.Get(Format);
5155 if Assigned(Data) then begin
5156 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
5157 raise EglBitmapUnsupportedFormatFormat.Create('RemoveAlpha - ' + UNSUPPORTED_FORMAT);
5158 result := ConvertTo(FormatDesc.WithoutAlpha);
5162 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5163 function TglBitmap.Clone: TglBitmap;
5170 Temp := (ClassType.Create as TglBitmap);
5172 // copy texture data if assigned
5173 if Assigned(Data) then begin
5174 Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
5175 GetMem(TempPtr, Size);
5177 Move(Data^, TempPtr^, Size);
5178 Temp.SetDataPointer(TempPtr, Format, Width, Height);
5184 Temp.SetDataPointer(nil, Format, Width, Height);
5188 Temp.fTarget := Target;
5189 Temp.fFormat := Format;
5190 Temp.fMipMap := MipMap;
5191 Temp.fAnisotropic := Anisotropic;
5192 Temp.fBorderColor := fBorderColor;
5193 Temp.fDeleteTextureOnFree := DeleteTextureOnFree;
5194 Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
5195 Temp.fFilterMin := fFilterMin;
5196 Temp.fFilterMag := fFilterMag;
5197 Temp.fWrapS := fWrapS;
5198 Temp.fWrapT := fWrapT;
5199 Temp.fWrapR := fWrapR;
5200 Temp.fFilename := fFilename;
5201 Temp.fCustomName := fCustomName;
5202 Temp.fCustomNameW := fCustomNameW;
5203 Temp.fCustomData := fCustomData;
5212 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5213 function TglBitmap.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
5215 SourceFD, DestFD: TFormatDescriptor;
5216 SourcePD, DestPD: TglBitmapPixelData;
5217 ShiftData: TShiftData;
5219 function CanCopyDirect: Boolean;
5222 ((SourcePD.Range.r = DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
5223 ((SourcePD.Range.g = DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
5224 ((SourcePD.Range.b = DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
5225 ((SourcePD.Range.a = DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
5228 function CanShift: Boolean;
5231 ((SourcePD.Range.r >= DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
5232 ((SourcePD.Range.g >= DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
5233 ((SourcePD.Range.b >= DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
5234 ((SourcePD.Range.a >= DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
5237 function GetShift(aSource, aDest: Cardinal) : ShortInt;
5240 while (aSource > aDest) and (aSource > 0) do begin
5242 aSource := aSource shr 1;
5247 if (aFormat <> fFormat) and (aFormat <> tfEmpty) then begin
5248 SourceFD := TFormatDescriptor.Get(Format);
5249 DestFD := TFormatDescriptor.Get(aFormat);
5251 SourceFD.PreparePixel(SourcePD);
5252 DestFD.PreparePixel (DestPD);
5254 if CanCopyDirect then
5255 result := AddFunc(Self, glBitmapConvertCopyFunc, false, aFormat)
5256 else if CanShift then begin
5257 ShiftData.r := GetShift(SourcePD.Range.r, DestPD.Range.r);
5258 ShiftData.g := GetShift(SourcePD.Range.g, DestPD.Range.g);
5259 ShiftData.b := GetShift(SourcePD.Range.b, DestPD.Range.b);
5260 ShiftData.a := GetShift(SourcePD.Range.a, DestPD.Range.a);
5261 result := AddFunc(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, PtrInt(@ShiftData));
5263 result := AddFunc(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
5268 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5269 procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
5271 if aUseRGB or aUseAlpha then
5272 AddFunc(glBitmapInvertFunc, false, ((PtrInt(aUseAlpha) and 1) shl 1) or (PtrInt(aUseRGB) and 1));
5275 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5276 procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
5278 fBorderColor[0] := aRed;
5279 fBorderColor[1] := aGreen;
5280 fBorderColor[2] := aBlue;
5281 fBorderColor[3] := aAlpha;
5282 if (ID > 0) then begin
5284 glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
5288 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5289 procedure TglBitmap.FreeData;
5291 SetDataPointer(nil, tfEmpty);
5294 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5295 procedure TglBitmap.FillWithColor(const aRed, aGreen, aBlue: Byte;
5296 const aAlpha: Byte);
5298 FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
5301 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5302 procedure TglBitmap.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
5304 PixelData: TglBitmapPixelData;
5306 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
5308 aRed / PixelData.Range.r,
5309 aGreen / PixelData.Range.g,
5310 aBlue / PixelData.Range.b,
5311 aAlpha / PixelData.Range.a);
5314 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5315 procedure TglBitmap.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
5317 PixelData: TglBitmapPixelData;
5319 TFormatDescriptor.Get(Format).PreparePixel(PixelData);
5320 with PixelData do begin
5321 Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed)));
5322 Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen)));
5323 Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue)));
5324 Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha)));
5326 AddFunc(glBitmapFillWithColorFunc, false, PtrInt(@PixelData));
5329 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5330 procedure TglBitmap.SetFilter(const aMin, aMag: Cardinal);
5335 fFilterMin := GL_NEAREST;
5337 fFilterMin := GL_LINEAR;
5338 GL_NEAREST_MIPMAP_NEAREST:
5339 fFilterMin := GL_NEAREST_MIPMAP_NEAREST;
5340 GL_LINEAR_MIPMAP_NEAREST:
5341 fFilterMin := GL_LINEAR_MIPMAP_NEAREST;
5342 GL_NEAREST_MIPMAP_LINEAR:
5343 fFilterMin := GL_NEAREST_MIPMAP_LINEAR;
5344 GL_LINEAR_MIPMAP_LINEAR:
5345 fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
5347 raise EglBitmapException.Create('SetFilter - Unknow MIN filter.');
5353 fFilterMag := GL_NEAREST;
5355 fFilterMag := GL_LINEAR;
5357 raise EglBitmapException.Create('SetFilter - Unknow MAG filter.');
5361 if (ID > 0) then begin
5363 glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
5365 if (MipMap = mmNone) or (Target = GL_TEXTURE_RECTANGLE) then begin
5367 GL_NEAREST, GL_LINEAR:
5368 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
5369 GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR:
5370 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5371 GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR:
5372 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5375 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
5379 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5380 procedure TglBitmap.SetWrap(const S: Cardinal; const T: Cardinal; const R: Cardinal);
5382 procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
5386 aTarget := GL_CLAMP;
5389 aTarget := GL_REPEAT;
5391 GL_CLAMP_TO_EDGE: begin
5392 if GL_VERSION_1_2 or GL_EXT_texture_edge_clamp then
5393 aTarget := GL_CLAMP_TO_EDGE
5395 aTarget := GL_CLAMP;
5398 GL_CLAMP_TO_BORDER: begin
5399 if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
5400 aTarget := GL_CLAMP_TO_BORDER
5402 aTarget := GL_CLAMP;
5405 GL_MIRRORED_REPEAT: begin
5406 if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
5407 aTarget := GL_MIRRORED_REPEAT
5409 raise EglBitmapException.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
5412 raise EglBitmapException.Create('SetWrap - Unknow Texturewrap (S).');
5417 CheckAndSetWrap(S, fWrapS);
5418 CheckAndSetWrap(T, fWrapT);
5419 CheckAndSetWrap(R, fWrapR);
5421 if (ID > 0) then begin
5423 glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
5424 glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
5425 glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
5429 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5430 procedure TglBitmap.GetPixel(const aPos: TglBitmapPixelPosition; var aPixel: TglBitmapPixelData);
5433 if Assigned (fGetPixelFunc) then
5434 fGetPixelFunc(aPos, aPixel);
5438 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5439 procedure TglBitmap.SetPixel(const aPos: TglBitmapPixelPosition; const aPixel: TglBitmapPixelData);
5442 if Assigned (fSetPixelFunc) then
5443 fSetPixelFuc(aPos, aPixel);
5447 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5448 procedure TglBitmap.Bind(const aEnableTextureUnit: Boolean);
5450 if aEnableTextureUnit then
5453 glBindTexture(Target, ID);
5456 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5457 procedure TglBitmap.Unbind(const aDisableTextureUnit: Boolean);
5459 if aDisableTextureUnit then
5461 glBindTexture(Target, 0);
5464 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5465 constructor TglBitmap.Create;
5467 {$IFDEF GLB_NATIVE_OGL}
5468 glbReadOpenGLExtensions;
5470 if (ClassType = TglBitmap) then
5471 raise EglBitmapException.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
5475 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5476 constructor TglBitmap.Create(const aFileName: String);
5479 LoadFromFile(FileName);
5482 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5483 constructor TglBitmap.Create(const aStream: TStream);
5486 LoadFromStream(aStream);
5489 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5490 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat);
5496 TFormatDescriptor.Get(aFormat).GetSize(aSize);
5497 GetMem(Image, ImageSize);
5499 FillChar(Image^, ImageSize, #$FF);
5500 SetDataPointer(Image, aFormat, aSize.X, aSize.Y);
5507 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5508 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat;
5509 const aFunc: TglBitmapFunction; const aArgs: PtrInt);
5512 LoadFromFunc(aSize, aFunc, aFormat, aArgs);
5516 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5517 constructor TglBitmap.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
5520 LoadFromResource(aInstance, aResource, aResType);
5523 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5524 constructor TglBitmap.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
5527 LoadFromResourceID(aInstance, aResourceID, aResType);
5531 {$IFDEF GLB_SUPPORT_PNG_READ}
5532 {$IF DEFINED(GLB_SDL_IMAGE)}
5533 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5534 //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5535 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5536 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
5538 Surface: PSDL_Surface;
5542 RWops := glBitmapCreateRWops(aStream);
5544 if IMG_isPNG(RWops) > 0 then begin
5545 Surface := IMG_LoadPNG_RW(RWops);
5547 AssignFromSurface(Surface);
5550 SDL_FreeSurface(Surface);
5558 {$ELSEIF DEFINED(GLB_LIB_PNG)}
5559 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5560 procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
5562 TStream(png_get_io_ptr(png)).Read(buffer^, size);
5565 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5566 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
5569 signature: array [0..7] of byte;
5571 png_info: png_infop;
5573 TempHeight, TempWidth: Integer;
5574 Format: TglBitmapInternalFormat;
5577 png_rows: array of pByte;
5578 Row, LineSize: Integer;
5582 if not init_libPNG then
5583 raise Exception.Create('LoadPNG - unable to initialize libPNG.');
5587 StreamPos := Stream.Position;
5588 Stream.Read(signature, 8);
5589 Stream.Position := StreamPos;
5591 if png_check_sig(@signature, 8) <> 0 then begin
5593 png := png_create_read_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
5595 raise EglBitmapException.Create('LoadPng - couldn''t create read struct.');
5598 png_info := png_create_info_struct(png);
5599 if png_info = nil then begin
5600 png_destroy_read_struct(@png, nil, nil);
5601 raise EglBitmapException.Create('LoadPng - couldn''t create info struct.');
5604 // set read callback
5605 png_set_read_fn(png, stream, glBitmap_libPNG_read_func);
5607 // read informations
5608 png_read_info(png, png_info);
5611 TempHeight := png_get_image_height(png, png_info);
5612 TempWidth := png_get_image_width(png, png_info);
5615 case png_get_color_type(png, png_info) of
5616 PNG_COLOR_TYPE_GRAY:
5617 Format := tfLuminance8;
5618 PNG_COLOR_TYPE_GRAY_ALPHA:
5619 Format := tfLuminance8Alpha8;
5622 PNG_COLOR_TYPE_RGB_ALPHA:
5625 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
5628 // cut upper 8 bit from 16 bit formats
5629 if png_get_bit_depth(png, png_info) > 8 then
5630 png_set_strip_16(png);
5632 // expand bitdepth smaller than 8
5633 if png_get_bit_depth(png, png_info) < 8 then
5634 png_set_expand(png);
5636 // allocating mem for scanlines
5637 LineSize := png_get_rowbytes(png, png_info);
5638 GetMem(png_data, TempHeight * LineSize);
5640 SetLength(png_rows, TempHeight);
5641 for Row := Low(png_rows) to High(png_rows) do begin
5642 png_rows[Row] := png_data;
5643 Inc(png_rows[Row], Row * LineSize);
5646 // read complete image into scanlines
5647 png_read_image(png, @png_rows[0]);
5650 png_read_end(png, png_info);
5652 // destroy read struct
5653 png_destroy_read_struct(@png, @png_info, nil);
5655 SetLength(png_rows, 0);
5658 SetDataPointer(png_data, Format, TempWidth, TempHeight);
5671 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
5672 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5673 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
5677 Header: Array[0..7] of Byte;
5678 Row, Col, PixSize, LineSize: Integer;
5679 NewImage, pSource, pDest, pAlpha: pByte;
5680 Format: TglBitmapInternalFormat;
5683 PngHeader: Array[0..7] of Byte = (#137, #80, #78, #71, #13, #10, #26, #10);
5688 StreamPos := Stream.Position;
5689 Stream.Read(Header[0], SizeOf(Header));
5690 Stream.Position := StreamPos;
5692 {Test if the header matches}
5693 if Header = PngHeader then begin
5694 Png := TPNGObject.Create;
5696 Png.LoadFromStream(Stream);
5698 case Png.Header.ColorType of
5700 Format := ifLuminance;
5701 COLOR_GRAYSCALEALPHA:
5702 Format := ifLuminanceAlpha;
5708 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
5711 PixSize := Trunc(FormatGetSize(Format));
5712 LineSize := Integer(Png.Header.Width) * PixSize;
5714 GetMem(NewImage, LineSize * Integer(Png.Header.Height));
5718 case Png.Header.ColorType of
5719 COLOR_RGB, COLOR_GRAYSCALE:
5721 for Row := 0 to Png.Height -1 do begin
5722 Move (Png.Scanline[Row]^, pDest^, LineSize);
5723 Inc(pDest, LineSize);
5726 COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA:
5728 PixSize := PixSize -1;
5730 for Row := 0 to Png.Height -1 do begin
5731 pSource := Png.Scanline[Row];
5732 pAlpha := pByte(Png.AlphaScanline[Row]);
5734 for Col := 0 to Png.Width -1 do begin
5735 Move (pSource^, pDest^, PixSize);
5736 Inc(pSource, PixSize);
5737 Inc(pDest, PixSize);
5746 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
5749 SetDataPointer(NewImage, Format, Png.Header.Width, Png.Header.Height);
5764 {$IFDEF GLB_SUPPORT_PNG_WRITE}
5765 {$IFDEF GLB_LIB_PNG}
5766 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5767 procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
5769 TStream(png_get_io_ptr(png)).Write(buffer^, size);
5773 {$IF DEFINED(GLB_LIB_PNG)}
5774 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5775 procedure TglBitmap.SavePNG(const aStream: TStream);
5778 png_info: png_infop;
5779 png_rows: array of pByte;
5784 if not (ftPNG in FormatGetSupportedFiles (InternalFormat)) then
5785 raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
5787 if not init_libPNG then
5788 raise Exception.Create('SavePNG - unable to initialize libPNG.');
5791 case FInternalFormat of
5792 ifAlpha, ifLuminance, ifDepth8:
5793 ColorType := PNG_COLOR_TYPE_GRAY;
5795 ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
5797 ColorType := PNG_COLOR_TYPE_RGB;
5799 ColorType := PNG_COLOR_TYPE_RGBA;
5801 raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
5803 LineSize := Trunc(FormatGetSize(FInternalFormat) * Width);
5805 // creating array for scanline
5806 SetLength(png_rows, Height);
5808 for Row := 0 to Height - 1 do begin
5809 png_rows[Row] := Data;
5810 Inc(png_rows[Row], Row * LineSize)
5814 png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
5816 raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
5819 png_info := png_create_info_struct(png);
5820 if png_info = nil then begin
5821 png_destroy_write_struct(@png, nil);
5822 raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
5825 // set read callback
5826 png_set_write_fn(png, stream, glBitmap_libPNG_write_func, nil);
5829 png_set_compression_level(png, 6);
5831 if InternalFormat in [ifBGR8, ifBGRA8] then
5834 png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
5835 png_write_info(png, png_info);
5836 png_write_image(png, @png_rows[0]);
5837 png_write_end(png, png_info);
5838 png_destroy_write_struct(@png, @png_info);
5840 SetLength(png_rows, 0);
5847 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
5848 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5849 procedure TglBitmap.SavePNG(const aStream: TStream);
5853 pSource, pDest: pByte;
5854 X, Y, PixSize: Integer;
5855 ColorType: Cardinal;
5861 if not (ftPNG in FormatGetSupportedFiles (InternalFormat)) then
5862 raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
5864 case FInternalFormat of
5865 ifAlpha, ifLuminance, ifDepth8: begin
5866 ColorType := COLOR_GRAYSCALE;
5870 ifLuminanceAlpha: begin
5871 ColorType := COLOR_GRAYSCALEALPHA;
5875 ifBGR8, ifRGB8: begin
5876 ColorType := COLOR_RGB;
5880 ifBGRA8, ifRGBA8: begin
5881 ColorType := COLOR_RGBALPHA;
5886 raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
5889 Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
5893 for Y := 0 to Height -1 do begin
5894 pDest := png.ScanLine[Y];
5895 for X := 0 to Width -1 do begin
5896 Move(pSource^, pDest^, PixSize);
5897 Inc(pDest, PixSize);
5898 Inc(pSource, PixSize);
5900 png.AlphaScanline[Y]^[X] := pSource^;
5905 // convert RGB line to BGR
5906 if InternalFormat in [ifRGB8, ifRGBA8] then begin
5907 pTemp := png.ScanLine[Y];
5908 for X := 0 to Width -1 do begin
5909 Temp := pByteArray(pTemp)^[0];
5910 pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
5911 pByteArray(pTemp)^[2] := Temp;
5918 Png.CompressionLevel := 6;
5919 Png.SaveToStream(Stream);
5927 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5928 //JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5929 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5930 {$IFDEF GLB_LIB_JPEG}
5932 glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
5933 glBitmap_libJPEG_source_mgr = record
5934 pub: jpeg_source_mgr;
5937 SrcBuffer: array [1..4096] of byte;
5940 glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
5941 glBitmap_libJPEG_dest_mgr = record
5942 pub: jpeg_destination_mgr;
5944 DestStream: TStream;
5945 DestBuffer: array [1..4096] of byte;
5948 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5950 procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
5954 SetLength(Msg, 256);
5955 cinfo^.err^.format_message(cinfo, pChar(Msg));
5956 Writeln('ERROR [' + IntToStr(cinfo^.err^.msg_code) + '] ' + Msg);
5957 cinfo^.global_state := 0;
5962 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5964 procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
5968 SetLength(Msg, 256);
5969 cinfo^.err^.format_message(cinfo, pChar(Msg));
5970 Writeln('OUTPUT [' + IntToStr(cinfo^.err^.msg_code) + '] ' + Msg);
5971 cinfo^.global_state := 0;
5975 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5977 procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
5982 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5983 function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
5985 src: glBitmap_libJPEG_source_mgr_ptr;
5988 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
5990 bytes := src^.SrcStream.Read(src^.SrcBuffer[1], 4096);
5991 if (bytes <= 0) then begin
5992 src^.SrcBuffer[1] := $FF;
5993 src^.SrcBuffer[2] := JPEG_EOI;
5997 src^.pub.next_input_byte := @(src^.SrcBuffer[1]);
5998 src^.pub.bytes_in_buffer := bytes;
6003 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6004 procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
6006 src: glBitmap_libJPEG_source_mgr_ptr;
6008 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
6010 if num_bytes > 0 then begin
6011 // wanted byte isn't in buffer so set stream position and read buffer
6012 if num_bytes > src^.pub.bytes_in_buffer then begin
6013 src^.SrcStream.Position := src^.SrcStream.Position + num_bytes - src^.pub.bytes_in_buffer;
6014 src^.pub.fill_input_buffer(cinfo);
6016 // wanted byte is in buffer so only skip
6017 inc(src^.pub.next_input_byte, num_bytes);
6018 dec(src^.pub.bytes_in_buffer, num_bytes);
6023 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6025 procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
6030 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6032 procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
6037 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6038 function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
6040 dest: glBitmap_libJPEG_dest_mgr_ptr;
6042 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
6044 if dest^.pub.free_in_buffer < Cardinal(Length(dest^.DestBuffer)) then begin
6045 // write complete buffer
6046 dest^.DestStream.Write(dest^.DestBuffer[1], SizeOf(dest^.DestBuffer));
6049 dest^.pub.next_output_byte := @dest^.DestBuffer[1];
6050 dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
6056 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6057 procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
6060 dest: glBitmap_libJPEG_dest_mgr_ptr;
6062 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
6064 for Idx := Low(dest^.DestBuffer) to High(dest^.DestBuffer) do begin
6065 // check for endblock
6066 if (Idx < High(dest^.DestBuffer)) and (dest^.DestBuffer[Idx] = $FF) and (dest^.DestBuffer[Idx +1] = JPEG_EOI) then begin
6068 dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
6073 dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
6078 {$IFDEF GLB_SUPPORT_JPEG_READ}
6079 {$IF DEFINED(GLB_SDL_IMAGE)}
6080 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6081 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6083 Surface: PSDL_Surface;
6088 RWops := glBitmapCreateRWops(Stream);
6090 if IMG_isJPG(RWops) > 0 then begin
6091 Surface := IMG_LoadJPG_RW(RWops);
6093 AssignFromSurface(Surface);
6096 SDL_FreeSurface(Surface);
6104 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
6105 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6106 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6109 Temp: array[0..1]of Byte;
6111 jpeg: jpeg_decompress_struct;
6112 jpeg_err: jpeg_error_mgr;
6114 IntFormat: TglBitmapInternalFormat;
6116 TempHeight, TempWidth: Integer;
6123 if not init_libJPEG then
6124 raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
6127 // reading first two bytes to test file and set cursor back to begin
6128 StreamPos := Stream.Position;
6129 Stream.Read(Temp[0], 2);
6130 Stream.Position := StreamPos;
6132 // if Bitmap then read file.
6133 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
6134 FillChar(jpeg, SizeOf(jpeg_decompress_struct), $00);
6135 FillChar(jpeg_err, SizeOf(jpeg_error_mgr), $00);
6138 jpeg.err := jpeg_std_error(@jpeg_err);
6139 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
6140 jpeg_err.output_message := glBitmap_libJPEG_output_message;
6142 // decompression struct
6143 jpeg_create_decompress(@jpeg);
6145 // allocation space for streaming methods
6146 jpeg.src := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_source_mgr));
6148 // seeting up custom functions
6149 with glBitmap_libJPEG_source_mgr_ptr(jpeg.src)^ do begin
6150 pub.init_source := glBitmap_libJPEG_init_source;
6151 pub.fill_input_buffer := glBitmap_libJPEG_fill_input_buffer;
6152 pub.skip_input_data := glBitmap_libJPEG_skip_input_data;
6153 pub.resync_to_restart := jpeg_resync_to_restart; // use default method
6154 pub.term_source := glBitmap_libJPEG_term_source;
6156 pub.bytes_in_buffer := 0; // forces fill_input_buffer on first read
6157 pub.next_input_byte := nil; // until buffer loaded
6159 SrcStream := Stream;
6162 // set global decoding state
6163 jpeg.global_state := DSTATE_START;
6165 // read header of jpeg
6166 jpeg_read_header(@jpeg, false);
6168 // setting output parameter
6169 case jpeg.jpeg_color_space of
6172 jpeg.out_color_space := JCS_GRAYSCALE;
6173 IntFormat := ifLuminance;
6176 jpeg.out_color_space := JCS_RGB;
6177 IntFormat := ifRGB8;
6181 jpeg_start_decompress(@jpeg);
6183 TempHeight := jpeg.output_height;
6184 TempWidth := jpeg.output_width;
6186 // creating new image
6187 GetMem(pImage, FormatGetImageSize(glBitmapPosition(TempWidth, TempHeight), IntFormat));
6191 for Row := 0 to TempHeight -1 do begin
6192 jpeg_read_scanlines(@jpeg, @pTemp, 1);
6193 Inc(pTemp, Trunc(FormatGetSize(IntFormat) * TempWidth));
6196 // finish decompression
6197 jpeg_finish_decompress(@jpeg);
6199 // destroy decompression
6200 jpeg_destroy_decompress(@jpeg);
6202 SetDataPointer(pImage, IntFormat, TempWidth, TempHeight);
6215 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
6216 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6217 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6222 Temp: array[0..1]of Byte;
6226 // reading first two bytes to test file and set cursor back to begin
6227 StreamPos := Stream.Position;
6228 Stream.Read(Temp[0], 2);
6229 Stream.Position := StreamPos;
6231 // if Bitmap then read file.
6232 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
6233 bmp := TBitmap.Create;
6235 jpg := TJPEGImage.Create;
6237 jpg.LoadFromStream(Stream);
6239 result := AssignFromBitmap(bmp);
6251 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
6252 {$IF DEFEFINED(GLB_LIB_JPEG)}
6253 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6254 procedure TglBitmap.SaveJPEG(Stream: TStream);
6256 jpeg: jpeg_compress_struct;
6257 jpeg_err: jpeg_error_mgr;
6259 pTemp, pTemp2: pByte;
6261 procedure CopyRow(pDest, pSource: pByte);
6265 for X := 0 to Width - 1 do begin
6266 pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
6267 pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
6268 pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
6275 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
6276 raise EglBitmapUnsupportedInternalFormat.Create('SaveJpg - ' + UNSUPPORTED_INTERNAL_FORMAT);
6278 if not init_libJPEG then
6279 raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
6282 FillChar(jpeg, SizeOf(jpeg_compress_struct), $00);
6283 FillChar(jpeg_err, SizeOf(jpeg_error_mgr), $00);
6286 jpeg.err := jpeg_std_error(@jpeg_err);
6287 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
6288 jpeg_err.output_message := glBitmap_libJPEG_output_message;
6290 // compression struct
6291 jpeg_create_compress(@jpeg);
6293 // allocation space for streaming methods
6294 jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
6296 // seeting up custom functions
6297 with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
6298 pub.init_destination := glBitmap_libJPEG_init_destination;
6299 pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
6300 pub.term_destination := glBitmap_libJPEG_term_destination;
6302 pub.next_output_byte := @DestBuffer[1];
6303 pub.free_in_buffer := Length(DestBuffer);
6305 DestStream := Stream;
6308 // very important state
6309 jpeg.global_state := CSTATE_START;
6310 jpeg.image_width := Width;
6311 jpeg.image_height := Height;
6312 case InternalFormat of
6313 ifAlpha, ifLuminance, ifDepth8: begin
6314 jpeg.input_components := 1;
6315 jpeg.in_color_space := JCS_GRAYSCALE;
6317 ifRGB8, ifBGR8: begin
6318 jpeg.input_components := 3;
6319 jpeg.in_color_space := JCS_RGB;
6323 jpeg_set_defaults(@jpeg);
6324 jpeg_set_quality(@jpeg, 95, true);
6325 jpeg_start_compress(@jpeg, true);
6328 if InternalFormat = ifBGR8 then
6329 GetMem(pTemp2, fRowSize)
6334 for Row := 0 to jpeg.image_height -1 do begin
6336 if InternalFormat = ifBGR8 then
6337 CopyRow(pTemp2, pTemp)
6342 jpeg_write_scanlines(@jpeg, @pTemp2, 1);
6343 inc(pTemp, fRowSize);
6347 if InternalFormat = ifBGR8 then
6350 jpeg_finish_compress(@jpeg);
6351 jpeg_destroy_compress(@jpeg);
6357 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
6358 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6359 procedure TglBitmap.SaveJPEG(Stream: TStream);
6364 if not (ftJPEG in FormatGetSupportedFiles (InternalFormat)) then
6365 raise EglBitmapUnsupportedInternalFormat.Create('SaveJpg - ' + UNSUPPORTED_INTERNAL_FORMAT);
6367 Bmp := TBitmap.Create;
6369 Jpg := TJPEGImage.Create;
6371 AssignToBitmap(Bmp);
6372 if FInternalFormat in [ifAlpha, ifLuminance, ifDepth8] then begin
6373 Jpg.Grayscale := true;
6374 Jpg.PixelFormat := jf8Bit;
6377 Jpg.SaveToStream(Stream);
6388 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6389 //BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6390 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6397 BMP_COMP_BITFIELDS = 3;
6400 TBMPHeader = packed record
6405 bfOffBits: Cardinal;
6408 TBMPInfo = packed record
6414 biCompression: Cardinal;
6415 biSizeImage: Cardinal;
6416 biXPelsPerMeter: Longint;
6417 biYPelsPerMeter: Longint;
6418 biClrUsed: Cardinal;
6419 biClrImportant: Cardinal;
6422 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6423 function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
6425 //////////////////////////////////////////////////////////////////////////////////////////////////
6426 function ReadInfo(var aInfo: TBMPInfo; var aMask: TglBitmapColorRec): TglBitmapFormat;
6429 aStream.Read(aInfo, SizeOf(aInfo));
6430 FillChar(aMask, SizeOf(aMask), 0);
6433 case aInfo.biCompression of
6435 BMP_COMP_RLE8: begin
6436 raise EglBitmapException.Create('RLE compression is not supported');
6438 BMP_COMP_BITFIELDS: begin
6439 if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
6440 aStream.Read(aMask.r, SizeOf(aMask.r));
6441 aStream.Read(aMask.g, SizeOf(aMask.g));
6442 aStream.Read(aMask.b, SizeOf(aMask.b));
6443 aStream.Read(aMask.a, SizeOf(aMask.a));
6445 raise EglBitmapException.Create('Bitfields are only supported for 16bit and 32bit formats');
6449 //get suitable format
6450 case aInfo.biBitCount of
6451 8: result := tfLuminance8;
6452 16: result := tfBGR5;
6453 24: result := tfBGR8;
6454 32: result := tfBGRA8;
6458 function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TbmpColorTableFormat;
6461 ColorTable: TbmpColorTable;
6464 if (aInfo.biBitCount >= 16) then
6466 aFormat := tfLuminance8;
6467 c := aInfo.biClrUsed;
6469 c := 1 shl aInfo.biBitCount;
6470 SetLength(ColorTable, c);
6471 for i := 0 to c-1 do begin
6472 aStream.Read(ColorTable[i], SizeOf(TbmpColorTableEnty));
6473 if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then
6477 result := TbmpColorTableFormat.Create;
6478 result.PixelSize := aInfo.biBitCount / 8;
6479 result.ColorTable := ColorTable;
6480 result.Range := glBitmapColorRec($FF, $FF, $FF, $00);
6483 //////////////////////////////////////////////////////////////////////////////////////////////////
6484 function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapColorRec;
6485 const aInfo: TBMPInfo): TbmpBitfieldFormat;
6487 TmpFormat: TglBitmapFormat;
6488 FormatDesc: TFormatDescriptor;
6491 if (aMask.r <> 0) or (aMask.g <> 0) or (aMask.b <> 0) or (aMask.a <> 0) then begin
6492 for TmpFormat := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
6493 FormatDesc := TFormatDescriptor.Get(TmpFormat);
6494 if FormatDesc.MaskMatch(aMask.r, aMask.g, aMask.b, aMask.a) then begin
6495 aFormat := FormatDesc.Format;
6500 if (aMask.a = 0) and TFormatDescriptor.Get(aFormat).HasAlpha then
6501 aFormat := TFormatDescriptor.Get(aFormat).WithoutAlpha;
6502 if (aMask.a <> 0) and not TFormatDescriptor.Get(aFormat).HasAlpha then
6503 aFormat := TFormatDescriptor.Get(aFormat).WithAlpha;
6505 result := TbmpBitfieldFormat.Create;
6506 result.PixelSize := aInfo.biBitCount / 8;
6507 result.RedMask := aMask.r;
6508 result.GreenMask := aMask.g;
6509 result.BlueMask := aMask.b;
6510 result.AlphaMask := aMask.a;
6517 ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
6518 PaddingBuff: Cardinal;
6519 LineBuf, ImageData, TmpData: PByte;
6520 SourceMD, DestMD: Pointer;
6521 BmpFormat: TglBitmapFormat;
6522 ColorTable: TbmpColorTable;
6525 Mask: TglBitmapColorRec;
6530 SpecialFormat: TFormatDescriptor;
6531 FormatDesc: TFormatDescriptor;
6533 //////////////////////////////////////////////////////////////////////////////////////////////////
6534 procedure SpecialFormatReadLine(aData: PByte; aLineBuf: PByte);
6537 Pixel: TglBitmapPixelData;
6539 aStream.Read(aLineBuf^, rbLineSize);
6540 SpecialFormat.PreparePixel(Pixel);
6541 for i := 0 to Info.biWidth-1 do begin
6542 SpecialFormat.Unmap(aLineBuf, Pixel, SourceMD);
6543 glBitmapConvertPixel(Pixel, SpecialFormat, FormatDesc);
6544 FormatDesc.Map(Pixel, aData, DestMD);
6550 BmpFormat := tfEmpty;
6551 SpecialFormat := nil;
6557 StartPos := aStream.Position;
6558 aStream.Read(Header, SizeOf(Header));
6560 if Header.bfType = BMP_MAGIC then begin
6562 BmpFormat := ReadInfo(Info, Mask);
6563 SpecialFormat := ReadColorTable(BmpFormat, Info);
6564 if not Assigned(SpecialFormat) then
6565 SpecialFormat := CheckBitfields(BmpFormat, Mask, Info);
6566 aStream.Position := StartPos + Header.bfOffBits;
6568 if (BmpFormat <> tfEmpty) then begin
6569 FormatDesc := TFormatDescriptor.Get(BmpFormat);
6570 rbLineSize := Round(Info.biWidth * Info.biBitCount / 8); //ReadBuffer LineSize
6571 wbLineSize := Trunc(Info.biWidth * FormatDesc.PixelSize);
6572 Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
6575 DestMD := FormatDesc.CreateMappingData;
6576 ImageSize := FormatDesc.GetSize(Info.biWidth, abs(Info.biHeight));
6577 GetMem(ImageData, ImageSize);
6578 if Assigned(SpecialFormat) then begin
6579 GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
6580 SourceMD := SpecialFormat.CreateMappingData;
6585 FillChar(ImageData^, ImageSize, $FF);
6586 TmpData := ImageData;
6587 if (Info.biHeight > 0) then
6588 Inc(TmpData, wbLineSize * (Info.biHeight-1));
6589 for i := 0 to Abs(Info.biHeight)-1 do begin
6590 if Assigned(SpecialFormat) then
6591 SpecialFormatReadLine(TmpData, LineBuf) //if is special format read and convert data
6593 aStream.Read(TmpData^, wbLineSize); //else only read data
6594 if (Info.biHeight > 0) then
6595 dec(TmpData, wbLineSize)
6597 inc(TmpData, wbLineSize);
6598 aStream.Read(PaddingBuff, Padding);
6600 SetDataPointer(ImageData, BmpFormat, Info.biWidth, abs(Info.biHeight));
6603 if Assigned(LineBuf) then
6605 if Assigned(SourceMD) then
6606 SpecialFormat.FreeMappingData(SourceMD);
6607 FormatDesc.FreeMappingData(DestMD);
6614 raise EglBitmapException.Create('LoadBMP - No suitable format found');
6616 aStream.Position := StartPos;
6620 FreeAndNil(SpecialFormat);
6623 else aStream.Position := StartPos;
6626 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6627 procedure TglBitmap.SaveBMP(const aStream: TStream);
6631 Converter: TbmpColorTableFormat;
6632 FormatDesc: TFormatDescriptor;
6633 SourceFD, DestFD: Pointer;
6634 pData, srcData, dstData, ConvertBuffer: pByte;
6636 Pixel: TglBitmapPixelData;
6637 PixelFormat: TglBitmapPixelData;
6638 ImageSize, wbLineSize, rbLineSize, Padding, LineIdx, PixelIdx, i: Integer;
6639 RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
6641 PaddingBuff: Cardinal;
6643 function GetLineWidth : Integer;
6645 result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
6649 if not (ftBMP in FormatGetSupportedFiles(Format)) then
6650 raise EglBitmapUnsupportedFormatFormat.Create('SaveBMP - ' + UNSUPPORTED_FORMAT);
6653 FormatDesc := TFormatDescriptor.Get(Format);
6654 ImageSize := FormatDesc.GetSize(Dimension);
6656 FillChar(Header, SizeOf(Header), 0);
6657 Header.bfType := BMP_MAGIC;
6658 Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
6659 Header.bfReserved1 := 0;
6660 Header.bfReserved2 := 0;
6661 Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
6663 FillChar(Info, SizeOf(Info), 0);
6664 Info.biSize := SizeOf(Info);
6665 Info.biWidth := Width;
6666 Info.biHeight := Height;
6668 Info.biCompression := BMP_COMP_RGB;
6669 Info.biSizeImage := ImageSize;
6674 Info.biBitCount := 4;
6675 Header.bfSize := Header.bfSize + 16 * SizeOf(Cardinal);
6676 Header.bfOffBits := Header.bfOffBits + 16 * SizeOf(Cardinal); //16 ColorTable entries
6677 Converter := TbmpColorTableFormat.Create;
6678 Converter.PixelSize := 0.5;
6679 Converter.Format := Format;
6680 Converter.Range := glBitmapColorRec($F, $F, $F, $0);
6681 Converter.CreateColorTable;
6684 tfR3G3B2, tfLuminance8: begin
6685 Info.biBitCount := 8;
6686 Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
6687 Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal); //256 ColorTable entries
6688 Converter := TbmpColorTableFormat.Create;
6689 Converter.PixelSize := 1;
6690 Converter.Format := Format;
6691 if (Format = tfR3G3B2) then begin
6692 Converter.Range := glBitmapColorRec($7, $7, $3, $0);
6693 Converter.Shift := glBitmapShiftRec(0, 3, 6, 0);
6695 Converter.Range := glBitmapColorRec($FF, $FF, $FF, $0);
6696 Converter.CreateColorTable;
6699 tfRGB4, tfRGB5, tfR5G6B5, tfRGB5A1, tfRGBA4,
6700 tfBGR4, tfBGR5, tfB5G6R5, tfBGR5A1, tfBGRA4: begin
6701 Info.biBitCount := 16;
6702 Info.biCompression := BMP_COMP_BITFIELDS;
6705 tfBGR8, tfRGB8: begin
6706 Info.biBitCount := 24;
6709 tfRGB10, tfRGB10A2, tfRGBA8,
6710 tfBGR10, tfBGR10A2, tfBGRA8: begin
6711 Info.biBitCount := 32;
6712 Info.biCompression := BMP_COMP_BITFIELDS;
6715 raise EglBitmapUnsupportedFormatFormat.Create('SaveBMP - ' + UNSUPPORTED_FORMAT);
6717 Info.biXPelsPerMeter := 2835;
6718 Info.biYPelsPerMeter := 2835;
6721 if Info.biCompression = BMP_COMP_BITFIELDS then begin
6722 Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
6723 Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
6725 RedMask := FormatDesc.RedMask;
6726 GreenMask := FormatDesc.GreenMask;
6727 BlueMask := FormatDesc.BlueMask;
6728 AlphaMask := FormatDesc.AlphaMask;
6732 aStream.Write(Header, SizeOf(Header));
6733 aStream.Write(Info, SizeOf(Info));
6736 if Assigned(Converter) then
6737 aStream.Write(Converter.ColorTable[0].b,
6738 SizeOf(TbmpColorTableEnty) * Length(Converter.ColorTable));
6741 if Info.biCompression = BMP_COMP_BITFIELDS then begin
6742 aStream.Write(RedMask, SizeOf(Cardinal));
6743 aStream.Write(GreenMask, SizeOf(Cardinal));
6744 aStream.Write(BlueMask, SizeOf(Cardinal));
6745 aStream.Write(AlphaMask, SizeOf(Cardinal));
6749 rbLineSize := Round(Info.biWidth * FormatDesc.PixelSize);
6750 wbLineSize := Round(Info.biWidth * Info.biBitCount / 8);
6751 Padding := GetLineWidth - wbLineSize;
6755 inc(pData, (Height-1) * rbLineSize);
6757 // prepare row buffer. But only for RGB because RGBA supports color masks
6758 // so it's possible to change color within the image.
6759 if Assigned(Converter) then begin
6760 FormatDesc.PreparePixel(Pixel);
6761 GetMem(ConvertBuffer, wbLineSize);
6762 SourceFD := FormatDesc.CreateMappingData;
6763 DestFD := Converter.CreateMappingData;
6765 ConvertBuffer := nil;
6768 for LineIdx := 0 to Height - 1 do begin
6770 if Assigned(Converter) then begin
6772 dstData := ConvertBuffer;
6773 for PixelIdx := 0 to Info.biWidth-1 do begin
6774 FormatDesc.Unmap(srcData, Pixel, SourceFD);
6775 glBitmapConvertPixel(Pixel, FormatDesc, Converter);
6776 Converter.Map(Pixel, dstData, DestFD);
6778 aStream.Write(ConvertBuffer^, wbLineSize);
6780 aStream.Write(pData^, rbLineSize);
6782 dec(pData, rbLineSize);
6783 if (Padding > 0) then
6784 aStream.Write(PaddingBuff, Padding);
6787 // destroy row buffer
6788 if Assigned(ConvertBuffer) then begin
6789 FormatDesc.FreeMappingData(SourceFD);
6790 Converter.FreeMappingData(DestFD);
6791 FreeMem(ConvertBuffer);
6795 if Assigned(Converter) then
6800 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6801 //TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6802 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6804 TTGAHeader = packed record
6808 //ColorMapSpec: Array[0..4] of Byte;
6809 ColorMapStart: Word;
6810 ColorMapLength: Word;
6811 ColorMapEntrySize: Byte;
6821 TGA_UNCOMPRESSED_RGB = 2;
6822 TGA_UNCOMPRESSED_GRAY = 3;
6823 TGA_COMPRESSED_RGB = 10;
6824 TGA_COMPRESSED_GRAY = 11;
6826 TGA_NONE_COLOR_TABLE = 0;
6828 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6829 function TglBitmap.LoadTGA(const aStream: TStream): Boolean;
6833 StartPosition: Int64;
6834 PixelSize, LineSize: Integer;
6835 tgaFormat: TglBitmapFormat;
6836 FormatDesc: TFormatDescriptor;
6837 Counter: packed record
6839 low, high, dir: Integer;
6846 ////////////////////////////////////////////////////////////////////////////////////////
6847 procedure ReadUncompressed;
6850 buf, tmp1, tmp2: PByte;
6853 if (Counter.X.dir < 0) then
6854 buf := GetMem(LineSize);
6856 while (Counter.Y.low <> Counter.Y.high + counter.Y.dir) do begin
6857 tmp1 := ImageData + (Counter.Y.low * LineSize); //pointer to LineStart
6858 if (Counter.X.dir < 0) then begin //flip X
6859 aStream.Read(buf^, LineSize);
6860 tmp2 := buf + LineSize - PixelSize; //pointer to last pixel in line
6861 for i := 0 to Header.Width-1 do begin //for all pixels in line
6862 for j := 0 to PixelSize-1 do begin //for all bytes in pixel
6867 dec(tmp2, 2*PixelSize); //move 2 backwards, because j-loop moved 1 forward
6870 aStream.Read(tmp1^, LineSize);
6871 inc(Counter.Y.low, Counter.Y.dir); //move to next line index
6874 if Assigned(buf) then
6879 ////////////////////////////////////////////////////////////////////////////////////////
6880 procedure ReadCompressed;
6882 /////////////////////////////////////////////////////////////////
6885 LinePixelsRead: Integer;
6886 procedure CheckLine;
6888 if (LinePixelsRead >= Header.Width) then begin
6889 LinePixelsRead := 0;
6890 inc(Counter.Y.low, Counter.Y.dir); //next line index
6891 TmpData := ImageData + Counter.Y.low * LineSize; //set line
6892 if (Counter.X.dir < 0) then //if x flipped then
6893 TmpData := TmpData + LineSize - PixelSize; //set last pixel
6897 /////////////////////////////////////////////////////////////////
6900 CacheSize, CachePos: Integer;
6901 procedure CachedRead(out Buffer; Count: Integer);
6905 if (CachePos + Count > CacheSize) then begin
6906 //if buffer overflow save non read bytes
6908 if (CacheSize - CachePos > 0) then begin
6909 BytesRead := CacheSize - CachePos;
6910 Move(PByteArray(Cache)^[CachePos], Buffer, BytesRead);
6911 inc(CachePos, BytesRead);
6914 //load cache from file
6915 CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
6916 aStream.Read(Cache^, CacheSize);
6919 //read rest of requested bytes
6920 if (Count - BytesRead > 0) then begin
6921 Move(PByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
6922 inc(CachePos, Count - BytesRead);
6925 //if no buffer overflow just read the data
6926 Move(PByteArray(Cache)^[CachePos], Buffer, Count);
6927 inc(CachePos, Count);
6931 procedure PixelToBuffer(const aData: PByte; var aBuffer: PByte);
6936 inc(aBuffer, Counter.X.dir);
6939 PWord(aBuffer)^ := PWord(aData)^;
6940 inc(aBuffer, 2 * Counter.X.dir);
6943 PByteArray(aBuffer)^[0] := PByteArray(aData)^[0];
6944 PByteArray(aBuffer)^[1] := PByteArray(aData)^[1];
6945 PByteArray(aBuffer)^[2] := PByteArray(aData)^[2];
6946 inc(aBuffer, 3 * Counter.X.dir);
6949 PCardinal(aBuffer)^ := PCardinal(aData)^;
6950 inc(aBuffer, 4 * Counter.X.dir);
6956 TotalPixelsToRead, TotalPixelsRead: Integer;
6958 buf: array [0..3] of Byte; //1 pixel is max 32bit long
6959 PixelRepeat: Boolean;
6960 PixelsToRead, PixelCount: Integer;
6965 TotalPixelsToRead := Header.Width * Header.Height;
6966 TotalPixelsRead := 0;
6967 LinePixelsRead := 0;
6969 GetMem(Cache, CACHE_SIZE);
6971 TmpData := ImageData + Counter.Y.low * LineSize; //set line
6972 if (Counter.X.dir < 0) then //if x flipped then
6973 TmpData := TmpData + LineSize - PixelSize; //set last pixel
6977 CachedRead(Temp, 1);
6978 PixelRepeat := (Temp and $80) > 0;
6979 PixelsToRead := (Temp and $7F) + 1;
6980 inc(TotalPixelsRead, PixelsToRead);
6983 CachedRead(buf[0], PixelSize);
6984 while (PixelsToRead > 0) do begin
6986 PixelCount := Min(Header.Width - LinePixelsRead, PixelsToRead); //max read to EOL or EOF
6987 while (PixelCount > 0) do begin
6988 if not PixelRepeat then
6989 CachedRead(buf[0], PixelSize);
6990 PixelToBuffer(@buf[0], TmpData);
6991 inc(LinePixelsRead);
6996 until (TotalPixelsRead >= TotalPixelsToRead);
7002 function IsGrayFormat: Boolean;
7004 result := Header.ImageType in [TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_GRAY];
7010 // reading header to test file and set cursor back to begin
7011 StartPosition := aStream.Position;
7012 aStream.Read(Header, SizeOf(Header));
7014 // no colormapped files
7015 if (Header.ColorMapType = TGA_NONE_COLOR_TABLE) and (Header.ImageType in [
7016 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY]) then
7019 if Header.ImageID <> 0 then // skip image ID
7020 aStream.Position := aStream.Position + Header.ImageID;
7023 8: if IsGrayFormat then case (Header.ImageDesc and $F) of
7024 0: tgaFormat := tfLuminance8;
7025 8: tgaFormat := tfAlpha8;
7028 16: if IsGrayFormat then case (Header.ImageDesc and $F) of
7029 0: tgaFormat := tfLuminance16;
7030 8: tgaFormat := tfLuminance8Alpha8;
7031 end else case (Header.ImageDesc and $F) of
7032 0: tgaFormat := tfBGR5;
7033 1: tgaFormat := tfBGR5A1;
7034 4: tgaFormat := tfBGRA4;
7037 24: if not IsGrayFormat then case (Header.ImageDesc and $F) of
7038 0: tgaFormat := tfBGR8;
7041 32: if not IsGrayFormat then case (Header.ImageDesc and $F) of
7042 2: tgaFormat := tfBGR10A2;
7043 8: tgaFormat := tfBGRA8;
7047 if (tgaFormat = tfEmpty) then
7048 raise EglBitmapException.Create('LoadTga - unsupported format');
7050 FormatDesc := TFormatDescriptor.Get(tgaFormat);
7051 PixelSize := FormatDesc.GetSize(1, 1);
7052 LineSize := FormatDesc.GetSize(Header.Width, 1);
7054 GetMem(ImageData, LineSize * Header.Height);
7057 if ((Header.ImageDesc and (1 shl 4)) > 0) then begin
7058 Counter.X.low := Header.Height-1;;
7059 Counter.X.high := 0;
7060 Counter.X.dir := -1;
7063 Counter.X.high := Header.Height-1;
7068 if ((Header.ImageDesc and (1 shl 5)) > 0) then begin
7070 Counter.Y.high := Header.Height-1;
7073 Counter.Y.low := Header.Height-1;;
7074 Counter.Y.high := 0;
7075 Counter.Y.dir := -1;
7079 case Header.ImageType of
7080 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY:
7082 TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY:
7086 SetDataPointer(ImageData, tgaFormat, Header.Width, Header.Height);
7093 aStream.Position := StartPosition;
7096 else aStream.Position := StartPosition;
7099 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7100 procedure TglBitmap.SaveTGA(const aStream: TStream);
7103 LineSize, Size, x, y: Integer;
7104 Pixel: TglBitmapPixelData;
7105 LineBuf, SourceData, DestData: PByte;
7106 SourceMD, DestMD: Pointer;
7107 FormatDesc: TFormatDescriptor;
7108 Converter: TFormatDescriptor;
7110 if not (ftTGA in FormatGetSupportedFiles(Format)) then
7111 raise EglBitmapUnsupportedFormatFormat.Create('SaveTGA - ' + UNSUPPORTED_FORMAT);
7114 FillChar(Header, SizeOf(Header), 0);
7117 if (Format in [tfLuminance8, tfLuminance6Alpha2, tfLuminance4Alpha4, tfAlpha8,
7118 tfLuminance16, tfLuminance12Alpha4, tfLuminance8Alpha8]) then
7119 Header.ImageType := TGA_UNCOMPRESSED_GRAY
7121 Header.ImageType := TGA_UNCOMPRESSED_RGB;
7124 if (Format in [tfLuminance8, tfLuminance6Alpha2, tfLuminance4Alpha4, tfAlpha8]) then
7126 else if (Format in [tfLuminance16, tfLuminance12Alpha4, tfLuminance8Alpha8,
7127 tfRGB5, tfBGR5, tfRGB5A1, tfBGR5A1, tfRGBA4, tfBGRA4]) then
7129 else if (Format in [tfBGR8, tfRGB8]) then
7137 Header.ImageDesc := 1 and $F;
7138 tfRGB10A2, tfBGR10A2:
7139 Header.ImageDesc := 2 and $F;
7141 Header.ImageDesc := 4 and $F;
7142 tfAlpha8, tfLuminance8Alpha8, tfRGBA8, tfBGRA8:
7143 Header.ImageDesc := 8 and $F;
7146 Header.Width := Width;
7147 Header.Height := Height;
7148 Header.ImageDesc := Header.ImageDesc or $20; //flip y
7149 aStream.Write(Header, SizeOf(Header));
7151 // convert RGB(A) to BGR(A)
7153 FormatDesc := TFormatDescriptor.Get(Format);
7154 Size := FormatDesc.GetSize(Dimension);
7155 if Format in [tfRGB5, tfRGB5A1, tfRGBA4, tfRGB8, tfRGB10A2, tfRGBA8] then begin
7156 if (FormatDesc.RGBInverted = tfEmpty) then
7157 raise EglBitmapException.Create('inverted RGB format is empty');
7158 Converter := TFormatDescriptor.Get(FormatDesc.RGBInverted);
7159 if not glBitmapColorRecCmp(Converter.Range, FormatDesc.Range) or
7160 (Converter.PixelSize <> FormatDesc.PixelSize) then
7161 raise EglBitmapException.Create('invalid inverted RGB format');
7164 if Assigned(Converter) then begin
7165 LineSize := FormatDesc.GetSize(Width, 1);
7166 LineBuf := GetMem(LineSize);
7167 SourceMD := FormatDesc.CreateMappingData;
7168 DestMD := Converter.CreateMappingData;
7171 for y := 0 to Height-1 do begin
7172 DestData := LineBuf;
7173 for x := 0 to Width-1 do begin
7174 FormatDesc.Unmap(SourceData, Pixel, SourceMD);
7175 Converter.Map(Pixel, DestData, DestMD);
7177 aStream.Write(LineBuf^, LineSize);
7181 FormatDesc.FreeMappingData(SourceMD);
7182 FormatDesc.FreeMappingData(DestMD);
7185 aStream.Write(Data^, Size);
7188 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7189 //DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7190 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7192 DDS_MAGIC: Cardinal = $20534444;
7194 // DDS_header.dwFlags
7195 DDSD_CAPS = $00000001;
7196 DDSD_HEIGHT = $00000002;
7197 DDSD_WIDTH = $00000004;
7198 DDSD_PIXELFORMAT = $00001000;
7200 // DDS_header.sPixelFormat.dwFlags
7201 DDPF_ALPHAPIXELS = $00000001;
7202 DDPF_ALPHA = $00000002;
7203 DDPF_FOURCC = $00000004;
7204 DDPF_RGB = $00000040;
7205 DDPF_LUMINANCE = $00020000;
7207 // DDS_header.sCaps.dwCaps1
7208 DDSCAPS_TEXTURE = $00001000;
7210 // DDS_header.sCaps.dwCaps2
7211 DDSCAPS2_CUBEMAP = $00000200;
7213 D3DFMT_DXT1 = $31545844;
7214 D3DFMT_DXT3 = $33545844;
7215 D3DFMT_DXT5 = $35545844;
7218 TDDSPixelFormat = packed record
7222 dwRGBBitCount: Cardinal;
7223 dwRBitMask: Cardinal;
7224 dwGBitMask: Cardinal;
7225 dwBBitMask: Cardinal;
7226 dwABitMask: Cardinal;
7229 TDDSCaps = packed record
7233 dwReserved: Cardinal;
7236 TDDSHeader = packed record
7241 dwPitchOrLinearSize: Cardinal;
7243 dwMipMapCount: Cardinal;
7244 dwReserved: array[0..10] of Cardinal;
7245 PixelFormat: TDDSPixelFormat;
7247 dwReserved2: Cardinal;
7250 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7251 function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
7254 Converter: TbmpBitfieldFormat;
7256 function GetDDSFormat: TglBitmapFormat;
7258 fd: TFormatDescriptor;
7260 Range: TglBitmapColorRec;
7264 with Header.PixelFormat do begin
7266 if ((dwFlags and DDPF_FOURCC) > 0) then begin
7267 case Header.PixelFormat.dwFourCC of
7268 D3DFMT_DXT1: result := tfS3tcDtx1RGBA;
7269 D3DFMT_DXT3: result := tfS3tcDtx3RGBA;
7270 D3DFMT_DXT5: result := tfS3tcDtx5RGBA;
7272 end else if ((Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0) then begin
7274 //find matching format
7275 for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
7276 fd := TFormatDescriptor.Get(result);
7277 if fd.MaskMatch(dwRBitMask, dwGBitMask, dwBBitMask, dwABitMask) and
7278 (8 * fd.PixelSize = dwRGBBitCount) then
7282 //find format with same Range
7283 Range.r := dwRBitMask;
7284 Range.g := dwGBitMask;
7285 Range.b := dwBBitMask;
7286 Range.a := dwABitMask;
7287 for i := 0 to 3 do begin
7288 while ((Range.arr[i] and 1) = 0) and (Range.arr[i] > 0) do
7289 Range.arr[i] := Range.arr[i] shr 1;
7291 for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
7292 fd := TFormatDescriptor.Get(result);
7295 if (fd.Range.arr[i] <> Range.arr[i]) then begin
7303 //no format with same range found -> use default
7304 if (result = tfEmpty) then begin
7305 if (dwABitMask > 0) then
7311 Converter := TbmpBitfieldFormat.Create;
7312 Converter.RedMask := dwRBitMask;
7313 Converter.GreenMask := dwGBitMask;
7314 Converter.BlueMask := dwBBitMask;
7315 Converter.AlphaMask := dwABitMask;
7316 Converter.PixelSize := dwRGBBitCount / 8;
7323 x, y, j, LineSize, RowSize, Magic: Cardinal;
7324 NewImage, TmpData, RowData, SrcData: PByte;
7325 SourceMD, DestMD: Pointer;
7326 Pixel: TglBitmapPixelData;
7327 ddsFormat: TglBitmapFormat;
7328 FormatDesc: TFormatDescriptor;
7333 StreamPos := aStream.Position;
7336 aStream.Read(Magic, sizeof(Magic));
7337 if (Magic <> DDS_MAGIC) then begin
7338 aStream.Position := StreamPos;
7343 aStream.Read(Header, sizeof(Header));
7344 if (Header.dwSize <> SizeOf(Header)) or
7345 ((Header.dwFlags and (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) <>
7346 (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) then
7348 aStream.Position := StreamPos;
7352 if ((Header.Caps.dwCaps1 and DDSCAPS2_CUBEMAP) > 0) then
7353 raise EglBitmapException.Create('LoadDDS - CubeMaps are not supported');
7355 ddsFormat := GetDDSFormat;
7357 if (ddsFormat = tfEmpty) then
7358 raise EglBitmapException.Create('LoadDDS - unsupported Pixelformat found.');
7360 FormatDesc := TFormatDescriptor.Get(ddsFormat);
7361 LineSize := Trunc(Header.dwWidth * FormatDesc.PixelSize);
7362 GetMem(NewImage, Header.dwHeight * LineSize);
7364 TmpData := NewImage;
7367 if Assigned(Converter) then begin
7368 RowSize := Round(Header.dwWidth * Header.PixelFormat.dwRGBBitCount / 8);
7369 GetMem(RowData, RowSize);
7370 SourceMD := Converter.CreateMappingData;
7371 DestMD := FormatDesc.CreateMappingData;
7373 for y := 0 to Header.dwHeight-1 do begin
7374 TmpData := NewImage + y * LineSize;
7376 aStream.Read(SrcData^, RowSize);
7377 for x := 0 to Header.dwWidth-1 do begin
7378 Converter.Unmap(SrcData, Pixel, SourceMD);
7379 glBitmapConvertPixel(Pixel, Converter, FormatDesc);
7380 FormatDesc.Map(Pixel, TmpData, DestMD);
7384 Converter.FreeMappingData(SourceMD);
7385 FormatDesc.FreeMappingData(DestMD);
7391 if ((Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0) then begin
7392 RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
7393 for Y := 0 to Header.dwHeight-1 do begin
7394 aStream.Read(TmpData^, RowSize);
7395 Inc(TmpData, LineSize);
7400 if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0 then begin
7401 RowSize := (Header.PixelFormat.dwRGBBitCount * Header.dwWidth) shr 3;
7402 for Y := 0 to Header.dwHeight-1 do begin
7403 aStream.Read(TmpData^, RowSize);
7404 Inc(TmpData, LineSize);
7407 raise EglBitmapException.Create('LoadDDS - unsupported Pixelformat found.');
7409 SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight);
7416 FreeAndNil(Converter);
7420 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7421 procedure TglBitmap.SaveDDS(const aStream: TStream);
7424 FormatDesc: TFormatDescriptor;
7426 if not (ftDDS in FormatGetSupportedFiles(Format)) then
7427 raise EglBitmapUnsupportedFormatFormat.Create('SaveDDS - ' + UNSUPPORTED_FORMAT);
7429 FormatDesc := TFormatDescriptor.Get(Format);
7432 FillChar(Header, SizeOf(Header), 0);
7433 Header.dwSize := SizeOf(Header);
7434 Header.dwFlags := DDSD_WIDTH or DDSD_HEIGHT or DDSD_CAPS or DDSD_PIXELFORMAT;
7436 Header.dwWidth := Max(1, Width);
7437 Header.dwHeight := Max(1, Height);
7440 Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
7443 Header.PixelFormat.dwSize := sizeof(Header);
7444 if (FormatDesc.IsCompressed) then begin
7445 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_FOURCC;
7447 tfS3tcDtx1RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT1;
7448 tfS3tcDtx3RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT3;
7449 tfS3tcDtx5RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT5;
7451 end else if (Format in [tfAlpha8, tfAlpha16]) then begin
7452 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHA;
7453 Header.PixelFormat.dwRGBBitCount := Round(FormatDesc.PixelSize * 8);
7454 Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
7455 end else if (FormatDesc.RedMask = FormatDesc.GreenMask) and (FormatDesc.GreenMask = FormatDesc.BlueMask) then begin
7456 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_LUMINANCE;
7457 Header.PixelFormat.dwRGBBitCount := Round(FormatDesc.PixelSize * 8);
7458 Header.PixelFormat.dwRBitMask := FormatDesc.RedMask;
7459 Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
7461 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_RGB;
7462 Header.PixelFormat.dwRGBBitCount := Round(FormatDesc.PixelSize * 8);
7463 Header.PixelFormat.dwRBitMask := FormatDesc.RedMask;
7464 Header.PixelFormat.dwGBitMask := FormatDesc.GreenMask;
7465 Header.PixelFormat.dwBBitMask := FormatDesc.BlueMask;
7466 Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
7469 if (FormatDesc.HasAlpha) then
7470 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
7472 aStream.Write(DDS_MAGIC, sizeof(DDS_MAGIC));
7473 aStream.Write(Header, SizeOf(Header));
7474 aStream.Write(Data^, FormatDesc.GetSize(Dimension));
7477 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7478 //TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7479 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7480 function TglBitmap2D.GetScanline(const aIndex: Integer): Pointer;
7482 if (aIndex >= Low(fLines)) and (aIndex <= High(fLines)) then
7483 result := fLines[aIndex]
7488 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7489 procedure TglBitmap2D.SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
7490 const aWidth: Integer; const aHeight: Integer);
7492 Idx, LineWidth: Integer;
7494 inherited SetDataPointer(aData, aFormat, aWidth, aHeight);
7496 if not TFormatDescriptor.Get(aFormat).IsCompressed then begin
7498 fGetPixelFunc := GetPixel2DUnmap;
7499 fSetPixelFunc := SetPixel2DUnmap;
7502 if Assigned(Data) then begin
7503 SetLength(fLines, GetHeight);
7504 LineWidth := Trunc(GetWidth * TFormatDescriptor.Get(Format).PixelSize);
7506 for Idx := 0 to GetHeight -1 do begin
7507 fLines[Idx] := Data;
7508 Inc(fLines[Idx], Idx * LineWidth);
7511 else SetLength(fLines, 0);
7513 SetLength(fLines, 0);
7515 fSetPixelFunc := nil;
7519 fGetPixelFunc := GetPixel2DDXT1;
7521 fGetPixelFunc := GetPixel2DDXT3;
7523 fGetPixelFunc := GetPixel2DDXT5;
7525 fGetPixelFunc := nil;
7531 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7532 procedure TglBitmap2D.UploadData(const aTarget: Cardinal; const aBuildWithGlu: Boolean);
7534 FormatDesc: TFormatDescriptor;
7536 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
7538 FormatDesc := TFormatDescriptor.Get(Format);
7539 if FormatDesc.IsCompressed then begin
7540 glCompressedTexImage2D(Target, 0, FormatDesc.glInternalFormat, Width, Height, 0, FormatDesc.GetSize(fDimension), Data)
7541 end else if aBuildWithGlu then begin
7542 gluBuild2DMipmaps(aTarget, FormatDesc.Components, Width, Height,
7543 FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
7545 glTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0,
7546 FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
7550 if (FreeDataAfterGenTexture) then
7554 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7555 procedure TglBitmap2D.AfterConstruction;
7558 Target := GL_TEXTURE_2D;
7561 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7562 procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
7565 Size, w, h: Integer;
7566 FormatDesc: TFormatDescriptor;
7568 FormatDesc := TFormatDescriptor.Get(Format);
7569 if FormatDesc.IsCompressed then
7570 raise EglBitmapUnsupportedFormatFormat.Create('TglBitmap2D.GrabScreen - ' + UNSUPPORTED_FORMAT);
7572 w := aRight - aLeft;
7573 h := aBottom - aTop;
7574 Size := FormatDesc.GetSize(w, h);
7577 glPixelStorei(GL_PACK_ALIGNMENT, 1);
7578 glReadPixels(aLeft, aTop, w, h, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
7579 SetDataPointer(Temp, Format, w, h);
7587 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7588 procedure TglBitmap2D.GetDataFromTexture;
7591 TempWidth, TempHeight: Integer;
7592 TempType, TempIntFormat: Cardinal;
7593 IntFormat, f: TglBitmapFormat;
7594 FormatDesc: TFormatDescriptor;
7599 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
7600 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
7601 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
7603 IntFormat := tfEmpty;
7604 for f := Low(TglBitmapFormat) to High(TglBitmapFormat) do
7605 if (TFormatDescriptor.Get(f).glInternalFormat = TempIntFormat) then begin
7606 IntFormat := FormatDesc.Format;
7610 // Getting data from OpenGL
7611 FormatDesc := TFormatDescriptor.Get(IntFormat);
7612 GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
7614 if FormatDesc.IsCompressed then
7615 glGetCompressedTexImage(Target, 0, Temp)
7617 glGetTexImage(Target, 0, FormatDesc.glInternalFormat, FormatDesc.glDataFormat, Temp);
7618 SetDataPointer(Temp, IntFormat, TempWidth, TempHeight);
7625 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7626 procedure TglBitmap2D.GenTexture(const aTestTextureSize: Boolean);
7628 BuildWithGlu, PotTex, TexRec: Boolean;
7631 if Assigned(Data) then begin
7632 // Check Texture Size
7633 if (aTestTextureSize) then begin
7634 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
7636 if ((Height > TexSize) or (Width > TexSize)) then
7637 raise EglBitmapSizeToLargeException.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
7639 PotTex := IsPowerOfTwo(Height) and IsPowerOfTwo(Width);
7640 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE);
7642 if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
7643 raise EglBitmapNonPowerOfTwoException.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
7647 SetupParameters(BuildWithGlu);
7648 UploadData(Target, BuildWithGlu);
7649 glAreTexturesResident(1, @fID, @fIsResident);
7653 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7654 function TglBitmap2D.FlipHorz: Boolean;
7657 TempDestData, DestData, SourceData: PByte;
7660 result := inherited FlipHorz;
7661 if Assigned(Data) then begin
7663 ImgSize := Height * fRowSize;
7664 GetMem(DestData, ImgSize);
7666 TempDestData := DestData;
7667 Dec(TempDestData, fRowSize + fPixelSize);
7668 for Row := 0 to Height -1 do begin
7669 Inc(TempDestData, fRowSize * 2);
7670 for Col := 0 to Width -1 do begin
7671 Move(SourceData^, TempDestData^, fPixelSize);
7672 Inc(SourceData, fPixelSize);
7673 Dec(TempDestData, fPixelSize);
7676 SetDataPointer(DestData, Format);
7685 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7686 function TglBitmap2D.FlipVert: Boolean;
7689 TempDestData, DestData, SourceData: PByte;
7691 result := inherited FlipVert;
7692 if Assigned(Data) then begin
7694 GetMem(DestData, Height * fRowSize);
7696 TempDestData := DestData;
7697 Inc(TempDestData, Width * (Height -1) * fPixelSize);
7698 for Row := 0 to Height -1 do begin
7699 Move(SourceData^, TempDestData^, fRowSize);
7700 Dec(TempDestData, fRowSize);
7701 Inc(SourceData, fRowSize);
7703 SetDataPointer(DestData, Format);
7712 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7713 //TglBitmap2D - ToNormalMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7714 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7716 TMatrixItem = record
7721 PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
7722 TglBitmapToNormalMapRec = Record
7724 Heights: array of Single;
7725 MatrixU : array of TMatrixItem;
7726 MatrixV : array of TMatrixItem;
7730 ONE_OVER_255 = 1 / 255;
7732 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7733 procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
7737 with FuncRec do begin
7739 Source.Data.r * LUMINANCE_WEIGHT_R +
7740 Source.Data.g * LUMINANCE_WEIGHT_G +
7741 Source.Data.b * LUMINANCE_WEIGHT_B;
7742 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255;
7746 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7747 procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
7750 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
7753 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7754 procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
7756 TVec = Array[0..2] of Single;
7763 function GetHeight(X, Y: Integer): Single;
7765 with FuncRec do begin
7766 X := Max(0, Min(Size.X -1, X));
7767 Y := Max(0, Min(Size.Y -1, Y));
7768 result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
7773 with FuncRec do begin
7774 with PglBitmapToNormalMapRec(Args)^ do begin
7776 for Idx := Low(MatrixU) to High(MatrixU) do
7777 du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
7780 for Idx := Low(MatrixU) to High(MatrixU) do
7781 dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
7783 Vec[0] := -du * Scale;
7784 Vec[1] := -dv * Scale;
7789 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
7790 if Len <> 0 then begin
7791 Vec[0] := Vec[0] * Len;
7792 Vec[1] := Vec[1] * Len;
7793 Vec[2] := Vec[2] * Len;
7797 Dest.Data.r := Trunc((Vec[0] + 1) * 127.5);
7798 Dest.Data.g := Trunc((Vec[1] + 1) * 127.5);
7799 Dest.Data.b := Trunc((Vec[2] + 1) * 127.5);
7803 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7804 procedure TglBitmap2D.ToNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
7806 Rec: TglBitmapToNormalMapRec;
7808 procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
7810 if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
7811 Matrix[Index].X := X;
7812 Matrix[Index].Y := Y;
7813 Matrix[Index].W := W;
7819 if not FormatIsUncompressed(InternalFormat) then
7820 raise EglBitmapUnsupportedFormatFormat.Create('TglBitmap2D.ToNormalMap - ' + UNSUPPORTED_FORMAT);
7823 if aScale > 100 then
7825 else if aScale < -100 then
7828 Rec.Scale := aScale;
7830 SetLength(Rec.Heights, Width * Height);
7834 SetLength(Rec.MatrixU, 2);
7835 SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
7836 SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
7838 SetLength(Rec.MatrixV, 2);
7839 SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
7840 SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
7844 SetLength(Rec.MatrixU, 6);
7845 SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
7846 SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
7847 SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
7848 SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
7849 SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
7850 SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
7852 SetLength(Rec.MatrixV, 6);
7853 SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
7854 SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
7855 SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
7856 SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
7857 SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
7858 SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
7862 SetLength(Rec.MatrixU, 6);
7863 SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
7864 SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
7865 SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
7866 SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
7867 SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
7868 SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
7870 SetLength(Rec.MatrixV, 6);
7871 SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
7872 SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
7873 SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
7874 SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
7875 SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
7876 SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
7880 SetLength(Rec.MatrixU, 20);
7881 SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
7882 SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
7883 SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
7884 SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
7885 SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
7886 SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
7887 SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
7888 SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
7889 SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
7890 SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
7891 SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
7892 SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
7893 SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
7894 SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
7895 SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
7896 SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
7897 SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
7898 SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
7899 SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
7900 SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
7902 SetLength(Rec.MatrixV, 20);
7903 SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
7904 SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
7905 SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
7906 SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
7907 SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
7908 SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
7909 SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
7910 SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
7911 SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
7912 SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
7913 SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
7914 SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
7915 SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
7916 SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
7917 SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
7918 SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
7919 SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
7920 SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
7921 SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
7922 SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
7927 if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
7928 AddFunc(glBitmapToNormalMapPrepareAlphaFunc, false, PtrInt(@Rec))
7930 AddFunc(glBitmapToNormalMapPrepareFunc, false, PtrInt(@Rec));
7931 AddFunc(glBitmapToNormalMapFunc, false, PtrInt(@Rec));
7933 SetLength(Rec.Heights, 0);
7946 procedure TglBitmap1D.SetDataPointer(Data: pByte; Format: TglBitmapInternalFormat; Width, Height: Integer);
7951 if Height > 1 then begin
7952 // extract first line of the data
7953 Size := FormatGetImageSize(glBitmapPosition(Width), Format);
7954 GetMem(pTemp, Size);
7956 Move(Data^, pTemp^, Size);
7963 inherited SetDataPointer(pTemp, Format, Width);
7965 if FormatIsUncompressed(Format) then begin
7966 fUnmapFunc := FormatGetUnMapFunc(Format);
7967 fGetPixelFunc := GetPixel1DUnmap;
7972 procedure TglBitmap1D.GetPixel1DUnmap(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
7977 Inc(pTemp, Pos.X * fPixelSize);
7979 fUnmapFunc(pTemp, Pixel);
7983 function TglBitmap1D.FlipHorz: Boolean;
7986 pTempDest, pDest, pSource: pByte;
7988 result := inherited FlipHorz;
7990 if Assigned(Data) and FormatIsUncompressed(InternalFormat) then begin
7993 GetMem(pDest, fRowSize);
7997 Inc(pTempDest, fRowSize);
7998 for Col := 0 to Width -1 do begin
7999 Move(pSource^, pTempDest^, fPixelSize);
8001 Inc(pSource, fPixelSize);
8002 Dec(pTempDest, fPixelSize);
8005 SetDataPointer(pDest, InternalFormat);
8015 procedure TglBitmap1D.UploadData (Target, Format, InternalFormat, Typ: Cardinal; BuildWithGlu: Boolean);
8018 if Self.InternalFormat in [ifDXT1, ifDXT3, ifDXT5] then
8019 glCompressedTexImage1D(Target, 0, InternalFormat, Width, 0, Trunc(Width * FormatGetSize(Self.InternalFormat)), Data)
8023 if BuildWithGlu then
8024 gluBuild1DMipmaps(Target, InternalFormat, Width, Format, Typ, Data)
8026 glTexImage1D(Target, 0, InternalFormat, Width, 0, Format, Typ, Data);
8029 if (FreeDataAfterGenTexture) then
8034 procedure TglBitmap1D.GenTexture(TestTextureSize: Boolean);
8036 BuildWithGlu, TexRec: Boolean;
8037 glFormat, glInternalFormat, glType: Cardinal;
8040 if Assigned(Data) then begin
8041 // Check Texture Size
8042 if (TestTextureSize) then begin
8043 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
8045 if (Width > TexSize) then
8046 raise EglBitmapSizeToLargeException.Create('TglBitmap1D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
8048 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
8049 (Target = GL_TEXTURE_RECTANGLE_ARB);
8051 if not (IsPowerOfTwo (Width) or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
8052 raise EglBitmapNonPowerOfTwoException.Create('TglBitmap1D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8057 SetupParameters(BuildWithGlu);
8058 SelectFormat(InternalFormat, glFormat, glInternalFormat, glType);
8060 UploadData(Target, glFormat, glInternalFormat, glType, BuildWithGlu);
8063 glAreTexturesResident(1, @fID, @fIsResident);
8068 procedure TglBitmap1D.AfterConstruction;
8072 Target := GL_TEXTURE_1D;
8076 { TglBitmapCubeMap }
8078 procedure TglBitmapCubeMap.AfterConstruction;
8082 if not (GL_VERSION_1_3 or GL_ARB_texture_cube_map or GL_EXT_texture_cube_map) then
8083 raise EglBitmapException.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
8085 SetWrap; // set all to GL_CLAMP_TO_EDGE
8086 Target := GL_TEXTURE_CUBE_MAP;
8087 fGenMode := GL_REFLECTION_MAP;
8091 procedure TglBitmapCubeMap.Bind(EnableTexCoordsGen, EnableTextureUnit: Boolean);
8093 inherited Bind (EnableTextureUnit);
8095 if EnableTexCoordsGen then begin
8096 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, fGenMode);
8097 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, fGenMode);
8098 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, fGenMode);
8099 glEnable(GL_TEXTURE_GEN_S);
8100 glEnable(GL_TEXTURE_GEN_T);
8101 glEnable(GL_TEXTURE_GEN_R);
8106 procedure TglBitmapCubeMap.GenerateCubeMap(CubeTarget: Cardinal; TestTextureSize: Boolean);
8108 glFormat, glInternalFormat, glType: Cardinal;
8109 BuildWithGlu: Boolean;
8112 // Check Texture Size
8113 if (TestTextureSize) then begin
8114 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @TexSize);
8116 if ((Height > TexSize) or (Width > TexSize)) then
8117 raise EglBitmapSizeToLargeException.Create('TglBitmapCubeMap.GenTexture - The size for the Cubemap is to large. It''s may be not conform with the Hardware.');
8119 if not ((IsPowerOfTwo (Height) and IsPowerOfTwo (Width)) or GL_VERSION_2_0 or GL_ARB_texture_non_power_of_two) then
8120 raise EglBitmapNonPowerOfTwoException.Create('TglBitmapCubeMap.GenTexture - Cubemaps dosn''t support non power of two texture.');
8124 if ID = 0 then begin
8126 SetupParameters(BuildWithGlu);
8129 SelectFormat(InternalFormat, glFormat, glInternalFormat, glType);
8131 UploadData (CubeTarget, glFormat, glInternalFormat, glType, BuildWithGlu);
8135 procedure TglBitmapCubeMap.GenTexture(TestTextureSize: Boolean);
8137 Assert(false, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
8141 procedure TglBitmapCubeMap.Unbind(DisableTexCoordsGen,
8142 DisableTextureUnit: Boolean);
8144 inherited Unbind (DisableTextureUnit);
8146 if DisableTexCoordsGen then begin
8147 glDisable(GL_TEXTURE_GEN_S);
8148 glDisable(GL_TEXTURE_GEN_T);
8149 glDisable(GL_TEXTURE_GEN_R);
8154 { TglBitmapNormalMap }
8157 TVec = Array[0..2] of Single;
8158 TglBitmapNormalMapGetVectorFunc = procedure (var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
8160 PglBitmapNormalMapRec = ^TglBitmapNormalMapRec;
8161 TglBitmapNormalMapRec = record
8163 Func: TglBitmapNormalMapGetVectorFunc;
8167 procedure glBitmapNormalMapPosX(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
8170 Vec[1] := - (Position.Y + 0.5 - HalfSize);
8171 Vec[2] := - (Position.X + 0.5 - HalfSize);
8175 procedure glBitmapNormalMapNegX(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
8177 Vec[0] := - HalfSize;
8178 Vec[1] := - (Position.Y + 0.5 - HalfSize);
8179 Vec[2] := Position.X + 0.5 - HalfSize;
8183 procedure glBitmapNormalMapPosY(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
8185 Vec[0] := Position.X + 0.5 - HalfSize;
8187 Vec[2] := Position.Y + 0.5 - HalfSize;
8191 procedure glBitmapNormalMapNegY(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
8193 Vec[0] := Position.X + 0.5 - HalfSize;
8194 Vec[1] := - HalfSize;
8195 Vec[2] := - (Position.Y + 0.5 - HalfSize);
8199 procedure glBitmapNormalMapPosZ(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
8201 Vec[0] := Position.X + 0.5 - HalfSize;
8202 Vec[1] := - (Position.Y + 0.5 - HalfSize);
8207 procedure glBitmapNormalMapNegZ(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
8209 Vec[0] := - (Position.X + 0.5 - HalfSize);
8210 Vec[1] := - (Position.Y + 0.5 - HalfSize);
8211 Vec[2] := - HalfSize;
8215 procedure glBitmapNormalMapFunc(var FuncRec: TglBitmapFunctionRec);
8220 with FuncRec do begin
8221 with PglBitmapNormalMapRec (CustomData)^ do begin
8222 Func(Vec, Position, HalfSize);
8225 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
8226 if Len <> 0 then begin
8227 Vec[0] := Vec[0] * Len;
8228 Vec[1] := Vec[1] * Len;
8229 Vec[2] := Vec[2] * Len;
8232 // Scale Vector and AddVectro
8233 Vec[0] := Vec[0] * 0.5 + 0.5;
8234 Vec[1] := Vec[1] * 0.5 + 0.5;
8235 Vec[2] := Vec[2] * 0.5 + 0.5;
8239 Dest.Red := Round(Vec[0] * 255);
8240 Dest.Green := Round(Vec[1] * 255);
8241 Dest.Blue := Round(Vec[2] * 255);
8246 procedure TglBitmapNormalMap.AfterConstruction;
8250 fGenMode := GL_NORMAL_MAP;
8254 procedure TglBitmapNormalMap.GenerateNormalMap(Size: Integer;
8255 TestTextureSize: Boolean);
8257 Rec: TglBitmapNormalMapRec;
8258 SizeRec: TglBitmapPixelPosition;
8260 Rec.HalfSize := Size div 2;
8262 FreeDataAfterGenTexture := false;
8264 SizeRec.Fields := [ffX, ffY];
8269 Rec.Func := glBitmapNormalMapPosX;
8270 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
8271 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X, TestTextureSize);
8274 Rec.Func := glBitmapNormalMapNegX;
8275 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
8276 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, TestTextureSize);
8279 Rec.Func := glBitmapNormalMapPosY;
8280 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
8281 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, TestTextureSize);
8284 Rec.Func := glBitmapNormalMapNegY;
8285 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
8286 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, TestTextureSize);
8289 Rec.Func := glBitmapNormalMapPosZ;
8290 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
8291 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, TestTextureSize);
8294 Rec.Func := glBitmapNormalMapNegZ;
8295 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
8296 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, TestTextureSize);
8301 glBitmapSetDefaultFormat(tfEmpty);
8302 glBitmapSetDefaultMipmap(mmMipmap);
8303 glBitmapSetDefaultFilter(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
8304 glBitmapSetDefaultWrap (GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
8306 glBitmapSetDefaultFreeDataAfterGenTexture(true);
8307 glBitmapSetDefaultDeleteTextureOnFree (true);
8309 TFormatDescriptor.Init;
8311 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
8312 OpenGLInitialized := false;
8313 InitOpenGLCS := TCriticalSection.Create;
8317 TFormatDescriptor.Finalize;
8319 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
8320 FreeAndNil(InitOpenGLCS);