1 { glBitmap by Steffen Xonna aka Lossy eX (2003-2008)
2 http://www.opengl24.de/index.php?cat=header&file=glbitmap
4 modified by Delphi OpenGL Community (http://delphigl.com/) (2013)
6 The contents of this file are used with permission, subject to
7 the Mozilla Public License Version 1.1 (the "License"); you may
8 not use this file except in compliance with the License. You may
9 obtain a copy of the License at
10 http://www.mozilla.org/MPL/MPL-1.1.html
12 The glBitmap is a Delphi/FPC unit that contains several wrapper classes
13 to manage OpenGL texture objects. Below you can find a list of the main
14 functionality of this classes:
15 - load texture data from file (e.g. BMP, TGA, DDS, PNG, JPEG, ...)
16 - load texture data from several other image objects (e.g. TBitmap, TLazIntfImage, SDL Surface)
17 - save texture data to file (e.g. BMP, TGA, DDS, PNG, JPEG, ...)
18 - save texture data to several other image objects (e.g. TBitmap, TLazIntfImage, SDL Surface)
19 - support for many texture formats (e.g. RGB8, BGR8, RGBA8, BGRA8, ...)
20 - manage texture properties (e.g. Filter, Clamp, Mipmap, ...)
21 - upload texture data to video card
22 - download texture data from video card
23 - manipulate texture data (e.g. add alpha, remove alpha, convert to other format, switch RGB, ...) }
27 // Please uncomment the defines below to configure the glBitmap to your preferences.
28 // If you have configured the unit you can uncomment the warning above.
29 {$MESSAGE error 'Hey. I''m the glBitmap.pas and i need to be configured. My master tell me your preferences! ;)'}
31 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
32 // Preferences ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
33 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
34 // enable support for OpenGL ES 1.1
35 {.$DEFINE OPENGL_ES_1_1}
37 // enable support for OpenGL ES 2.0
38 {.$DEFINE OPENGL_ES_2_0}
40 // enable support for OpenGL ES 3.0
41 {.$DEFINE OPENGL_ES_3_0}
43 // enable support for all OpenGL ES extensions
44 {.$DEFINE OPENGL_ES_EXT}
47 // activate to enable build-in OpenGL support with statically linked methods
48 // use dglOpenGL.pas if not enabled
49 {.$DEFINE GLB_NATIVE_OGL_STATIC}
51 // activate to enable build-in OpenGL support with dynamically linked methods
52 // use dglOpenGL.pas if not enabled
53 {.$DEFINE GLB_NATIVE_OGL_DYNAMIC}
56 // activate to enable the support for SDL_surfaces
59 // activate to enable the support for Delphi (including support for Delphi's (not Lazarus') TBitmap)
62 // activate to enable the support for TLazIntfImage from Lazarus
63 {.$DEFINE GLB_LAZARUS}
67 // activate to enable the support of SDL_image to load files. (READ ONLY)
68 // If you enable SDL_image all other libraries will be ignored!
69 {.$DEFINE GLB_SDL_IMAGE}
73 // activate to enable Lazarus TPortableNetworkGraphic support
74 // if you enable this pngImage and libPNG will be ignored
75 {.$DEFINE GLB_LAZ_PNG}
77 // activate to enable png support with the unit pngimage -> http://pngdelphi.sourceforge.net/
78 // if you enable pngimage the libPNG will be ignored
79 {.$DEFINE GLB_PNGIMAGE}
81 // activate to use the libPNG -> http://www.libpng.org/
82 // You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libpng
83 {.$DEFINE GLB_LIB_PNG}
87 // activate to enable Lazarus TJPEGImage support
88 // if you enable this delphi jpegs and libJPEG will be ignored
89 {.$DEFINE GLB_LAZ_JPEG}
91 // if you enable delphi jpegs the libJPEG will be ignored
92 {.$DEFINE GLB_DELPHI_JPEG}
94 // activate to use the libJPEG -> http://www.ijg.org/
95 // You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libjpeg
96 {.$DEFINE GLB_LIB_JPEG}
99 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
100 // PRIVATE: do not change anything! //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
101 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
117 {$IF DEFINED(WIN32) or DEFINED(WIN64) or DEFINED(WINDOWS)}
119 {$ELSEIF DEFINED(LINUX)}
124 {$IF DEFINED(OPENGL_ES_EXT)} {$DEFINE OPENGL_ES_1_1} {$IFEND}
125 {$IF DEFINED(OPENGL_ES_3_0)} {$DEFINE OPENGL_ES_2_0} {$IFEND}
126 {$IF DEFINED(OPENGL_ES_2_0)} {$DEFINE OPENGL_ES_1_1} {$IFEND}
127 {$IF DEFINED(OPENGL_ES_1_1)} {$DEFINE OPENGL_ES} {$IFEND}
129 // native OpenGL Support
130 {$IF DEFINED(GLB_NATIVE_OGL_STATIC) OR DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
132 {$ERROR 'native OpenGL is not supported yet for OpenGL ES, please use dglOpenGLES.pas instead'}
134 {$DEFINE GLB_NATIVE_OGL}
138 // checking define combinations
140 {$IFDEF GLB_SDL_IMAGE}
142 {$MESSAGE warn 'SDL_image won''t work without SDL. SDL will be activated.'}
147 {$MESSAGE warn 'The Lazarus TPortableNetworkGraphics will be ignored because you are using SDL_image.'}
151 {$IFDEF GLB_PNGIMAGE}
152 {$MESSAGE warn 'The unit pngimage will be ignored because you are using SDL_image.'}
153 {$undef GLB_PNGIMAGE}
156 {$IFDEF GLB_LAZ_JPEG}
157 {$MESSAGE warn 'The Lazarus TJPEGImage will be ignored because you are using SDL_image.'}
158 {$undef GLB_LAZ_JPEG}
161 {$IFDEF GLB_DELPHI_JPEG}
162 {$MESSAGE warn 'The unit JPEG will be ignored because you are using SDL_image.'}
163 {$undef GLB_DELPHI_JPEG}
167 {$MESSAGE warn 'The library libPNG will be ignored because you are using SDL_image.'}
171 {$IFDEF GLB_LIB_JPEG}
172 {$MESSAGE warn 'The library libJPEG will be ignored because you are using SDL_image.'}
173 {$undef GLB_LIB_JPEG}
176 {$DEFINE GLB_SUPPORT_PNG_READ}
177 {$DEFINE GLB_SUPPORT_JPEG_READ}
180 // Lazarus TPortableNetworkGraphic
182 {$IFNDEF GLB_LAZARUS}
183 {$MESSAGE warn 'Lazarus TPortableNetworkGraphic won''t work without Lazarus. Lazarus will be activated.'}
184 {$DEFINE GLB_LAZARUS}
187 {$IFDEF GLB_PNGIMAGE}
188 {$MESSAGE warn 'The pngimage will be ignored if you are using Lazarus TPortableNetworkGraphic.'}
189 {$undef GLB_PNGIMAGE}
193 {$MESSAGE warn 'The library libPNG will be ignored if you are using Lazarus TPortableNetworkGraphic.'}
197 {$DEFINE GLB_SUPPORT_PNG_READ}
198 {$DEFINE GLB_SUPPORT_PNG_WRITE}
202 {$IFDEF GLB_PNGIMAGE}
204 {$MESSAGE warn 'The library libPNG will be ignored if you are using pngimage.'}
208 {$DEFINE GLB_SUPPORT_PNG_READ}
209 {$DEFINE GLB_SUPPORT_PNG_WRITE}
214 {$DEFINE GLB_SUPPORT_PNG_READ}
215 {$DEFINE GLB_SUPPORT_PNG_WRITE}
218 // Lazarus TJPEGImage
219 {$IFDEF GLB_LAZ_JPEG}
220 {$IFNDEF GLB_LAZARUS}
221 {$MESSAGE warn 'Lazarus TJPEGImage won''t work without Lazarus. Lazarus will be activated.'}
222 {$DEFINE GLB_LAZARUS}
225 {$IFDEF GLB_DELPHI_JPEG}
226 {$MESSAGE warn 'The Delphi JPEGImage will be ignored if you are using the Lazarus TJPEGImage.'}
227 {$undef GLB_DELPHI_JPEG}
230 {$IFDEF GLB_LIB_JPEG}
231 {$MESSAGE warn 'The library libJPEG will be ignored if you are using the Lazarus TJPEGImage.'}
232 {$undef GLB_LIB_JPEG}
235 {$DEFINE GLB_SUPPORT_JPEG_READ}
236 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
240 {$IFDEF GLB_DELPHI_JPEG}
241 {$IFDEF GLB_LIB_JPEG}
242 {$MESSAGE warn 'The library libJPEG will be ignored if you are using the unit JPEG.'}
243 {$undef GLB_LIB_JPEG}
246 {$DEFINE GLB_SUPPORT_JPEG_READ}
247 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
251 {$IFDEF GLB_LIB_JPEG}
252 {$DEFINE GLB_SUPPORT_JPEG_READ}
253 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
257 {$IF DEFINED(GLB_NATIVE_OGL_STATIC) AND DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
258 {$MESSAGE warn 'GLB_NATIVE_OGL_STATIC will be ignored because you enabled GLB_NATIVE_OGL_DYNAMIC'}
272 {$IFNDEF GLB_NATIVE_OGL}
273 {$IFDEF OPENGL_ES} dglOpenGLES,
274 {$ELSE} dglOpenGL, {$ENDIF}
276 {$IF DEFINED(GLB_WIN) AND
277 (DEFINED(GLB_NATIVE_OGL) OR
278 DEFINED(GLB_DELPHI))} windows, {$IFEND}
280 {$IFDEF GLB_SDL} SDL, {$ENDIF}
281 {$IFDEF GLB_LAZARUS} IntfGraphics, GraphType, Graphics, {$ENDIF}
282 {$IFDEF GLB_DELPHI} Dialogs, Graphics, Types, {$ENDIF}
284 {$IFDEF GLB_SDL_IMAGE} SDL_image, {$ENDIF}
285 {$IFDEF GLB_PNGIMAGE} pngimage, {$ENDIF}
286 {$IFDEF GLB_LIB_PNG} libPNG, {$ENDIF}
287 {$IFDEF GLB_DELPHI_JPEG} JPEG, {$ENDIF}
288 {$IFDEF GLB_LIB_JPEG} libJPEG, {$ENDIF}
292 {$IFDEF GLB_NATIVE_OGL}
301 GL_EXTENSIONS = $1F03;
303 GL_TEXTURE_1D = $0DE0;
304 GL_TEXTURE_2D = $0DE1;
305 GL_TEXTURE_RECTANGLE = $84F5;
307 GL_NORMAL_MAP = $8511;
308 GL_TEXTURE_CUBE_MAP = $8513;
309 GL_REFLECTION_MAP = $8512;
310 GL_TEXTURE_CUBE_MAP_POSITIVE_X = $8515;
311 GL_TEXTURE_CUBE_MAP_NEGATIVE_X = $8516;
312 GL_TEXTURE_CUBE_MAP_POSITIVE_Y = $8517;
313 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = $8518;
314 GL_TEXTURE_CUBE_MAP_POSITIVE_Z = $8519;
315 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = $851A;
317 GL_TEXTURE_WIDTH = $1000;
318 GL_TEXTURE_HEIGHT = $1001;
319 GL_TEXTURE_INTERNAL_FORMAT = $1003;
320 GL_TEXTURE_SWIZZLE_RGBA = $8E46;
327 GL_TEXTURE_GEN_S = $0C60;
328 GL_TEXTURE_GEN_T = $0C61;
329 GL_TEXTURE_GEN_R = $0C62;
330 GL_TEXTURE_GEN_Q = $0C63;
342 GL_LUMINANCE = $1909;
343 GL_LUMINANCE4 = $803F;
344 GL_LUMINANCE8 = $8040;
345 GL_LUMINANCE12 = $8041;
346 GL_LUMINANCE16 = $8042;
348 GL_LUMINANCE_ALPHA = $190A;
349 GL_LUMINANCE4_ALPHA4 = $8043;
350 GL_LUMINANCE6_ALPHA2 = $8044;
351 GL_LUMINANCE8_ALPHA8 = $8045;
352 GL_LUMINANCE12_ALPHA4 = $8046;
353 GL_LUMINANCE12_ALPHA12 = $8047;
354 GL_LUMINANCE16_ALPHA16 = $8048;
377 GL_DEPTH_COMPONENT = $1902;
378 GL_DEPTH_COMPONENT16 = $81A5;
379 GL_DEPTH_COMPONENT24 = $81A6;
380 GL_DEPTH_COMPONENT32 = $81A7;
382 GL_COMPRESSED_RGB = $84ED;
383 GL_COMPRESSED_RGBA = $84EE;
384 GL_COMPRESSED_RGB_S3TC_DXT1_EXT = $83F0;
385 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = $83F1;
386 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = $83F2;
387 GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = $83F3;
389 GL_UNSIGNED_BYTE = $1401;
390 GL_UNSIGNED_BYTE_3_3_2 = $8032;
391 GL_UNSIGNED_BYTE_2_3_3_REV = $8362;
393 GL_UNSIGNED_SHORT = $1403;
394 GL_UNSIGNED_SHORT_5_6_5 = $8363;
395 GL_UNSIGNED_SHORT_4_4_4_4 = $8033;
396 GL_UNSIGNED_SHORT_5_5_5_1 = $8034;
397 GL_UNSIGNED_SHORT_5_6_5_REV = $8364;
398 GL_UNSIGNED_SHORT_4_4_4_4_REV = $8365;
399 GL_UNSIGNED_SHORT_1_5_5_5_REV = $8366;
401 GL_UNSIGNED_INT = $1405;
402 GL_UNSIGNED_INT_8_8_8_8 = $8035;
403 GL_UNSIGNED_INT_10_10_10_2 = $8036;
404 GL_UNSIGNED_INT_8_8_8_8_REV = $8367;
405 GL_UNSIGNED_INT_2_10_10_10_REV = $8368;
408 GL_TEXTURE_MAG_FILTER = $2800;
409 GL_TEXTURE_MIN_FILTER = $2801;
411 GL_NEAREST_MIPMAP_NEAREST = $2700;
412 GL_NEAREST_MIPMAP_LINEAR = $2702;
414 GL_LINEAR_MIPMAP_NEAREST = $2701;
415 GL_LINEAR_MIPMAP_LINEAR = $2703;
418 GL_TEXTURE_WRAP_S = $2802;
419 GL_TEXTURE_WRAP_T = $2803;
420 GL_TEXTURE_WRAP_R = $8072;
423 GL_CLAMP_TO_EDGE = $812F;
424 GL_CLAMP_TO_BORDER = $812D;
425 GL_MIRRORED_REPEAT = $8370;
428 GL_GENERATE_MIPMAP = $8191;
429 GL_TEXTURE_BORDER_COLOR = $1004;
430 GL_MAX_TEXTURE_SIZE = $0D33;
431 GL_PACK_ALIGNMENT = $0D05;
432 GL_UNPACK_ALIGNMENT = $0CF5;
434 GL_TEXTURE_MAX_ANISOTROPY_EXT = $84FE;
435 GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = $84FF;
436 GL_MAX_CUBE_MAP_TEXTURE_SIZE = $851C;
437 GL_TEXTURE_GEN_MODE = $2500;
439 {$IF DEFINED(GLB_WIN)}
440 libglu = 'glu32.dll';
441 libopengl = 'opengl32.dll';
442 {$ELSEIF DEFINED(GLB_LINUX)}
443 libglu = 'libGLU.so.1';
444 libopengl = 'libGL.so.1';
448 GLboolean = BYTEBOOL;
456 PGLboolean = ^GLboolean;
461 TglCompressedTexImage1D = procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
462 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}
463 TglGetCompressedTexImage = procedure(target: GLenum; level: GLint; img: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
465 {$IF DEFINED(GLB_WIN)}
466 TwglGetProcAddress = function (ProcName: PAnsiChar): Pointer; stdcall;
467 {$ELSEIF DEFINED(GLB_LINUX)}
468 TglXGetProcAddress = function(ProcName: PAnsiChar): Pointer; cdecl;
469 TglXGetProcAddressARB = function(const name: PAnsiChar): pointer; cdecl;
472 {$IF DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
473 TglEnable = procedure(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
474 TglDisable = procedure(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
476 TglGetString = function(name: GLenum): PAnsiChar; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
477 TglGetIntegerv = procedure(pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
479 TglTexParameteri = procedure(target: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
480 TglTexParameteriv = procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
481 TglTexParameterfv = procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
482 TglGetTexParameteriv = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
483 TglGetTexParameterfv = procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
484 TglGetTexLevelParameteriv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
485 TglGetTexLevelParameterfv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
487 TglTexGeni = procedure(coord: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
488 TglGenTextures = procedure(n: GLsizei; textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
489 TglBindTexture = procedure(target: GLenum; texture: GLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
490 TglDeleteTextures = procedure(n: GLsizei; const textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
492 TglAreTexturesResident = function(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
493 TglReadPixels = procedure(x: GLint; y: GLint; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
494 TglPixelStorei = procedure(pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
496 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}
497 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}
498 TglGetTexImage = procedure(target: GLenum; level: GLint; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
500 TgluBuild1DMipmaps = function(target: GLEnum; components, width: GLint; format, atype: GLEnum; const data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
501 TgluBuild2DMipmaps = function(target: GLEnum; components, width, height: GLint; format, atype: GLEnum; const Data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
503 {$ELSEIF DEFINED(GLB_NATIVE_OGL_STATIC)}
504 procedure glEnable(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
505 procedure glDisable(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
507 function glGetString(name: GLenum): PAnsiChar; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
508 procedure glGetIntegerv(pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
510 procedure glTexParameteri(target: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
511 procedure glTexParameteriv(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
512 procedure glTexParameterfv(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
513 procedure glGetTexParameteriv(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
514 procedure glGetTexParameterfv(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
515 procedure glGetTexLevelParameteriv(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
516 procedure glGetTexLevelParameterfv(target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
518 procedure glTexGeni(coord: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
519 procedure glGenTextures(n: GLsizei; textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
520 procedure glBindTexture(target: GLenum; texture: GLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
521 procedure glDeleteTextures(n: GLsizei; const textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
523 function glAreTexturesResident(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
524 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;
525 procedure glPixelStorei(pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
527 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;
528 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;
529 procedure glGetTexImage(target: GLenum; level: GLint; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
531 function gluBuild1DMipmaps(target: GLEnum; components, width: GLint; format, atype: GLEnum; const data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libglu;
532 function gluBuild2DMipmaps(target: GLEnum; components, width, height: GLint; format, atype: GLEnum; const Data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libglu;
542 GL_SGIS_generate_mipmap,
544 GL_ARB_texture_border_clamp,
545 GL_ARB_texture_mirrored_repeat,
546 GL_ARB_texture_rectangle,
547 GL_ARB_texture_non_power_of_two,
548 GL_ARB_texture_swizzle,
549 GL_ARB_texture_cube_map,
551 GL_IBM_texture_mirrored_repeat,
553 GL_NV_texture_rectangle,
555 GL_EXT_texture_edge_clamp,
556 GL_EXT_texture_rectangle,
557 GL_EXT_texture_swizzle,
558 GL_EXT_texture_cube_map,
559 GL_EXT_texture_filter_anisotropic: Boolean;
561 glCompressedTexImage1D: TglCompressedTexImage1D;
562 glCompressedTexImage2D: TglCompressedTexImage2D;
563 glGetCompressedTexImage: TglGetCompressedTexImage;
565 {$IF DEFINED(GLB_WIN)}
566 wglGetProcAddress: TwglGetProcAddress;
567 {$ELSEIF DEFINED(GLB_LINUX)}
568 glXGetProcAddress: TglXGetProcAddress;
569 glXGetProcAddressARB: TglXGetProcAddress;
572 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
574 glDisable: TglDisable;
576 glGetString: TglGetString;
577 glGetIntegerv: TglGetIntegerv;
579 glTexParameteri: TglTexParameteri;
580 glTexParameteriv: TglTexParameteriv;
581 glTexParameterfv: TglTexParameterfv;
582 glGetTexParameteriv: TglGetTexParameteriv;
583 glGetTexParameterfv: TglGetTexParameterfv;
584 glGetTexLevelParameteriv: TglGetTexLevelParameteriv;
585 glGetTexLevelParameterfv: TglGetTexLevelParameterfv;
587 glTexGeni: TglTexGeni;
588 glGenTextures: TglGenTextures;
589 glBindTexture: TglBindTexture;
590 glDeleteTextures: TglDeleteTextures;
592 glAreTexturesResident: TglAreTexturesResident;
593 glReadPixels: TglReadPixels;
594 glPixelStorei: TglPixelStorei;
596 glTexImage1D: TglTexImage1D;
597 glTexImage2D: TglTexImage2D;
598 glGetTexImage: TglGetTexImage;
600 gluBuild1DMipmaps: TgluBuild1DMipmaps;
601 gluBuild2DMipmaps: TgluBuild2DMipmaps;
607 QWord = System.UInt64;
615 { type that describes the format of the data stored in a texture.
616 the name of formats is composed of the following constituents:
618 - channel (e.g. R, G, B, A or Alpha, Luminance or X (reserved))
619 - width of the chanel in bit (4, 8, 16, ...)
620 - data type (e.g. ub, us, ui)
621 - number of elements of data types }
625 tfAlpha4ub1, //< 1 x unsigned byte
626 tfAlpha8ub1, //< 1 x unsigned byte
627 tfAlpha16us1, //< 1 x unsigned short
629 tfLuminance4ub1, //< 1 x unsigned byte
630 tfLuminance8ub1, //< 1 x unsigned byte
631 tfLuminance16us1, //< 1 x unsigned short
633 tfLuminance4Alpha4ub2, //< 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
634 tfLuminance6Alpha2ub2, //< 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
635 tfLuminance8Alpha8ub2, //< 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
636 tfLuminance12Alpha4us2, //< 1 x unsigned short (lum), 1 x unsigned short (alpha)
637 tfLuminance16Alpha16us2, //< 1 x unsigned short (lum), 1 x unsigned short (alpha)
639 tfR3G3B2ub1, //< 1 x unsigned byte (3bit red, 3bit green, 2bit blue)
640 tfRGBX4us1, //< 1 x unsigned short (4bit red, 4bit green, 4bit blue, 4bit reserverd)
641 tfXRGB4us1, //< 1 x unsigned short (4bit reserved, 4bit red, 4bit green, 4bit blue)
642 tfR5G6B5us1, //< 1 x unsigned short (5bit red, 6bit green, 5bit blue)
643 tfRGB5X1us1, //< 1 x unsigned short (5bit red, 5bit green, 5bit blue, 1bit reserved)
644 tfX1RGB5us1, //< 1 x unsigned short (1bit reserved, 5bit red, 5bit green, 5bit blue)
645 tfRGB8ub3, //< 1 x unsigned byte (red), 1 x unsigned byte (green), 1 x unsigned byte (blue)
646 tfRGBX8ui1, //< 1 x unsigned int (8bit red, 8bit green, 8bit blue, 8bit reserved)
647 tfXRGB8ui1, //< 1 x unsigned int (8bit reserved, 8bit red, 8bit green, 8bit blue)
648 tfRGB10X2ui1, //< 1 x unsigned int (10bit red, 10bit green, 10bit blue, 2bit reserved)
649 tfX2RGB10ui1, //< 1 x unsigned int (2bit reserved, 10bit red, 10bit green, 10bit blue)
650 tfRGB16us3, //< 1 x unsigned short (red), 1 x unsigned short (green), 1 x unsigned short (blue)
652 tfRGBA4us1, //< 1 x unsigned short (4bit red, 4bit green, 4bit blue, 4bit alpha)
653 tfARGB4us1, //< 1 x unsigned short (4bit alpha, 4bit red, 4bit green, 4bit blue)
654 tfRGB5A1us1, //< 1 x unsigned short (5bit red, 5bit green, 5bit blue, 1bit alpha)
655 tfA1RGB5us1, //< 1 x unsigned short (1bit alpha, 5bit red, 5bit green, 5bit blue)
656 tfRGBA8ui1, //< 1 x unsigned int (8bit red, 8bit green, 8bit blue, 8 bit alpha)
657 tfARGB8ui1, //< 1 x unsigned int (8 bit alpha, 8bit red, 8bit green, 8bit blue)
658 tfRGBA8ub4, //< 1 x unsigned byte (red), 1 x unsigned byte (green), 1 x unsigned byte (blue), 1 x unsigned byte (alpha)
659 tfRGB10A2ui1, //< 1 x unsigned int (10bit red, 10bit green, 10bit blue, 2bit alpha)
660 tfA2RGB10ui1, //< 1 x unsigned int (2bit alpha, 10bit red, 10bit green, 10bit blue)
661 tfRGBA16us4, //< 1 x unsigned short (red), 1 x unsigned short (green), 1 x unsigned short (blue), 1 x unsigned short (alpha)
663 tfBGRX4us1, //< 1 x unsigned short (4bit blue, 4bit green, 4bit red, 4bit reserved)
664 tfXBGR4us1, //< 1 x unsigned short (4bit reserved, 4bit blue, 4bit green, 4bit red)
665 tfB5G6R5us1, //< 1 x unsigned short (5bit blue, 6bit green, 5bit red)
666 tfBGR5X1us1, //< 1 x unsigned short (5bit blue, 5bit green, 5bit red, 1bit reserved)
667 tfX1BGR5us1, //< 1 x unsigned short (1bit reserved, 5bit blue, 5bit green, 5bit red)
668 tfBGR8ub3, //< 1 x unsigned byte (blue), 1 x unsigned byte (green), 1 x unsigned byte (red)
669 tfBGRX8ui1, //< 1 x unsigned int (8bit blue, 8bit green, 8bit red, 8bit reserved)
670 tfXBGR8ui1, //< 1 x unsigned int (8bit reserved, 8bit blue, 8bit green, 8bit red)
671 tfBGR10X2ui1, //< 1 x unsigned int (10bit blue, 10bit green, 10bit red, 2bit reserved)
672 tfX2BGR10ui1, //< 1 x unsigned int (2bit reserved, 10bit blue, 10bit green, 10bit red)
673 tfBGR16us3, //< 1 x unsigned short (blue), 1 x unsigned short (green), 1 x unsigned short (red)
675 tfBGRA4us1, //< 1 x unsigned short (4bit blue, 4bit green, 4bit red, 4bit alpha)
676 tfABGR4us1, //< 1 x unsigned short (4bit alpha, 4bit blue, 4bit green, 4bit red)
677 tfBGR5A1us1, //< 1 x unsigned short (5bit blue, 5bit green, 5bit red, 1bit alpha)
678 tfA1BGR5us1, //< 1 x unsigned short (1bit alpha, 5bit blue, 5bit green, 5bit red)
679 tfBGRA8ui1, //< 1 x unsigned int (8bit blue, 8bit green, 8bit red, 8bit alpha)
680 tfABGR8ui1, //< 1 x unsigned int (8bit alpha, 8bit blue, 8bit green, 8bit red)
681 tfBGRA8ub4, //< 1 x unsigned byte (blue), 1 x unsigned byte (green), 1 x unsigned byte (red), 1 x unsigned byte (alpha)
682 tfBGR10A2ui1, //< 1 x unsigned int (10bit blue, 10bit green, 10bit red, 2bit alpha)
683 tfA2BGR10ui1, //< 1 x unsigned int (2bit alpha, 10bit blue, 10bit green, 10bit red)
684 tfBGRA16us4, //< 1 x unsigned short (blue), 1 x unsigned short (green), 1 x unsigned short (red), 1 x unsigned short (alpha)
686 tfDepth16us1, //< 1 x unsigned short (depth)
687 tfDepth24ui1, //< 1 x unsigned int (depth)
688 tfDepth32ui1, //< 1 x unsigned int (depth)
695 { type to define suitable file formats }
696 TglBitmapFileType = (
697 {$IFDEF GLB_SUPPORT_PNG_WRITE} ftPNG, {$ENDIF} //< Portable Network Graphic file (PNG)
698 {$IFDEF GLB_SUPPORT_JPEG_WRITE}ftJPEG, {$ENDIF} //< JPEG file
699 ftDDS, //< Direct Draw Surface file (DDS)
700 ftTGA, //< Targa Image File (TGA)
701 ftBMP, //< Windows Bitmap File (BMP)
702 ftRAW); //< glBitmap RAW file format
703 TglBitmapFileTypes = set of TglBitmapFileType;
705 { possible mipmap types }
707 mmNone, //< no mipmaps
708 mmMipmap, //< normal mipmaps
709 mmMipmapGlu); //< mipmaps generated with glu functions
711 { possible normal map functions }
712 TglBitmapNormalMapFunc = (
718 ////////////////////////////////////////////////////////////////////////////////////////////////////
719 EglBitmap = class(Exception); //< glBitmap exception
720 EglBitmapNotSupported = class(Exception); //< exception for not supported functions
721 EglBitmapSizeToLarge = class(EglBitmap); //< exception for to large textures
722 EglBitmapNonPowerOfTwo = class(EglBitmap); //< exception for non power of two textures
723 EglBitmapUnsupportedFormat = class(EglBitmap) //< exception for unsupporetd formats
725 constructor Create(const aFormat: TglBitmapFormat); overload;
726 constructor Create(const aMsg: String; const aFormat: TglBitmapFormat); overload;
729 ////////////////////////////////////////////////////////////////////////////////////////////////////
730 { record that stores 4 unsigned integer values }
731 TglBitmapRec4ui = packed record
733 0: (r, g, b, a: Cardinal);
734 1: (arr: array[0..3] of Cardinal);
737 { record that stores 4 unsigned byte values }
738 TglBitmapRec4ub = packed record
740 0: (r, g, b, a: Byte);
741 1: (arr: array[0..3] of Byte);
744 { record that stores 4 unsigned long integer values }
745 TglBitmapRec4ul = packed record
747 0: (r, g, b, a: QWord);
748 1: (arr: array[0..3] of QWord);
751 { describes the properties of a given texture data format }
752 TglBitmapFormatDescriptor = class(TObject)
755 fBytesPerPixel: Single; //< number of bytes for each pixel
756 fChannelCount: Integer; //< number of color channels
757 fMask: TglBitmapRec4ul; //< bitmask for each color channel
758 fRange: TglBitmapRec4ui; //< maximal value of each color channel
760 { @return @true if the format has a red color channel, @false otherwise }
761 function GetHasRed: Boolean;
763 { @return @true if the format has a green color channel, @false otherwise }
764 function GetHasGreen: Boolean;
766 { @return @true if the format has a blue color channel, @false otherwise }
767 function GetHasBlue: Boolean;
769 { @return @true if the format has a alpha color channel, @false otherwise }
770 function GetHasAlpha: Boolean;
772 { @return @true if the format has any color color channel, @false otherwise }
773 function GetHasColor: Boolean;
775 { @return @true if the format is a grayscale format, @false otherwise }
776 function GetIsGrayscale: Boolean;
778 fFormat: TglBitmapFormat; //< format this descriptor belongs to
779 fWithAlpha: TglBitmapFormat; //< suitable format with alpha channel
780 fWithoutAlpha: TglBitmapFormat; //< suitable format without alpha channel
781 fOpenGLFormat: TglBitmapFormat; //< suitable format that is supported by OpenGL
782 fRGBInverted: TglBitmapFormat; //< suitable format with inverted RGB channels
783 fUncompressed: TglBitmapFormat; //< suitable format with uncompressed data
785 fBitsPerPixel: Integer; //< number of bits per pixel
786 fIsCompressed: Boolean; //< @true if the format is compressed, @false otherwise
788 fPrecision: TglBitmapRec4ub; //< number of bits for each color channel
789 fShift: TglBitmapRec4ub; //< bit offset for each color channel
791 fglFormat: GLenum; //< OpenGL format enum (e.g. GL_RGB)
792 fglInternalFormat: GLenum; //< OpenGL internal format enum (e.g. GL_RGB8)
793 fglDataFormat: GLenum; //< OpenGL data format enum (e.g. GL_UNSIGNED_BYTE)
795 { set values for this format descriptor }
796 procedure SetValues; virtual;
798 { calculate cached values }
799 procedure CalcValues;
801 property Format: TglBitmapFormat read fFormat; //< format this descriptor belongs to
802 property ChannelCount: Integer read fChannelCount; //< number of color channels
803 property IsCompressed: Boolean read fIsCompressed; //< @true if the format is compressed, @false otherwise
804 property BitsPerPixel: Integer read fBitsPerPixel; //< number of bytes per pixel
805 property BytesPerPixel: Single read fBytesPerPixel; //< number of bits per pixel
807 property Precision: TglBitmapRec4ub read fPrecision; //< number of bits for each color channel
808 property Shift: TglBitmapRec4ub read fShift; //< bit offset for each color channel
809 property Range: TglBitmapRec4ui read fRange; //< maximal value of each color channel
810 property Mask: TglBitmapRec4ul read fMask; //< bitmask for each color channel
812 property RGBInverted: TglBitmapFormat read fRGBInverted; //< suitable format with inverted RGB channels
813 property WithAlpha: TglBitmapFormat read fWithAlpha; //< suitable format with alpha channel
814 property WithoutAlpha: TglBitmapFormat read fWithAlpha; //< suitable format without alpha channel
815 property OpenGLFormat: TglBitmapFormat read fOpenGLFormat; //< suitable format that is supported by OpenGL
816 property Uncompressed: TglBitmapFormat read fUncompressed; //< suitable format with uncompressed data
818 property glFormat: GLenum read fglFormat; //< OpenGL format enum (e.g. GL_RGB)
819 property glInternalFormat: GLenum read fglInternalFormat; //< OpenGL internal format enum (e.g. GL_RGB8)
820 property glDataFormat: GLenum read fglDataFormat; //< OpenGL data format enum (e.g. GL_UNSIGNED_BYTE)
822 property HasRed: Boolean read GetHasRed; //< @true if the format has a red color channel, @false otherwise
823 property HasGreen: Boolean read GetHasGreen; //< @true if the format has a green color channel, @false otherwise
824 property HasBlue: Boolean read GetHasBlue; //< @true if the format has a blue color channel, @false otherwise
825 property HasAlpha: Boolean read GetHasAlpha; //< @true if the format has a alpha color channel, @false otherwise
826 property HasColor: Boolean read GetHasColor; //< @true if the format has any color color channel, @false otherwise
827 property IsGrayscale: Boolean read GetIsGrayscale; //< @true if the format is a grayscale format, @false otherwise
832 { get the format descriptor by a given OpenGL internal format
833 @param aInternalFormat OpenGL internal format to get format descriptor for
834 @returns suitable format descriptor or tfEmpty-Descriptor }
835 class function GetByFormat(const aInternalFormat: GLenum): TglBitmapFormatDescriptor;
838 ////////////////////////////////////////////////////////////////////////////////////////////////////
839 { structure to store pixel data in }
840 TglBitmapPixelData = packed record
841 Data: TglBitmapRec4ui; //< color data for each color channel
842 Range: TglBitmapRec4ui; //< maximal color value for each channel
843 Format: TglBitmapFormat; //< format of the pixel
845 PglBitmapPixelData = ^TglBitmapPixelData;
847 TglBitmapSizeFields = set of (ffX, ffY);
848 TglBitmapSize = packed record
849 Fields: TglBitmapSizeFields;
853 TglBitmapPixelPosition = TglBitmapSize;
855 ////////////////////////////////////////////////////////////////////////////////////////////////////
858 { structure to store data for converting in }
859 TglBitmapFunctionRec = record
860 Sender: TglBitmap; //< texture object that stores the data to convert
861 Size: TglBitmapSize; //< size of the texture
862 Position: TglBitmapPixelPosition; //< position of the currently pixel
863 Source: TglBitmapPixelData; //< pixel data of the current pixel
864 Dest: TglBitmapPixelData; //< new data of the pixel (must be filled in)
865 Args: Pointer; //< user defined args that was passed to the convert function
868 { callback to use for converting texture data }
869 TglBitmapFunction = procedure(var FuncRec: TglBitmapFunctionRec);
871 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
872 { base class for all glBitmap classes. used to manage OpenGL texture objects
873 and to load, save and manipulate texture data }
876 { @returns format descriptor that describes the format of the stored data }
877 function GetFormatDesc: TglBitmapFormatDescriptor;
879 fID: GLuint; //< name of the OpenGL texture object
880 fTarget: GLuint; //< texture target (e.g. GL_TEXTURE_2D)
881 fAnisotropic: Integer; //< anisotropic level
882 fDeleteTextureOnFree: Boolean; //< delete OpenGL texture object when this object is destroyed
883 fFreeDataOnDestroy: Boolean; //< free stored data when this object is destroyed
884 fFreeDataAfterGenTexture: Boolean; //< free stored data after data was uploaded to video card
885 fData: PByte; //< data of this texture
887 fIsResident: GLboolean; //< @true if OpenGL texture object has data, @false otherwise
889 fBorderColor: array[0..3] of Single; //< color of the texture border
891 fDimension: TglBitmapSize; //< size of this texture
892 fMipMap: TglBitmapMipMap; //< mipmap type
893 fFormat: TglBitmapFormat; //< format the texture data is stored in
896 fPixelSize: Integer; //< size of one pixel (in byte)
897 fRowSize: Integer; //< size of one pixel row (in byte)
900 fFilterMin: GLenum; //< min filter to apply to the texture
901 fFilterMag: GLenum; //< mag filter to apply to the texture
904 fWrapS: GLenum; //< texture wrapping for x axis
905 fWrapT: GLenum; //< texture wrapping for y axis
906 fWrapR: GLenum; //< texture wrapping for z axis
908 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
910 fSwizzle: array[0..3] of GLenum; //< color channel swizzle
914 fFilename: String; //< filename the texture was load from
915 fCustomName: String; //< user defined name
916 fCustomNameW: WideString; //< user defined name
917 fCustomData: Pointer; //< user defined data
920 { @returns the actual width of the texture }
921 function GetWidth: Integer; virtual;
923 { @returns the actual height of the texture }
924 function GetHeight: Integer; virtual;
926 { @returns the width of the texture or 1 if the width is zero }
927 function GetFileWidth: Integer; virtual;
929 { @returns the height of the texture or 1 if the height is zero }
930 function GetFileHeight: Integer; virtual;
933 { set a new value for fCustomData }
934 procedure SetCustomData(const aValue: Pointer);
936 { set a new value for fCustomName }
937 procedure SetCustomName(const aValue: String);
939 { set a new value for fCustomNameW }
940 procedure SetCustomNameW(const aValue: WideString);
942 { set new value for fFreeDataOnDestroy }
943 procedure SetFreeDataOnDestroy(const aValue: Boolean);
945 { set new value for fDeleteTextureOnFree }
946 procedure SetDeleteTextureOnFree(const aValue: Boolean);
948 { set new value for the data format. only possible if new format has the same pixel size.
949 if you want to convert the texture data, see ConvertTo function }
950 procedure SetFormat(const aValue: TglBitmapFormat);
952 { set new value for fFreeDataAfterGenTexture }
953 procedure SetFreeDataAfterGenTexture(const aValue: Boolean);
955 { set name of OpenGL texture object }
956 procedure SetID(const aValue: Cardinal);
958 { set new value for fMipMap }
959 procedure SetMipMap(const aValue: TglBitmapMipMap);
961 { set new value for target }
962 procedure SetTarget(const aValue: Cardinal);
964 { set new value for fAnisotrophic }
965 procedure SetAnisotropic(const aValue: Integer);
968 { create OpenGL texture object (delete exisiting object if exists) }
971 { setup texture parameters }
972 procedure SetupParameters({$IFNDEF OPENGL_ES}out aBuildWithGlu: Boolean{$ENDIF});
974 { set data pointer of texture data
975 @param aData pointer to new texture data (be carefull, aData could be freed by this function)
976 @param aFormat format of the data stored at aData
977 @param aWidth width of the texture data
978 @param aHeight height of the texture data }
979 procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
980 const aWidth: Integer = -1; const aHeight: Integer = -1); virtual;
982 { generate texture (upload texture data to video card)
983 @param aTestTextureSize test texture size before uploading and raise exception if something is wrong }
984 procedure GenTexture(const aTestTextureSize: Boolean = true); virtual; abstract;
986 { flip texture horizontal
987 @returns @true in success, @false otherwise }
988 function FlipHorz: Boolean; virtual;
990 { flip texture vertical
991 @returns @true in success, @false otherwise }
992 function FlipVert: Boolean; virtual;
995 property Width: Integer read GetWidth; //< the actual width of the texture
996 property Height: Integer read GetHeight; //< the actual height of the texture
998 property FileWidth: Integer read GetFileWidth; //< the width of the texture or 1 if the width is zero
999 property FileHeight: Integer read GetFileHeight; //< the height of the texture or 1 if the height is zero
1001 property ID: Cardinal read fID write SetID; //< name of the OpenGL texture object
1002 property Target: Cardinal read fTarget write SetTarget; //< texture target (e.g. GL_TEXTURE_2D)
1003 property Format: TglBitmapFormat read fFormat write SetFormat; //< format the texture data is stored in
1004 property MipMap: TglBitmapMipMap read fMipMap write SetMipMap; //< mipmap type
1005 property Anisotropic: Integer read fAnisotropic write SetAnisotropic; //< anisotropic level
1007 property FormatDesc: TglBitmapFormatDescriptor read GetFormatDesc; //< format descriptor that describes the format of the stored data
1009 property Filename: String read fFilename; //< filename the texture was load from
1010 property CustomName: String read fCustomName write SetCustomName; //< user defined name (use at will)
1011 property CustomNameW: WideString read fCustomNameW write SetCustomNameW; //< user defined name (as WideString; use at will)
1012 property CustomData: Pointer read fCustomData write SetCustomData; //< user defined data (use at will)
1014 property DeleteTextureOnFree: Boolean read fDeleteTextureOnFree write SetDeleteTextureOnFree; //< delete texture object when this object is destroyed
1015 property FreeDataOnDestroy: Boolean read fFreeDataOnDestroy write SetFreeDataOnDestroy; //< free stored data when this object is destroyed
1016 property FreeDataAfterGenTexture: Boolean read fFreeDataAfterGenTexture write SetFreeDataAfterGenTexture; //< free stored data after it is uplaoded to video card
1018 property Dimension: TglBitmapSize read fDimension; //< size of the texture
1019 property Data: PByte read fData; //< texture data (or @nil if unset)
1021 property IsResident: GLboolean read fIsResident; //< @true if OpenGL texture object has data, @false otherwise
1024 { this method is called after the constructor and sets the default values of this object }
1025 procedure AfterConstruction; override;
1027 { this method is called before the destructor and does some cleanup }
1028 procedure BeforeDestruction; override;
1030 { splits a resource identifier into the resource and it's type
1031 @param aResource resource identifier to split and store name in
1032 @param aResType type of the resource }
1033 procedure PrepareResType(var aResource: String; var aResType: PChar);
1036 { load a texture from a file
1037 @param aFilename file to load texuture from }
1038 procedure LoadFromFile(const aFilename: String);
1040 { load a texture from a stream
1041 @param aStream stream to load texture from }
1042 procedure LoadFromStream(const aStream: TStream); virtual;
1044 { use a function to generate texture data
1045 @param aSize size of the texture
1046 @param aFunc callback to use for generation
1047 @param aFormat format of the texture data
1048 @param aArgs user defined paramaters (use at will) }
1049 procedure LoadFromFunc(const aSize: TglBitmapSize; const aFunc: TglBitmapFunction;
1050 const aFormat: TglBitmapFormat; const aArgs: Pointer = nil);
1052 { load a texture from a resource
1053 @param aInstance resource handle
1054 @param aResource resource indentifier
1055 @param aResType resource type (if known) }
1056 procedure LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil);
1058 { load a texture from a resource id
1059 @param aInstance resource handle
1060 @param aResource resource ID
1061 @param aResType resource type }
1062 procedure LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
1065 { save texture data to a file
1066 @param aFilename filename to store texture in
1067 @param aFileType file type to store data into }
1068 procedure SaveToFile(const aFilename: String; const aFileType: TglBitmapFileType);
1070 { save texture data to a stream
1071 @param aFilename filename to store texture in
1072 @param aFileType file type to store data into }
1073 procedure SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType); virtual;
1076 { convert texture data using a user defined callback
1077 @param aFunc callback to use for converting
1078 @param aCreateTemp create a temporary buffer to use for converting
1079 @param aArgs user defined paramters (use at will)
1080 @returns @true if converting was successful, @false otherwise }
1081 function Convert(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer = nil): Boolean; overload;
1083 { convert texture data using a user defined callback
1084 @param aSource glBitmap to read data from
1085 @param aFunc callback to use for converting
1086 @param aCreateTemp create a temporary buffer to use for converting
1087 @param aFormat format of the new data
1088 @param aArgs user defined paramters (use at will)
1089 @returns @true if converting was successful, @false otherwise }
1090 function Convert(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
1091 const aFormat: TglBitmapFormat; const aArgs: Pointer = nil): Boolean; overload;
1093 { convert texture data using a specific format
1094 @param aFormat new format of texture data
1095 @returns @true if converting was successful, @false otherwise }
1096 function ConvertTo(const aFormat: TglBitmapFormat): Boolean; virtual;
1100 { assign texture data to SDL surface
1101 @param aSurface SDL surface to write data to
1102 @returns @true on success, @false otherwise }
1103 function AssignToSurface(out aSurface: PSDL_Surface): Boolean;
1105 { assign texture data from SDL surface
1106 @param aSurface SDL surface to read data from
1107 @returns @true on success, @false otherwise }
1108 function AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
1110 { assign alpha channel data to SDL surface
1111 @param aSurface SDL surface to write alpha channel data to
1112 @returns @true on success, @false otherwise }
1113 function AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
1115 { assign alpha channel data from SDL surface
1116 @param aSurface SDL surface to read data from
1117 @param aFunc callback to use for converting
1118 @param aArgs user defined parameters (use at will)
1119 @returns @true on success, @false otherwise }
1120 function AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1125 { assign texture data to TBitmap object
1126 @param aBitmap TBitmap to write data to
1127 @returns @true on success, @false otherwise }
1128 function AssignToBitmap(const aBitmap: TBitmap): Boolean;
1130 { assign texture data from TBitmap object
1131 @param aBitmap TBitmap to read data from
1132 @returns @true on success, @false otherwise }
1133 function AssignFromBitmap(const aBitmap: TBitmap): Boolean;
1135 { assign alpha channel data to TBitmap object
1136 @param aBitmap TBitmap to write data to
1137 @returns @true on success, @false otherwise }
1138 function AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
1140 { assign alpha channel data from TBitmap object
1141 @param aBitmap TBitmap to read data from
1142 @param aFunc callback to use for converting
1143 @param aArgs user defined parameters (use at will)
1144 @returns @true on success, @false otherwise }
1145 function AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1148 {$IFDEF GLB_LAZARUS}
1150 { assign texture data to TLazIntfImage object
1151 @param aImage TLazIntfImage to write data to
1152 @returns @true on success, @false otherwise }
1153 function AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
1155 { assign texture data from TLazIntfImage object
1156 @param aImage TLazIntfImage to read data from
1157 @returns @true on success, @false otherwise }
1158 function AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
1160 { assign alpha channel data to TLazIntfImage object
1161 @param aImage TLazIntfImage to write data to
1162 @returns @true on success, @false otherwise }
1163 function AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
1165 { assign alpha channel data from TLazIntfImage object
1166 @param aImage TLazIntfImage to read data from
1167 @param aFunc callback to use for converting
1168 @param aArgs user defined parameters (use at will)
1169 @returns @true on success, @false otherwise }
1170 function AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1174 { load alpha channel data from resource
1175 @param aInstance resource handle
1176 @param aResource resource ID
1177 @param aResType resource type
1178 @param aFunc callback to use for converting
1179 @param aArgs user defined parameters (use at will)
1180 @returns @true on success, @false otherwise }
1181 function AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1183 { load alpha channel data from resource ID
1184 @param aInstance resource handle
1185 @param aResourceID resource ID
1186 @param aResType resource type
1187 @param aFunc callback to use for converting
1188 @param aArgs user defined parameters (use at will)
1189 @returns @true on success, @false otherwise }
1190 function AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1192 { add alpha channel data from function
1193 @param aFunc callback to get data from
1194 @param aArgs user defined parameters (use at will)
1195 @returns @true on success, @false otherwise }
1196 function AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer = nil): Boolean; virtual;
1198 { add alpha channel data from file (macro for: new glBitmap, LoadFromFile, AddAlphaFromGlBitmap)
1199 @param aFilename file to load alpha channel data from
1200 @param aFunc callback to use for converting
1201 @param aArgs user defined parameters (use at will)
1202 @returns @true on success, @false otherwise }
1203 function AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1205 { add alpha channel data from stream (macro for: new glBitmap, LoadFromStream, AddAlphaFromGlBitmap)
1206 @param aStream stream to load alpha channel data from
1207 @param aFunc callback to use for converting
1208 @param aArgs user defined parameters (use at will)
1209 @returns @true on success, @false otherwise }
1210 function AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1212 { add alpha channel data from existing glBitmap object
1213 @param aBitmap TglBitmap to copy alpha channel data from
1214 @param aFunc callback to use for converting
1215 @param aArgs user defined parameters (use at will)
1216 @returns @true on success, @false otherwise }
1217 function AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1219 { add alpha to pixel if the pixels color is greter than the given color value
1220 @param aRed red threshold (0-255)
1221 @param aGreen green threshold (0-255)
1222 @param aBlue blue threshold (0-255)
1223 @param aDeviatation accepted deviatation (0-255)
1224 @returns @true on success, @false otherwise }
1225 function AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte = 0): Boolean;
1227 { add alpha to pixel if the pixels color is greter than the given color value
1228 @param aRed red threshold (0-Range.r)
1229 @param aGreen green threshold (0-Range.g)
1230 @param aBlue blue threshold (0-Range.b)
1231 @param aDeviatation accepted deviatation (0-max(Range.rgb))
1232 @returns @true on success, @false otherwise }
1233 function AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal = 0): Boolean;
1235 { add alpha to pixel if the pixels color is greter than the given color value
1236 @param aRed red threshold (0.0-1.0)
1237 @param aGreen green threshold (0.0-1.0)
1238 @param aBlue blue threshold (0.0-1.0)
1239 @param aDeviatation accepted deviatation (0.0-1.0)
1240 @returns @true on success, @false otherwise }
1241 function AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single = 0): Boolean;
1243 { add a constand alpha value to all pixels
1244 @param aAlpha alpha value to add (0-255)
1245 @returns @true on success, @false otherwise }
1246 function AddAlphaFromValue(const aAlpha: Byte): Boolean;
1248 { add a constand alpha value to all pixels
1249 @param aAlpha alpha value to add (0-max(Range.rgb))
1250 @returns @true on success, @false otherwise }
1251 function AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
1253 { add a constand alpha value to all pixels
1254 @param aAlpha alpha value to add (0.0-1.0)
1255 @returns @true on success, @false otherwise }
1256 function AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
1258 { remove alpha channel
1259 @returns @true on success, @false otherwise }
1260 function RemoveAlpha: Boolean; virtual;
1263 { create a clone of the current object
1264 @returns clone of this object}
1265 function Clone: TglBitmap;
1267 { invert color data (xor)
1268 @param aUseRGB xor each color channel
1269 @param aUseAlpha xor alpha channel }
1270 procedure Invert(const aUseRGB: Boolean = true; const aUseAlpha: Boolean = false);
1272 { free texture stored data }
1276 { set the new value for texture border color
1277 @param aRed red color for border (0.0-1.0)
1278 @param aGreen green color for border (0.0-1.0)
1279 @param aBlue blue color for border (0.0-1.0)
1280 @param aAlpha alpha color for border (0.0-1.0) }
1281 procedure SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
1285 { fill complete texture with one color
1286 @param aRed red color for border (0-255)
1287 @param aGreen green color for border (0-255)
1288 @param aBlue blue color for border (0-255)
1289 @param aAlpha alpha color for border (0-255) }
1290 procedure FillWithColor(const aRed, aGreen, aBlue: Byte; const aAlpha: Byte = 255);
1292 { fill complete texture with one color
1293 @param aRed red color for border (0-Range.r)
1294 @param aGreen green color for border (0-Range.g)
1295 @param aBlue blue color for border (0-Range.b)
1296 @param aAlpha alpha color for border (0-Range.a) }
1297 procedure FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal = $FFFFFFFF);
1299 { fill complete texture with one color
1300 @param aRed red color for border (0.0-1.0)
1301 @param aGreen green color for border (0.0-1.0)
1302 @param aBlue blue color for border (0.0-1.0)
1303 @param aAlpha alpha color for border (0.0-1.0) }
1304 procedure FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single = 1.0);
1307 { set new texture filer
1308 @param aMin min filter
1309 @param aMag mag filter }
1310 procedure SetFilter(const aMin, aMag: GLenum);
1312 { set new texture wrapping
1313 @param S texture wrapping for x axis
1314 @param T texture wrapping for y axis
1315 @param R texture wrapping for z axis }
1317 const S: GLenum = GL_CLAMP_TO_EDGE;
1318 const T: GLenum = GL_CLAMP_TO_EDGE;
1319 const R: GLenum = GL_CLAMP_TO_EDGE);
1321 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
1323 @param r swizzle for red channel
1324 @param g swizzle for green channel
1325 @param b swizzle for blue channel
1326 @param a swizzle for alpha channel }
1327 procedure SetSwizzle(const r, g, b, a: GLenum);
1332 @param aEnableTextureUnit enable texture unit for this texture (e.g. glEnable(GL_TEXTURE_2D)) }
1333 procedure Bind(const aEnableTextureUnit: Boolean = true); virtual;
1336 @param aDisableTextureUnit disable texture unit for this texture (e.g. glEnable(GL_TEXTURE_2D)) }
1337 procedure Unbind(const aDisableTextureUnit: Boolean = true); virtual;
1340 { constructor - created an empty texture }
1341 constructor Create; overload;
1343 { constructor - creates a texture and load it from a file
1344 @param aFilename file to load texture from }
1345 constructor Create(const aFileName: String); overload;
1347 { constructor - creates a texture and load it from a stream
1348 @param aStream stream to load texture from }
1349 constructor Create(const aStream: TStream); overload;
1351 { constructor - creates a texture with the given size, format and data
1352 @param aSize size of the texture
1353 @param aFormat format of the given data
1354 @param aData texture data - be carefull: the data will now be managed by the glBitmap object,
1355 you can control this by setting DeleteTextureOnFree, FreeDataOnDestroy and FreeDataAfterGenTexture }
1356 constructor Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; aData: PByte = nil); overload;
1358 { constructor - creates a texture with the given size and format and uses the given callback to create the data
1359 @param aSize size of the texture
1360 @param aFormat format of the given data
1361 @param aFunc callback to use for generating the data
1362 @param aArgs user defined parameters (use at will) }
1363 constructor Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer = nil); overload;
1365 { constructor - creates a texture and loads it from a resource
1366 @param aInstance resource handle
1367 @param aResource resource indentifier
1368 @param aResType resource type (if known) }
1369 constructor Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil); overload;
1371 { constructor - creates a texture and loads it from a resource
1372 @param aInstance resource handle
1373 @param aResourceID resource ID
1374 @param aResType resource type (if known) }
1375 constructor Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar); overload;
1378 {$IFDEF GLB_SUPPORT_PNG_READ}
1379 { try to load a PNG from a stream
1380 @param aStream stream to load PNG from
1381 @returns @true on success, @false otherwise }
1382 function LoadPNG(const aStream: TStream): Boolean; virtual;
1385 {$ifdef GLB_SUPPORT_PNG_WRITE}
1386 { save texture data as PNG to stream
1387 @param aStream stream to save data to}
1388 procedure SavePNG(const aStream: TStream); virtual;
1391 {$IFDEF GLB_SUPPORT_JPEG_READ}
1392 { try to load a JPEG from a stream
1393 @param aStream stream to load JPEG from
1394 @returns @true on success, @false otherwise }
1395 function LoadJPEG(const aStream: TStream): Boolean; virtual;
1398 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
1399 { save texture data as JPEG to stream
1400 @param aStream stream to save data to}
1401 procedure SaveJPEG(const aStream: TStream); virtual;
1404 { try to load a RAW image from a stream
1405 @param aStream stream to load RAW image from
1406 @returns @true on success, @false otherwise }
1407 function LoadRAW(const aStream: TStream): Boolean;
1409 { save texture data as RAW image to stream
1410 @param aStream stream to save data to}
1411 procedure SaveRAW(const aStream: TStream);
1413 { try to load a BMP from a stream
1414 @param aStream stream to load BMP from
1415 @returns @true on success, @false otherwise }
1416 function LoadBMP(const aStream: TStream): Boolean;
1418 { save texture data as BMP to stream
1419 @param aStream stream to save data to}
1420 procedure SaveBMP(const aStream: TStream);
1422 { try to load a TGA from a stream
1423 @param aStream stream to load TGA from
1424 @returns @true on success, @false otherwise }
1425 function LoadTGA(const aStream: TStream): Boolean;
1427 { save texture data as TGA to stream
1428 @param aStream stream to save data to}
1429 procedure SaveTGA(const aStream: TStream);
1431 { try to load a DDS from a stream
1432 @param aStream stream to load DDS from
1433 @returns @true on success, @false otherwise }
1434 function LoadDDS(const aStream: TStream): Boolean;
1436 { save texture data as DDS to stream
1437 @param aStream stream to save data to}
1438 procedure SaveDDS(const aStream: TStream);
1441 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1442 {$IF NOT DEFINED(OPENGL_ES)}
1443 { wrapper class for 1-dimensional textures (OpenGL target = GL_TEXTURE_1D }
1444 TglBitmap1D = class(TglBitmap)
1446 { set data pointer of texture data
1447 @param aData pointer to new texture data (be carefull, aData could be freed by this function)
1448 @param aFormat format of the data stored at aData
1449 @param aWidth width of the texture data
1450 @param aHeight height of the texture data }
1451 procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat; const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
1453 { upload the texture data to video card
1454 @param aBuildWithGlu use glu functions to build mipmaps }
1455 procedure UploadData(const aBuildWithGlu: Boolean);
1457 property Width; //< actual with of the texture
1459 { this method is called after constructor and initializes the object }
1460 procedure AfterConstruction; override;
1462 { flip texture horizontally
1463 @returns @true on success, @fals otherwise }
1464 function FlipHorz: Boolean; override;
1466 { generate texture (create texture object if not exist, set texture parameters and upload data
1467 @param aTestTextureSize check the size of the texture and throw exception if something is wrong }
1468 procedure GenTexture(const aTestTextureSize: Boolean = true); override;
1472 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1473 { wrapper class for 2-dimensional textures (OpenGL target = GL_TEXTURE_2D) }
1474 TglBitmap2D = class(TglBitmap)
1476 fLines: array of PByte; //< array to store scanline entry points in
1478 { get a specific scanline
1479 @param aIndex index of the scanline to return
1480 @returns scanline at position aIndex or @nil }
1481 function GetScanline(const aIndex: Integer): Pointer;
1483 { set data pointer of texture data
1484 @param aData pointer to new texture data (be carefull, aData could be freed by this function)
1485 @param aFormat format of the data stored at aData
1486 @param aWidth width of the texture data
1487 @param aHeight height of the texture data }
1488 procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
1489 const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
1491 { upload the texture data to video card
1492 @param aTarget target o upload data to (e.g. GL_TEXTURE_2D)
1493 @param aBuildWithGlu use glu functions to build mipmaps }
1494 procedure UploadData(const aTarget: GLenum{$IFNDEF OPENGL_ES}; const aBuildWithGlu: Boolean{$ENDIF});
1496 property Width; //< actual width of the texture
1497 property Height; //< actual height of the texture
1498 property Scanline[const aIndex: Integer]: Pointer read GetScanline; //< scanline to access texture data directly
1500 { this method is called after constructor and initializes the object }
1501 procedure AfterConstruction; override;
1503 { copy a part of the frame buffer top the texture
1504 @param aTop topmost pixel to copy
1505 @param aLeft leftmost pixel to copy
1506 @param aRight rightmost pixel to copy
1507 @param aBottom bottommost pixel to copy
1508 @param aFormat format to store data in }
1509 procedure GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
1512 { downlaod texture data from OpenGL texture object }
1513 procedure GetDataFromTexture;
1516 { generate texture (create texture object if not exist, set texture parameters and upload data)
1517 @param aTestTextureSize check the size of the texture and throw exception if something is wrong }
1518 procedure GenTexture(const aTestTextureSize: Boolean = true); override;
1520 { flip texture horizontally
1521 @returns @true on success, @false otherwise }
1522 function FlipHorz: Boolean; override;
1524 { flip texture vertically
1525 @returns @true on success, @false otherwise }
1526 function FlipVert: Boolean; override;
1528 { create normal map from texture data
1529 @param aFunc normal map function to generate normalmap with
1530 @param aScale scale of the normale stored in the normal map
1531 @param aUseAlpha generate normalmap from alpha channel data (if present) }
1532 procedure GenerateNormalMap(const aFunc: TglBitmapNormalMapFunc = nm3x3;
1533 const aScale: Single = 2; const aUseAlpha: Boolean = false);
1536 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1537 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
1538 { wrapper class for cube maps (OpenGL target = GL_TEXTURE_CUBE_MAP) }
1539 TglBitmapCubeMap = class(TglBitmap2D)
1542 fGenMode: Integer; //< generation mode for the cube map (e.g. GL_REFLECTION_MAP)
1545 { generate texture (create texture object if not exist, set texture parameters and upload data
1546 do not call directly for cubemaps, use GenerateCubeMap instead
1547 @param aTestTextureSize check the size of the texture and throw exception if something is wrong }
1548 procedure GenTexture(const aTestTextureSize: Boolean = true); reintroduce;
1550 { this method is called after constructor and initializes the object }
1551 procedure AfterConstruction; override;
1553 { generate texture (create texture object if not exist, set texture parameters and upload data
1554 @param aCubeTarget cube map target to upload data to (e.g. GL_TEXTURE_CUBE_MAP_POSITIVE_X)
1555 @param aTestTextureSize check the size of the texture and throw exception if something is wrong }
1556 procedure GenerateCubeMap(const aCubeTarget: Cardinal; const aTestTextureSize: Boolean = true);
1559 @param aEnableTexCoordsGen enable cube map generator
1560 @param aEnableTextureUnit enable texture unit }
1561 procedure Bind({$IFNDEF OPENGL_ES}const aEnableTexCoordsGen: Boolean = true;{$ENDIF} const aEnableTextureUnit: Boolean = true); reintroduce; virtual;
1564 @param aDisableTexCoordsGen disable cube map generator
1565 @param aDisableTextureUnit disable texture unit }
1566 procedure Unbind({$IFNDEF OPENGL_ES}const aDisableTexCoordsGen: Boolean = true;{$ENDIF} const aDisableTextureUnit: Boolean = true); reintroduce; virtual;
1570 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
1571 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1572 { wrapper class for cube normal maps }
1573 TglBitmapNormalMap = class(TglBitmapCubeMap)
1575 { this method is called after constructor and initializes the object }
1576 procedure AfterConstruction; override;
1578 { create cube normal map from texture data and upload it to video card
1579 @param aSize size of each cube map texture
1580 @param aTestTextureSize check texture size when uploading and throw exception if something is wrong }
1581 procedure GenerateNormalMap(const aSize: Integer = 32; const aTestTextureSize: Boolean = true);
1586 NULL_SIZE: TglBitmapSize = (Fields: []; X: 0; Y: 0);
1588 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
1589 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
1590 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
1591 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
1592 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
1593 procedure glBitmapSetDefaultWrap(
1594 const S: Cardinal = GL_CLAMP_TO_EDGE;
1595 const T: Cardinal = GL_CLAMP_TO_EDGE;
1596 const R: Cardinal = GL_CLAMP_TO_EDGE);
1598 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
1599 procedure glBitmapSetDefaultSwizzle(const r: GLenum = GL_RED; g: GLenum = GL_GREEN; b: GLenum = GL_BLUE; a: GLenum = GL_ALPHA);
1602 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
1603 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
1604 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
1605 function glBitmapGetDefaultFormat: TglBitmapFormat;
1606 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
1607 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
1608 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
1609 procedure glBitmapGetDefaultSwizzle(var r, g, b, a: GLenum);
1612 function glBitmapSize(X: Integer = -1; Y: Integer = -1): TglBitmapSize;
1613 function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
1614 function glBitmapRec4ub(const r, g, b, a: Byte): TglBitmapRec4ub;
1615 function glBitmapRec4ui(const r, g, b, a: Cardinal): TglBitmapRec4ui;
1616 function glBitmapRec4ul(const r, g, b, a: QWord): TglBitmapRec4ul;
1617 function glBitmapRec4ubCompare(const r1, r2: TglBitmapRec4ub): Boolean;
1618 function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean;
1620 function glBitmapCreateTestTexture(const aFormat: TglBitmapFormat): TglBitmap2D;
1623 function CreateGrayPalette: HPALETTE;
1629 Math, syncobjs, typinfo
1630 {$IF DEFINED(GLB_SUPPORT_JPEG_READ) AND DEFINED(GLB_LAZ_JPEG)}, FPReadJPEG{$IFEND};
1634 glBitmapDefaultDeleteTextureOnFree: Boolean;
1635 glBitmapDefaultFreeDataAfterGenTextures: Boolean;
1636 glBitmapDefaultFormat: TglBitmapFormat;
1637 glBitmapDefaultMipmap: TglBitmapMipMap;
1638 glBitmapDefaultFilterMin: Cardinal;
1639 glBitmapDefaultFilterMag: Cardinal;
1640 glBitmapDefaultWrapS: Cardinal;
1641 glBitmapDefaultWrapT: Cardinal;
1642 glBitmapDefaultWrapR: Cardinal;
1643 glDefaultSwizzle: array[0..3] of GLenum;
1645 ////////////////////////////////////////////////////////////////////////////////////////////////////
1647 TFormatDescriptor = class(TglBitmapFormatDescriptor)
1649 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); virtual; abstract;
1650 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract;
1652 function GetSize(const aSize: TglBitmapSize): Integer; overload; virtual;
1653 function GetSize(const aWidth, aHeight: Integer): Integer; overload; virtual;
1655 function CreateMappingData: Pointer; virtual;
1656 procedure FreeMappingData(var aMappingData: Pointer); virtual;
1658 function IsEmpty: Boolean; virtual;
1659 function MaskMatch(const aMask: TglBitmapRec4ul): Boolean; virtual;
1661 procedure PreparePixel(out aPixel: TglBitmapPixelData); virtual;
1663 constructor Create; virtual;
1665 class procedure Init;
1666 class function Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
1667 class function GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
1668 class function GetFromMask(const aMask: TglBitmapRec4ul; const aBitCount: Integer = 0): TFormatDescriptor;
1669 class function GetFromPrecShift(const aPrec, aShift: TglBitmapRec4ub; const aBitCount: Integer): TFormatDescriptor;
1670 class procedure Clear;
1671 class procedure Finalize;
1673 TFormatDescriptorClass = class of TFormatDescriptor;
1675 TfdEmpty = class(TFormatDescriptor);
1677 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1678 TfdAlphaUB1 = class(TFormatDescriptor) //1* unsigned byte
1679 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1680 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1683 TfdLuminanceUB1 = class(TFormatDescriptor) //1* unsigned byte
1684 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1685 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1688 TfdUniversalUB1 = class(TFormatDescriptor) //1* unsigned byte
1689 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1690 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1693 TfdLuminanceAlphaUB2 = class(TfdLuminanceUB1) //2* unsigned byte
1694 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1695 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1698 TfdRGBub3 = class(TFormatDescriptor) //3* unsigned byte
1699 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1700 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1703 TfdBGRub3 = class(TFormatDescriptor) //3* unsigned byte (inverse)
1704 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1705 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1708 TfdRGBAub4 = class(TfdRGBub3) //3* unsigned byte
1709 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1710 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1713 TfdBGRAub4 = class(TfdBGRub3) //3* unsigned byte (inverse)
1714 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1715 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1718 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1719 TfdAlphaUS1 = class(TFormatDescriptor) //1* unsigned short
1720 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1721 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1724 TfdLuminanceUS1 = class(TFormatDescriptor) //1* unsigned short
1725 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1726 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1729 TfdUniversalUS1 = class(TFormatDescriptor) //1* unsigned short
1730 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1731 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1734 TfdDepthUS1 = class(TFormatDescriptor) //1* unsigned short
1735 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1736 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1739 TfdLuminanceAlphaUS2 = class(TfdLuminanceUS1) //2* unsigned short
1740 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1741 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1744 TfdRGBus3 = class(TFormatDescriptor) //3* unsigned short
1745 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1746 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1749 TfdBGRus3 = class(TFormatDescriptor) //3* unsigned short (inverse)
1750 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1751 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1754 TfdRGBAus4 = class(TfdRGBus3) //4* unsigned short
1755 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1756 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1759 TfdARGBus4 = class(TfdRGBus3) //4* unsigned short
1760 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1761 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1764 TfdBGRAus4 = class(TfdBGRus3) //4* unsigned short (inverse)
1765 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1766 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1769 TfdABGRus4 = class(TfdBGRus3) //4* unsigned short (inverse)
1770 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1771 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1774 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1775 TfdUniversalUI1 = class(TFormatDescriptor) //1* unsigned int
1776 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1777 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1780 TfdDepthUI1 = class(TFormatDescriptor) //1* unsigned int
1781 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1782 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1785 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1786 TfdAlpha4ub1 = class(TfdAlphaUB1)
1787 procedure SetValues; override;
1790 TfdAlpha8ub1 = class(TfdAlphaUB1)
1791 procedure SetValues; override;
1794 TfdAlpha16us1 = class(TfdAlphaUS1)
1795 procedure SetValues; override;
1798 TfdLuminance4ub1 = class(TfdLuminanceUB1)
1799 procedure SetValues; override;
1802 TfdLuminance8ub1 = class(TfdLuminanceUB1)
1803 procedure SetValues; override;
1806 TfdLuminance16us1 = class(TfdLuminanceUS1)
1807 procedure SetValues; override;
1810 TfdLuminance4Alpha4ub2 = class(TfdLuminanceAlphaUB2)
1811 procedure SetValues; override;
1814 TfdLuminance6Alpha2ub2 = class(TfdLuminanceAlphaUB2)
1815 procedure SetValues; override;
1818 TfdLuminance8Alpha8ub2 = class(TfdLuminanceAlphaUB2)
1819 procedure SetValues; override;
1822 TfdLuminance12Alpha4us2 = class(TfdLuminanceAlphaUS2)
1823 procedure SetValues; override;
1826 TfdLuminance16Alpha16us2 = class(TfdLuminanceAlphaUS2)
1827 procedure SetValues; override;
1830 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1831 TfdR3G3B2ub1 = class(TfdUniversalUB1)
1832 procedure SetValues; override;
1835 TfdRGBX4us1 = class(TfdUniversalUS1)
1836 procedure SetValues; override;
1839 TfdXRGB4us1 = class(TfdUniversalUS1)
1840 procedure SetValues; override;
1843 TfdR5G6B5us1 = class(TfdUniversalUS1)
1844 procedure SetValues; override;
1847 TfdRGB5X1us1 = class(TfdUniversalUS1)
1848 procedure SetValues; override;
1851 TfdX1RGB5us1 = class(TfdUniversalUS1)
1852 procedure SetValues; override;
1855 TfdRGB8ub3 = class(TfdRGBub3)
1856 procedure SetValues; override;
1859 TfdRGBX8ui1 = class(TfdUniversalUI1)
1860 procedure SetValues; override;
1863 TfdXRGB8ui1 = class(TfdUniversalUI1)
1864 procedure SetValues; override;
1867 TfdRGB10X2ui1 = class(TfdUniversalUI1)
1868 procedure SetValues; override;
1871 TfdX2RGB10ui1 = class(TfdUniversalUI1)
1872 procedure SetValues; override;
1875 TfdRGB16us3 = class(TfdRGBus3)
1876 procedure SetValues; override;
1879 TfdRGBA4us1 = class(TfdUniversalUS1)
1880 procedure SetValues; override;
1883 TfdARGB4us1 = class(TfdUniversalUS1)
1884 procedure SetValues; override;
1887 TfdRGB5A1us1 = class(TfdUniversalUS1)
1888 procedure SetValues; override;
1891 TfdA1RGB5us1 = class(TfdUniversalUS1)
1892 procedure SetValues; override;
1895 TfdRGBA8ui1 = class(TfdUniversalUI1)
1896 procedure SetValues; override;
1899 TfdARGB8ui1 = class(TfdUniversalUI1)
1900 procedure SetValues; override;
1903 TfdRGBA8ub4 = class(TfdRGBAub4)
1904 procedure SetValues; override;
1907 TfdRGB10A2ui1 = class(TfdUniversalUI1)
1908 procedure SetValues; override;
1911 TfdA2RGB10ui1 = class(TfdUniversalUI1)
1912 procedure SetValues; override;
1915 TfdRGBA16us4 = class(TfdRGBAus4)
1916 procedure SetValues; override;
1919 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1920 TfdBGRX4us1 = class(TfdUniversalUS1)
1921 procedure SetValues; override;
1924 TfdXBGR4us1 = class(TfdUniversalUS1)
1925 procedure SetValues; override;
1928 TfdB5G6R5us1 = class(TfdUniversalUS1)
1929 procedure SetValues; override;
1932 TfdBGR5X1us1 = class(TfdUniversalUS1)
1933 procedure SetValues; override;
1936 TfdX1BGR5us1 = class(TfdUniversalUS1)
1937 procedure SetValues; override;
1940 TfdBGR8ub3 = class(TfdBGRub3)
1941 procedure SetValues; override;
1944 TfdBGRX8ui1 = class(TfdUniversalUI1)
1945 procedure SetValues; override;
1948 TfdXBGR8ui1 = class(TfdUniversalUI1)
1949 procedure SetValues; override;
1952 TfdBGR10X2ui1 = class(TfdUniversalUI1)
1953 procedure SetValues; override;
1956 TfdX2BGR10ui1 = class(TfdUniversalUI1)
1957 procedure SetValues; override;
1960 TfdBGR16us3 = class(TfdBGRus3)
1961 procedure SetValues; override;
1964 TfdBGRA4us1 = class(TfdUniversalUS1)
1965 procedure SetValues; override;
1968 TfdABGR4us1 = class(TfdUniversalUS1)
1969 procedure SetValues; override;
1972 TfdBGR5A1us1 = class(TfdUniversalUS1)
1973 procedure SetValues; override;
1976 TfdA1BGR5us1 = class(TfdUniversalUS1)
1977 procedure SetValues; override;
1980 TfdBGRA8ui1 = class(TfdUniversalUI1)
1981 procedure SetValues; override;
1984 TfdABGR8ui1 = class(TfdUniversalUI1)
1985 procedure SetValues; override;
1988 TfdBGRA8ub4 = class(TfdBGRAub4)
1989 procedure SetValues; override;
1992 TfdBGR10A2ui1 = class(TfdUniversalUI1)
1993 procedure SetValues; override;
1996 TfdA2BGR10ui1 = class(TfdUniversalUI1)
1997 procedure SetValues; override;
2000 TfdBGRA16us4 = class(TfdBGRAus4)
2001 procedure SetValues; override;
2004 TfdDepth16us1 = class(TfdDepthUS1)
2005 procedure SetValues; override;
2008 TfdDepth24ui1 = class(TfdDepthUI1)
2009 procedure SetValues; override;
2012 TfdDepth32ui1 = class(TfdDepthUI1)
2013 procedure SetValues; override;
2016 TfdS3tcDtx1RGBA = class(TFormatDescriptor)
2017 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
2018 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
2019 procedure SetValues; override;
2022 TfdS3tcDtx3RGBA = class(TFormatDescriptor)
2023 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
2024 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
2025 procedure SetValues; override;
2028 TfdS3tcDtx5RGBA = class(TFormatDescriptor)
2029 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
2030 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
2031 procedure SetValues; override;
2034 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2035 TbmpBitfieldFormat = class(TFormatDescriptor)
2037 procedure SetCustomValues(const aBPP: Integer; aMask: TglBitmapRec4ul); overload;
2038 procedure SetCustomValues(const aBBP: Integer; const aPrec, aShift: TglBitmapRec4ub); overload;
2039 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
2040 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
2043 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2044 TbmpColorTableEnty = packed record
2047 TbmpColorTable = array of TbmpColorTableEnty;
2048 TbmpColorTableFormat = class(TFormatDescriptor)
2050 fBitsPerPixel: Integer;
2051 fColorTable: TbmpColorTable;
2053 procedure SetValues; override;
2055 property ColorTable: TbmpColorTable read fColorTable write fColorTable;
2056 property BitsPerPixel: Integer read fBitsPerPixel write fBitsPerPixel;
2058 procedure SetCustomValues(const aFormat: TglBitmapFormat; const aBPP: Integer; const aPrec, aShift: TglBitmapRec4ub); overload;
2059 procedure CalcValues;
2060 procedure CreateColorTable;
2062 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
2063 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
2064 destructor Destroy; override;
2068 LUMINANCE_WEIGHT_R = 0.30;
2069 LUMINANCE_WEIGHT_G = 0.59;
2070 LUMINANCE_WEIGHT_B = 0.11;
2072 ALPHA_WEIGHT_R = 0.30;
2073 ALPHA_WEIGHT_G = 0.59;
2074 ALPHA_WEIGHT_B = 0.11;
2076 DEPTH_WEIGHT_R = 0.333333333;
2077 DEPTH_WEIGHT_G = 0.333333333;
2078 DEPTH_WEIGHT_B = 0.333333333;
2080 FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
2091 TfdLuminance4Alpha4ub2,
2092 TfdLuminance6Alpha2ub2,
2093 TfdLuminance8Alpha8ub2,
2094 TfdLuminance12Alpha4us2,
2095 TfdLuminance16Alpha16us2,
2154 FormatDescriptorCS: TCriticalSection;
2155 FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
2157 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2158 constructor EglBitmapUnsupportedFormat.Create(const aFormat: TglBitmapFormat);
2160 inherited Create('unsupported format: ' + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
2163 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2164 constructor EglBitmapUnsupportedFormat.Create(const aMsg: String; const aFormat: TglBitmapFormat);
2166 inherited Create(aMsg + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
2169 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2170 function glBitmapSize(X: Integer; Y: Integer): TglBitmapSize;
2172 result.Fields := [];
2174 result.Fields := result.Fields + [ffX];
2176 result.Fields := result.Fields + [ffY];
2177 result.X := Max(0, X);
2178 result.Y := Max(0, Y);
2181 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2182 function glBitmapPosition(X: Integer; Y: Integer): TglBitmapPixelPosition;
2184 result := glBitmapSize(X, Y);
2187 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2188 function glBitmapRec4ub(const r, g, b, a: Byte): TglBitmapRec4ub;
2196 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2197 function glBitmapRec4ui(const r, g, b, a: Cardinal): TglBitmapRec4ui;
2205 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2206 function glBitmapRec4ul(const r, g, b, a: QWord): TglBitmapRec4ul;
2214 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2215 function glBitmapRec4ubCompare(const r1, r2: TglBitmapRec4ub): Boolean;
2220 for i := 0 to high(r1.arr) do
2221 if (r1.arr[i] <> r2.arr[i]) then
2226 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2227 function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean;
2232 for i := 0 to high(r1.arr) do
2233 if (r1.arr[i] <> r2.arr[i]) then
2238 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2239 function glBitmapCreateTestTexture(const aFormat: TglBitmapFormat): TglBitmap2D;
2241 desc: TFormatDescriptor;
2245 px: TglBitmapPixelData;
2248 desc := TFormatDescriptor.Get(aFormat);
2249 if (desc.IsCompressed) or (desc.glFormat = 0) then
2252 p := GetMemory(ceil(25 * desc.BytesPerPixel)); // 5 x 5 pixel
2253 md := desc.CreateMappingData;
2256 desc.PreparePixel(px);
2258 for x := 0 to 4 do begin
2259 px.Data := glBitmapRec4ui(0, 0, 0, 0);
2260 for i := 0 to 3 do begin
2261 if ((y < 3) and (y = i)) or
2262 ((y = 3) and (i < 3)) or
2263 ((y = 4) and (i = 3))
2265 px.Data.arr[i] := Trunc(px.Range.arr[i] / 4 * x)
2266 else if ((y < 4) and (i = 3)) or
2267 ((y = 4) and (i < 3))
2269 px.Data.arr[i] := px.Range.arr[i]
2271 px.Data.arr[i] := 0; //px.Range.arr[i];
2273 desc.Map(px, tmp, md);
2276 desc.FreeMappingData(md);
2279 result := TglBitmap2D.Create(glBitmapPosition(5, 5), aFormat, p);
2280 result.FreeDataOnDestroy := true;
2281 result.FreeDataAfterGenTexture := false;
2282 result.SetFilter(GL_NEAREST, GL_NEAREST);
2285 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2286 function glBitmapShiftRec(const r, g, b, a: Byte): TglBitmapRec4ub;
2294 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2295 function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
2301 tfAlpha4ub1, tfAlpha8ub1,
2302 tfLuminance4ub1, tfLuminance8ub1, tfR3G3B2ub1,
2305 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
2306 tfRGBX4us1, tfXRGB4us1, tfRGB5X1us1, tfX1RGB5us1, tfR5G6B5us1, tfRGB5A1us1, tfA1RGB5us1, tfRGBA4us1, tfARGB4us1,
2307 tfBGRX4us1, tfXBGR4us1, tfBGR5X1us1, tfX1BGR5us1, tfB5G6R5us1, tfBGR5A1us1, tfA1BGR5us1, tfBGRA4us1, tfABGR4us1,
2310 tfBGR8ub3, tfRGB8ub3,
2313 tfRGBX8ui1, tfXRGB8ui1, tfRGB10X2ui1, tfX2RGB10ui1, tfRGBA8ui1, tfARGB8ui1, tfRGBA8ub4, tfRGB10A2ui1, tfA2RGB10ui1,
2314 tfBGRX8ui1, tfXBGR8ui1, tfBGR10X2ui1, tfX2BGR10ui1, tfBGRA8ui1, tfABGR8ui1, tfBGRA8ub4, tfBGR10A2ui1, tfA2BGR10ui1])
2316 result := result + [ ftBMP ];
2320 tfAlpha4ub1, tfAlpha8ub1, tfLuminance4ub1, tfLuminance8ub1,
2323 tfAlpha16us1, tfLuminance16us1,
2324 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
2325 tfX1RGB5us1, tfARGB4us1, tfA1RGB5us1, tfDepth16us1,
2331 tfX2RGB10ui1, tfARGB8ui1, tfBGRA8ub4, tfA2RGB10ui1,
2332 tfDepth24ui1, tfDepth32ui1])
2334 result := result + [ftTGA];
2336 if not (aFormat in [tfEmpty, tfRGB16us3, tfBGR16us3]) then
2337 result := result + [ftDDS];
2339 {$IFDEF GLB_SUPPORT_PNG_WRITE}
2341 tfAlpha8ub1, tfLuminance8ub1, tfLuminance8Alpha8ub2,
2342 tfRGB8ub3, tfRGBA8ui1,
2343 tfBGR8ub3, tfBGRA8ui1] then
2344 result := result + [ftPNG];
2347 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
2348 if aFormat in [tfAlpha8ub1, tfLuminance8ub1, tfRGB8ub3, tfBGR8ub3] then
2349 result := result + [ftJPEG];
2353 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2354 function IsPowerOfTwo(aNumber: Integer): Boolean;
2356 while (aNumber and 1) = 0 do
2357 aNumber := aNumber shr 1;
2358 result := aNumber = 1;
2361 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2362 function GetTopMostBit(aBitSet: QWord): Integer;
2365 while aBitSet > 0 do begin
2367 aBitSet := aBitSet shr 1;
2371 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2372 function CountSetBits(aBitSet: QWord): Integer;
2375 while aBitSet > 0 do begin
2376 if (aBitSet and 1) = 1 then
2378 aBitSet := aBitSet shr 1;
2382 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2383 function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
2386 LUMINANCE_WEIGHT_R * aPixel.Data.r +
2387 LUMINANCE_WEIGHT_G * aPixel.Data.g +
2388 LUMINANCE_WEIGHT_B * aPixel.Data.b);
2391 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2392 function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
2395 DEPTH_WEIGHT_R * aPixel.Data.r +
2396 DEPTH_WEIGHT_G * aPixel.Data.g +
2397 DEPTH_WEIGHT_B * aPixel.Data.b);
2400 {$IFDEF GLB_NATIVE_OGL}
2401 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2402 //OpenGLInitialization///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2403 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2405 GL_LibHandle: Pointer = nil;
2407 function glbGetProcAddress(aProcName: PAnsiChar; aLibHandle: Pointer = nil; const aRaiseOnErr: Boolean = true): Pointer;
2409 if not Assigned(aLibHandle) then
2410 aLibHandle := GL_LibHandle;
2412 {$IF DEFINED(GLB_WIN)}
2413 result := GetProcAddress({%H-}HMODULE(aLibHandle), aProcName);
2414 if Assigned(result) then
2417 if Assigned(wglGetProcAddress) then
2418 result := wglGetProcAddress(aProcName);
2419 {$ELSEIF DEFINED(GLB_LINUX)}
2420 if Assigned(glXGetProcAddress) then begin
2421 result := glXGetProcAddress(aProcName);
2422 if Assigned(result) then
2426 if Assigned(glXGetProcAddressARB) then begin
2427 result := glXGetProcAddressARB(aProcName);
2428 if Assigned(result) then
2432 result := dlsym(aLibHandle, aProcName);
2434 if not Assigned(result) and aRaiseOnErr then
2435 raise EglBitmap.Create('unable to load procedure form library: ' + aProcName);
2438 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
2440 GLU_LibHandle: Pointer = nil;
2441 OpenGLInitialized: Boolean;
2442 InitOpenGLCS: TCriticalSection;
2444 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2445 procedure glbInitOpenGL;
2447 ////////////////////////////////////////////////////////////////////////////////
2448 function glbLoadLibrary(const aName: PChar): Pointer;
2450 {$IF DEFINED(GLB_WIN)}
2451 result := {%H-}Pointer(LoadLibrary(aName));
2452 {$ELSEIF DEFINED(GLB_LINUX)}
2453 result := dlopen(Name, RTLD_LAZY);
2459 ////////////////////////////////////////////////////////////////////////////////
2460 function glbFreeLibrary(const aLibHandle: Pointer): Boolean;
2463 if not Assigned(aLibHandle) then
2466 {$IF DEFINED(GLB_WIN)}
2467 Result := FreeLibrary({%H-}HINST(aLibHandle));
2468 {$ELSEIF DEFINED(GLB_LINUX)}
2469 Result := dlclose(aLibHandle) = 0;
2474 if Assigned(GL_LibHandle) then
2475 glbFreeLibrary(GL_LibHandle);
2477 if Assigned(GLU_LibHandle) then
2478 glbFreeLibrary(GLU_LibHandle);
2480 GL_LibHandle := glbLoadLibrary(libopengl);
2481 if not Assigned(GL_LibHandle) then
2482 raise EglBitmap.Create('unable to load library: ' + libopengl);
2484 GLU_LibHandle := glbLoadLibrary(libglu);
2485 if not Assigned(GLU_LibHandle) then
2486 raise EglBitmap.Create('unable to load library: ' + libglu);
2488 {$IF DEFINED(GLB_WIN)}
2489 wglGetProcAddress := glbGetProcAddress('wglGetProcAddress');
2490 {$ELSEIF DEFINED(GLB_LINUX)}
2491 glXGetProcAddress := glbGetProcAddress('glXGetProcAddress');
2492 glXGetProcAddressARB := glbGetProcAddress('glXGetProcAddressARB');
2495 glEnable := glbGetProcAddress('glEnable');
2496 glDisable := glbGetProcAddress('glDisable');
2497 glGetString := glbGetProcAddress('glGetString');
2498 glGetIntegerv := glbGetProcAddress('glGetIntegerv');
2499 glTexParameteri := glbGetProcAddress('glTexParameteri');
2500 glTexParameteriv := glbGetProcAddress('glTexParameteriv');
2501 glTexParameterfv := glbGetProcAddress('glTexParameterfv');
2502 glGetTexParameteriv := glbGetProcAddress('glGetTexParameteriv');
2503 glGetTexParameterfv := glbGetProcAddress('glGetTexParameterfv');
2504 glGetTexLevelParameteriv := glbGetProcAddress('glGetTexLevelParameteriv');
2505 glGetTexLevelParameterfv := glbGetProcAddress('glGetTexLevelParameterfv');
2506 glTexGeni := glbGetProcAddress('glTexGeni');
2507 glGenTextures := glbGetProcAddress('glGenTextures');
2508 glBindTexture := glbGetProcAddress('glBindTexture');
2509 glDeleteTextures := glbGetProcAddress('glDeleteTextures');
2510 glAreTexturesResident := glbGetProcAddress('glAreTexturesResident');
2511 glReadPixels := glbGetProcAddress('glReadPixels');
2512 glPixelStorei := glbGetProcAddress('glPixelStorei');
2513 glTexImage1D := glbGetProcAddress('glTexImage1D');
2514 glTexImage2D := glbGetProcAddress('glTexImage2D');
2515 glGetTexImage := glbGetProcAddress('glGetTexImage');
2517 gluBuild1DMipmaps := glbGetProcAddress('gluBuild1DMipmaps', GLU_LibHandle);
2518 gluBuild2DMipmaps := glbGetProcAddress('gluBuild2DMipmaps', GLU_LibHandle);
2522 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2523 procedure glbReadOpenGLExtensions;
2526 MajorVersion, MinorVersion: Integer;
2528 ///////////////////////////////////////////////////////////////////////////////////////////
2529 procedure TrimVersionString(aBuffer: AnsiString; out aMajor, aMinor: Integer);
2536 Separator := Pos(AnsiString('.'), aBuffer);
2537 if (Separator > 1) and (Separator < Length(aBuffer)) and
2538 (aBuffer[Separator - 1] in ['0'..'9']) and
2539 (aBuffer[Separator + 1] in ['0'..'9']) then begin
2542 while (Separator > 0) and (aBuffer[Separator] in ['0'..'9']) do
2545 Delete(aBuffer, 1, Separator);
2546 Separator := Pos(AnsiString('.'), aBuffer) + 1;
2548 while (Separator <= Length(aBuffer)) and (AnsiChar(aBuffer[Separator]) in ['0'..'9']) do
2551 Delete(aBuffer, Separator, 255);
2552 Separator := Pos(AnsiString('.'), aBuffer);
2554 aMajor := StrToInt(Copy(String(aBuffer), 1, Separator - 1));
2555 aMinor := StrToInt(Copy(String(aBuffer), Separator + 1, 1));
2559 ///////////////////////////////////////////////////////////////////////////////////////////
2560 function CheckExtension(const Extension: AnsiString): Boolean;
2564 ExtPos := Pos(Extension, Buffer);
2565 result := ExtPos > 0;
2567 result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
2570 ///////////////////////////////////////////////////////////////////////////////////////////
2571 function CheckVersion(const aMajor, aMinor: Integer): Boolean;
2573 result := (MajorVersion > aMajor) or ((MajorVersion = aMajor) and (MinorVersion >= aMinor));
2577 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
2580 if not OpenGLInitialized then begin
2582 OpenGLInitialized := true;
2590 Buffer := glGetString(GL_VERSION);
2591 TrimVersionString(Buffer, MajorVersion, MinorVersion);
2593 GL_VERSION_1_2 := CheckVersion(1, 2);
2594 GL_VERSION_1_3 := CheckVersion(1, 3);
2595 GL_VERSION_1_4 := CheckVersion(1, 4);
2596 GL_VERSION_2_0 := CheckVersion(2, 0);
2597 GL_VERSION_3_3 := CheckVersion(3, 3);
2600 Buffer := glGetString(GL_EXTENSIONS);
2601 GL_ARB_texture_border_clamp := CheckExtension('GL_ARB_texture_border_clamp');
2602 GL_ARB_texture_non_power_of_two := CheckExtension('GL_ARB_texture_non_power_of_two');
2603 GL_ARB_texture_swizzle := CheckExtension('GL_ARB_texture_swizzle');
2604 GL_ARB_texture_cube_map := CheckExtension('GL_ARB_texture_cube_map');
2605 GL_ARB_texture_rectangle := CheckExtension('GL_ARB_texture_rectangle');
2606 GL_ARB_texture_mirrored_repeat := CheckExtension('GL_ARB_texture_mirrored_repeat');
2607 GL_EXT_texture_edge_clamp := CheckExtension('GL_EXT_texture_edge_clamp');
2608 GL_EXT_texture_filter_anisotropic := CheckExtension('GL_EXT_texture_filter_anisotropic');
2609 GL_EXT_texture_rectangle := CheckExtension('GL_EXT_texture_rectangle');
2610 GL_EXT_texture_swizzle := CheckExtension('GL_EXT_texture_swizzle');
2611 GL_EXT_texture_cube_map := CheckExtension('GL_EXT_texture_cube_map');
2612 GL_NV_texture_rectangle := CheckExtension('GL_NV_texture_rectangle');
2613 GL_IBM_texture_mirrored_repeat := CheckExtension('GL_IBM_texture_mirrored_repeat');
2614 GL_SGIS_generate_mipmap := CheckExtension('GL_SGIS_generate_mipmap');
2616 if GL_VERSION_1_3 then begin
2617 glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1D');
2618 glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2D');
2619 glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImage');
2621 glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1DARB', nil, false);
2622 glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2DARB', nil, false);
2623 glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImageARB', nil, false);
2628 {$IFDEF GLB_SDL_IMAGE}
2629 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2630 // SDL Image Helper /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2631 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2632 function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
2634 result := TStream(context^.unknown.data1).Seek(offset, whence);
2637 function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
2639 result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
2642 function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
2644 result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
2647 function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
2652 function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
2654 result := SDL_AllocRW;
2656 if result = nil then
2657 raise EglBitmap.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
2659 result^.seek := glBitmapRWseek;
2660 result^.read := glBitmapRWread;
2661 result^.write := glBitmapRWwrite;
2662 result^.close := glBitmapRWclose;
2663 result^.unknown.data1 := Stream;
2667 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2668 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
2670 glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
2673 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2674 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
2676 glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
2679 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2680 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
2682 glBitmapDefaultMipmap := aValue;
2685 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2686 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
2688 glBitmapDefaultFormat := aFormat;
2691 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2692 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
2694 glBitmapDefaultFilterMin := aMin;
2695 glBitmapDefaultFilterMag := aMag;
2698 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2699 procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
2701 glBitmapDefaultWrapS := S;
2702 glBitmapDefaultWrapT := T;
2703 glBitmapDefaultWrapR := R;
2706 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2707 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
2708 procedure glBitmapSetDefaultSwizzle(const r: GLenum = GL_RED; g: GLenum = GL_GREEN; b: GLenum = GL_BLUE; a: GLenum = GL_ALPHA);
2710 glDefaultSwizzle[0] := r;
2711 glDefaultSwizzle[1] := g;
2712 glDefaultSwizzle[2] := b;
2713 glDefaultSwizzle[3] := a;
2717 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2718 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
2720 result := glBitmapDefaultDeleteTextureOnFree;
2723 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2724 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
2726 result := glBitmapDefaultFreeDataAfterGenTextures;
2729 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2730 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
2732 result := glBitmapDefaultMipmap;
2735 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2736 function glBitmapGetDefaultFormat: TglBitmapFormat;
2738 result := glBitmapDefaultFormat;
2741 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2742 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
2744 aMin := glBitmapDefaultFilterMin;
2745 aMag := glBitmapDefaultFilterMag;
2748 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2749 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
2751 S := glBitmapDefaultWrapS;
2752 T := glBitmapDefaultWrapT;
2753 R := glBitmapDefaultWrapR;
2756 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
2757 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2758 procedure glBitmapGetDefaultSwizzle(var r, g, b, a: GLenum);
2760 r := glDefaultSwizzle[0];
2761 g := glDefaultSwizzle[1];
2762 b := glDefaultSwizzle[2];
2763 a := glDefaultSwizzle[3];
2767 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2768 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2769 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2770 function TFormatDescriptor.GetSize(const aSize: TglBitmapSize): Integer;
2774 if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
2775 w := Max(1, aSize.X);
2776 h := Max(1, aSize.Y);
2777 result := GetSize(w, h);
2782 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2783 function TFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer;
2786 if (aWidth <= 0) or (aHeight <= 0) then
2788 result := Ceil(aWidth * aHeight * BytesPerPixel);
2791 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2792 function TFormatDescriptor.CreateMappingData: Pointer;
2797 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2798 procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
2803 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2804 function TFormatDescriptor.IsEmpty: Boolean;
2806 result := (fFormat = tfEmpty);
2809 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2810 function TFormatDescriptor.MaskMatch(const aMask: TglBitmapRec4ul): Boolean;
2816 if (aMask.r = 0) and (aMask.g = 0) and (aMask.b = 0) and (aMask.a = 0) then
2817 raise EglBitmap.Create('FormatCheckFormat - All Masks are 0');
2820 if (aMask.arr[i] <> m.arr[i]) then
2825 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2826 procedure TFormatDescriptor.PreparePixel(out aPixel: TglBitmapPixelData);
2828 FillChar(aPixel{%H-}, SizeOf(aPixel), 0);
2829 aPixel.Data := Range;
2830 aPixel.Format := fFormat;
2831 aPixel.Range := Range;
2834 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2835 constructor TFormatDescriptor.Create;
2840 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2841 //TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2842 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2843 procedure TfdAlphaUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2845 aData^ := aPixel.Data.a;
2849 procedure TfdAlphaUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2854 aPixel.Data.a := aData^;
2858 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2859 //TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2860 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2861 procedure TfdLuminanceUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2863 aData^ := LuminanceWeight(aPixel);
2867 procedure TfdLuminanceUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2869 aPixel.Data.r := aData^;
2870 aPixel.Data.g := aData^;
2871 aPixel.Data.b := aData^;
2876 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2877 //TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2878 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2879 procedure TfdUniversalUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2885 if (Range.arr[i] > 0) then
2886 aData^ := aData^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2890 procedure TfdUniversalUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2895 aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and Range.arr[i];
2899 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2900 //TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2901 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2902 procedure TfdLuminanceAlphaUB2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2904 inherited Map(aPixel, aData, aMapData);
2905 aData^ := aPixel.Data.a;
2909 procedure TfdLuminanceAlphaUB2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2911 inherited Unmap(aData, aPixel, aMapData);
2912 aPixel.Data.a := aData^;
2916 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2917 //TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2918 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2919 procedure TfdRGBub3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2921 aData^ := aPixel.Data.r;
2923 aData^ := aPixel.Data.g;
2925 aData^ := aPixel.Data.b;
2929 procedure TfdRGBub3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2931 aPixel.Data.r := aData^;
2933 aPixel.Data.g := aData^;
2935 aPixel.Data.b := aData^;
2940 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2941 //TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2942 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2943 procedure TfdBGRub3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2945 aData^ := aPixel.Data.b;
2947 aData^ := aPixel.Data.g;
2949 aData^ := aPixel.Data.r;
2953 procedure TfdBGRub3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2955 aPixel.Data.b := aData^;
2957 aPixel.Data.g := aData^;
2959 aPixel.Data.r := aData^;
2964 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2965 //TfdRGBA_UB4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2966 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2967 procedure TfdRGBAub4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2969 inherited Map(aPixel, aData, aMapData);
2970 aData^ := aPixel.Data.a;
2974 procedure TfdRGBAub4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2976 inherited Unmap(aData, aPixel, aMapData);
2977 aPixel.Data.a := aData^;
2981 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2982 //TfdBGRA_UB4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2983 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2984 procedure TfdBGRAub4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2986 inherited Map(aPixel, aData, aMapData);
2987 aData^ := aPixel.Data.a;
2991 procedure TfdBGRAub4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2993 inherited Unmap(aData, aPixel, aMapData);
2994 aPixel.Data.a := aData^;
2998 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2999 //TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3000 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3001 procedure TfdAlphaUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3003 PWord(aData)^ := aPixel.Data.a;
3007 procedure TfdAlphaUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3012 aPixel.Data.a := PWord(aData)^;
3016 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3017 //TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3018 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3019 procedure TfdLuminanceUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3021 PWord(aData)^ := LuminanceWeight(aPixel);
3025 procedure TfdLuminanceUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3027 aPixel.Data.r := PWord(aData)^;
3028 aPixel.Data.g := PWord(aData)^;
3029 aPixel.Data.b := PWord(aData)^;
3034 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3035 //TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3036 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3037 procedure TfdUniversalUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3043 if (Range.arr[i] > 0) then
3044 PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
3048 procedure TfdUniversalUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3053 aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and Range.arr[i];
3057 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3058 //TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3059 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3060 procedure TfdDepthUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3062 PWord(aData)^ := DepthWeight(aPixel);
3066 procedure TfdDepthUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3068 aPixel.Data.r := PWord(aData)^;
3069 aPixel.Data.g := PWord(aData)^;
3070 aPixel.Data.b := PWord(aData)^;
3071 aPixel.Data.a := PWord(aData)^;;
3075 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3076 //TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3077 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3078 procedure TfdLuminanceAlphaUS2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3080 inherited Map(aPixel, aData, aMapData);
3081 PWord(aData)^ := aPixel.Data.a;
3085 procedure TfdLuminanceAlphaUS2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3087 inherited Unmap(aData, aPixel, aMapData);
3088 aPixel.Data.a := PWord(aData)^;
3092 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3093 //TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3094 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3095 procedure TfdRGBus3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3097 PWord(aData)^ := aPixel.Data.r;
3099 PWord(aData)^ := aPixel.Data.g;
3101 PWord(aData)^ := aPixel.Data.b;
3105 procedure TfdRGBus3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3107 aPixel.Data.r := PWord(aData)^;
3109 aPixel.Data.g := PWord(aData)^;
3111 aPixel.Data.b := PWord(aData)^;
3116 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3117 //TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3118 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3119 procedure TfdBGRus3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3121 PWord(aData)^ := aPixel.Data.b;
3123 PWord(aData)^ := aPixel.Data.g;
3125 PWord(aData)^ := aPixel.Data.r;
3129 procedure TfdBGRus3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3131 aPixel.Data.b := PWord(aData)^;
3133 aPixel.Data.g := PWord(aData)^;
3135 aPixel.Data.r := PWord(aData)^;
3140 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3141 //TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3142 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3143 procedure TfdRGBAus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3145 inherited Map(aPixel, aData, aMapData);
3146 PWord(aData)^ := aPixel.Data.a;
3150 procedure TfdRGBAus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3152 inherited Unmap(aData, aPixel, aMapData);
3153 aPixel.Data.a := PWord(aData)^;
3157 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3158 //TfdARGB_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3159 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3160 procedure TfdARGBus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3162 PWord(aData)^ := aPixel.Data.a;
3164 inherited Map(aPixel, aData, aMapData);
3167 procedure TfdARGBus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3169 aPixel.Data.a := PWord(aData)^;
3171 inherited Unmap(aData, aPixel, aMapData);
3174 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3175 //TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3176 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3177 procedure TfdBGRAus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3179 inherited Map(aPixel, aData, aMapData);
3180 PWord(aData)^ := aPixel.Data.a;
3184 procedure TfdBGRAus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3186 inherited Unmap(aData, aPixel, aMapData);
3187 aPixel.Data.a := PWord(aData)^;
3191 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3192 //TfdABGR_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3193 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3194 procedure TfdABGRus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3196 PWord(aData)^ := aPixel.Data.a;
3198 inherited Map(aPixel, aData, aMapData);
3201 procedure TfdABGRus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3203 aPixel.Data.a := PWord(aData)^;
3205 inherited Unmap(aData, aPixel, aMapData);
3208 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3209 //TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3210 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3211 procedure TfdUniversalUI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3215 PCardinal(aData)^ := 0;
3217 if (Range.arr[i] > 0) then
3218 PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
3222 procedure TfdUniversalUI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3227 aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and Range.arr[i];
3231 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3232 //TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3233 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3234 procedure TfdDepthUI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3236 PCardinal(aData)^ := DepthWeight(aPixel);
3240 procedure TfdDepthUI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3242 aPixel.Data.r := PCardinal(aData)^;
3243 aPixel.Data.g := PCardinal(aData)^;
3244 aPixel.Data.b := PCardinal(aData)^;
3245 aPixel.Data.a := PCardinal(aData)^;
3249 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3250 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3251 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3252 procedure TfdAlpha4ub1.SetValues;
3254 inherited SetValues;
3256 fFormat := tfAlpha4ub1;
3257 fWithAlpha := tfAlpha4ub1;
3258 fPrecision := glBitmapRec4ub(0, 0, 0, 8);
3259 fShift := glBitmapRec4ub(0, 0, 0, 0);
3261 fOpenGLFormat := tfAlpha4ub1;
3262 fglFormat := GL_ALPHA;
3263 fglInternalFormat := GL_ALPHA4;
3264 fglDataFormat := GL_UNSIGNED_BYTE;
3266 fOpenGLFormat := tfAlpha8ub1;
3270 procedure TfdAlpha8ub1.SetValues;
3272 inherited SetValues;
3274 fFormat := tfAlpha8ub1;
3275 fWithAlpha := tfAlpha8ub1;
3276 fPrecision := glBitmapRec4ub(0, 0, 0, 8);
3277 fShift := glBitmapRec4ub(0, 0, 0, 0);
3278 fOpenGLFormat := tfAlpha8ub1;
3279 fglFormat := GL_ALPHA;
3280 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_ALPHA8{$ELSE}GL_ALPHA{$ENDIF};
3281 fglDataFormat := GL_UNSIGNED_BYTE;
3284 procedure TfdAlpha16us1.SetValues;
3286 inherited SetValues;
3287 fBitsPerPixel := 16;
3288 fFormat := tfAlpha16us1;
3289 fWithAlpha := tfAlpha16us1;
3290 fPrecision := glBitmapRec4ub(0, 0, 0, 16);
3291 fShift := glBitmapRec4ub(0, 0, 0, 0);
3293 fOpenGLFormat := tfAlpha16us1;
3294 fglFormat := GL_ALPHA;
3295 fglInternalFormat := GL_ALPHA16;
3296 fglDataFormat := GL_UNSIGNED_SHORT;
3298 fOpenGLFormat := tfAlpha8ub1;
3302 procedure TfdLuminance4ub1.SetValues;
3304 inherited SetValues;
3306 fFormat := tfLuminance4ub1;
3307 fWithAlpha := tfLuminance4Alpha4ub2;
3308 fWithoutAlpha := tfLuminance4ub1;
3309 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
3310 fShift := glBitmapRec4ub(0, 0, 0, 0);
3312 fOpenGLFormat := tfLuminance4ub1;
3313 fglFormat := GL_LUMINANCE;
3314 fglInternalFormat := GL_LUMINANCE4;
3315 fglDataFormat := GL_UNSIGNED_BYTE;
3317 fOpenGLFormat := tfLuminance8ub1;
3321 procedure TfdLuminance8ub1.SetValues;
3323 inherited SetValues;
3325 fFormat := tfLuminance8ub1;
3326 fWithAlpha := tfLuminance8Alpha8ub2;
3327 fWithoutAlpha := tfLuminance8ub1;
3328 fOpenGLFormat := tfLuminance8ub1;
3329 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
3330 fShift := glBitmapRec4ub(0, 0, 0, 0);
3331 fglFormat := GL_LUMINANCE;
3332 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_LUMINANCE8{$ELSE}GL_LUMINANCE{$ENDIF};
3333 fglDataFormat := GL_UNSIGNED_BYTE;
3336 procedure TfdLuminance16us1.SetValues;
3338 inherited SetValues;
3339 fBitsPerPixel := 16;
3340 fFormat := tfLuminance16us1;
3341 fWithAlpha := tfLuminance16Alpha16us2;
3342 fWithoutAlpha := tfLuminance16us1;
3343 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
3344 fShift := glBitmapRec4ub( 0, 0, 0, 0);
3346 fOpenGLFormat := tfLuminance16us1;
3347 fglFormat := GL_LUMINANCE;
3348 fglInternalFormat := GL_LUMINANCE16;
3349 fglDataFormat := GL_UNSIGNED_SHORT;
3351 fOpenGLFormat := tfLuminance8ub1;
3355 procedure TfdLuminance4Alpha4ub2.SetValues;
3357 inherited SetValues;
3358 fBitsPerPixel := 16;
3359 fFormat := tfLuminance4Alpha4ub2;
3360 fWithAlpha := tfLuminance4Alpha4ub2;
3361 fWithoutAlpha := tfLuminance4ub1;
3362 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
3363 fShift := glBitmapRec4ub(0, 0, 0, 8);
3365 fOpenGLFormat := tfLuminance4Alpha4ub2;
3366 fglFormat := GL_LUMINANCE_ALPHA;
3367 fglInternalFormat := GL_LUMINANCE4_ALPHA4;
3368 fglDataFormat := GL_UNSIGNED_BYTE;
3370 fOpenGLFormat := tfLuminance8Alpha8ub2;
3374 procedure TfdLuminance6Alpha2ub2.SetValues;
3376 inherited SetValues;
3377 fBitsPerPixel := 16;
3378 fFormat := tfLuminance6Alpha2ub2;
3379 fWithAlpha := tfLuminance6Alpha2ub2;
3380 fWithoutAlpha := tfLuminance8ub1;
3381 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
3382 fShift := glBitmapRec4ub(0, 0, 0, 8);
3384 fOpenGLFormat := tfLuminance6Alpha2ub2;
3385 fglFormat := GL_LUMINANCE_ALPHA;
3386 fglInternalFormat := GL_LUMINANCE6_ALPHA2;
3387 fglDataFormat := GL_UNSIGNED_BYTE;
3389 fOpenGLFormat := tfLuminance8Alpha8ub2;
3393 procedure TfdLuminance8Alpha8ub2.SetValues;
3395 inherited SetValues;
3396 fBitsPerPixel := 16;
3397 fFormat := tfLuminance8Alpha8ub2;
3398 fWithAlpha := tfLuminance8Alpha8ub2;
3399 fWithoutAlpha := tfLuminance8ub1;
3400 fOpenGLFormat := tfLuminance8Alpha8ub2;
3401 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
3402 fShift := glBitmapRec4ub(0, 0, 0, 8);
3403 fglFormat := GL_LUMINANCE_ALPHA;
3404 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_LUMINANCE8_ALPHA8{$ELSE}GL_LUMINANCE_ALPHA{$ENDIF};
3405 fglDataFormat := GL_UNSIGNED_BYTE;
3408 procedure TfdLuminance12Alpha4us2.SetValues;
3410 inherited SetValues;
3411 fBitsPerPixel := 32;
3412 fFormat := tfLuminance12Alpha4us2;
3413 fWithAlpha := tfLuminance12Alpha4us2;
3414 fWithoutAlpha := tfLuminance16us1;
3415 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3416 fShift := glBitmapRec4ub( 0, 0, 0, 16);
3418 fOpenGLFormat := tfLuminance12Alpha4us2;
3419 fglFormat := GL_LUMINANCE_ALPHA;
3420 fglInternalFormat := GL_LUMINANCE12_ALPHA4;
3421 fglDataFormat := GL_UNSIGNED_SHORT;
3423 fOpenGLFormat := tfLuminance8Alpha8ub2;
3427 procedure TfdLuminance16Alpha16us2.SetValues;
3429 inherited SetValues;
3430 fBitsPerPixel := 32;
3431 fFormat := tfLuminance16Alpha16us2;
3432 fWithAlpha := tfLuminance16Alpha16us2;
3433 fWithoutAlpha := tfLuminance16us1;
3434 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3435 fShift := glBitmapRec4ub( 0, 0, 0, 16);
3437 fOpenGLFormat := tfLuminance16Alpha16us2;
3438 fglFormat := GL_LUMINANCE_ALPHA;
3439 fglInternalFormat := GL_LUMINANCE16_ALPHA16;
3440 fglDataFormat := GL_UNSIGNED_SHORT;
3442 fOpenGLFormat := tfLuminance8Alpha8ub2;
3446 procedure TfdR3G3B2ub1.SetValues;
3448 inherited SetValues;
3450 fFormat := tfR3G3B2ub1;
3451 fWithAlpha := tfRGBA4us1;
3452 fWithoutAlpha := tfR3G3B2ub1;
3453 fRGBInverted := tfEmpty;
3454 fPrecision := glBitmapRec4ub(3, 3, 2, 0);
3455 fShift := glBitmapRec4ub(5, 2, 0, 0);
3457 fOpenGLFormat := tfR3G3B2ub1;
3458 fglFormat := GL_RGB;
3459 fglInternalFormat := GL_R3_G3_B2;
3460 fglDataFormat := GL_UNSIGNED_BYTE_3_3_2;
3462 fOpenGLFormat := tfR5G6B5us1;
3466 procedure TfdRGBX4us1.SetValues;
3468 inherited SetValues;
3469 fBitsPerPixel := 16;
3470 fFormat := tfRGBX4us1;
3471 fWithAlpha := tfRGBA4us1;
3472 fWithoutAlpha := tfRGBX4us1;
3473 fRGBInverted := tfBGRX4us1;
3474 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
3475 fShift := glBitmapRec4ub(12, 8, 4, 0);
3477 fOpenGLFormat := tfRGBX4us1;
3478 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3479 fglInternalFormat := GL_RGB4;
3480 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3482 fOpenGLFormat := tfR5G6B5us1;
3486 procedure TfdXRGB4us1.SetValues;
3488 inherited SetValues;
3489 fBitsPerPixel := 16;
3490 fFormat := tfXRGB4us1;
3491 fWithAlpha := tfARGB4us1;
3492 fWithoutAlpha := tfXRGB4us1;
3493 fRGBInverted := tfXBGR4us1;
3494 fPrecision := glBitmapRec4ub(4, 4, 4, 0);
3495 fShift := glBitmapRec4ub(8, 4, 0, 0);
3497 fOpenGLFormat := tfXRGB4us1;
3498 fglFormat := GL_BGRA;
3499 fglInternalFormat := GL_RGB4;
3500 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3502 fOpenGLFormat := tfR5G6B5us1;
3506 procedure TfdR5G6B5us1.SetValues;
3508 inherited SetValues;
3509 fBitsPerPixel := 16;
3510 fFormat := tfR5G6B5us1;
3511 fWithAlpha := tfRGB5A1us1;
3512 fWithoutAlpha := tfR5G6B5us1;
3513 fRGBInverted := tfB5G6R5us1;
3514 fPrecision := glBitmapRec4ub( 5, 6, 5, 0);
3515 fShift := glBitmapRec4ub(11, 5, 0, 0);
3516 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
3517 fOpenGLFormat := tfR5G6B5us1;
3518 fglFormat := GL_RGB;
3519 fglInternalFormat := GL_RGB565;
3520 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5;
3522 fOpenGLFormat := tfRGB8ub3;
3526 procedure TfdRGB5X1us1.SetValues;
3528 inherited SetValues;
3529 fBitsPerPixel := 16;
3530 fFormat := tfRGB5X1us1;
3531 fWithAlpha := tfRGB5A1us1;
3532 fWithoutAlpha := tfRGB5X1us1;
3533 fRGBInverted := tfBGR5X1us1;
3534 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3535 fShift := glBitmapRec4ub(11, 6, 1, 0);
3537 fOpenGLFormat := tfRGB5X1us1;
3538 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3539 fglInternalFormat := GL_RGB5;
3540 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3542 fOpenGLFormat := tfR5G6B5us1;
3546 procedure TfdX1RGB5us1.SetValues;
3548 inherited SetValues;
3549 fBitsPerPixel := 16;
3550 fFormat := tfX1RGB5us1;
3551 fWithAlpha := tfA1RGB5us1;
3552 fWithoutAlpha := tfX1RGB5us1;
3553 fRGBInverted := tfX1BGR5us1;
3554 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3555 fShift := glBitmapRec4ub(10, 5, 0, 0);
3557 fOpenGLFormat := tfX1RGB5us1;
3558 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3559 fglInternalFormat := GL_RGB5;
3560 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3562 fOpenGLFormat := tfR5G6B5us1;
3566 procedure TfdRGB8ub3.SetValues;
3568 inherited SetValues;
3569 fBitsPerPixel := 24;
3570 fFormat := tfRGB8ub3;
3571 fWithAlpha := tfRGBA8ub4;
3572 fWithoutAlpha := tfRGB8ub3;
3573 fRGBInverted := tfBGR8ub3;
3574 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
3575 fShift := glBitmapRec4ub(0, 8, 16, 0);
3576 fOpenGLFormat := tfRGB8ub3;
3577 fglFormat := GL_RGB;
3578 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGB8{$ELSE}GL_RGB{$IFEND};
3579 fglDataFormat := GL_UNSIGNED_BYTE;
3582 procedure TfdRGBX8ui1.SetValues;
3584 inherited SetValues;
3585 fBitsPerPixel := 32;
3586 fFormat := tfRGBX8ui1;
3587 fWithAlpha := tfRGBA8ui1;
3588 fWithoutAlpha := tfRGBX8ui1;
3589 fRGBInverted := tfBGRX8ui1;
3590 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3591 fShift := glBitmapRec4ub(24, 16, 8, 0);
3593 fOpenGLFormat := tfRGBX8ui1;
3594 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3595 fglInternalFormat := GL_RGB8;
3596 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3598 fOpenGLFormat := tfRGB8ub3;
3602 procedure TfdXRGB8ui1.SetValues;
3604 inherited SetValues;
3605 fBitsPerPixel := 32;
3606 fFormat := tfXRGB8ui1;
3607 fWithAlpha := tfXRGB8ui1;
3608 fWithoutAlpha := tfXRGB8ui1;
3609 fOpenGLFormat := tfXRGB8ui1;
3610 fRGBInverted := tfXBGR8ui1;
3611 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3612 fShift := glBitmapRec4ub(16, 8, 0, 0);
3614 fOpenGLFormat := tfXRGB8ui1;
3615 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3616 fglInternalFormat := GL_RGB8;
3617 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3619 fOpenGLFormat := tfRGB8ub3;
3623 procedure TfdRGB10X2ui1.SetValues;
3625 inherited SetValues;
3626 fBitsPerPixel := 32;
3627 fFormat := tfRGB10X2ui1;
3628 fWithAlpha := tfRGB10A2ui1;
3629 fWithoutAlpha := tfRGB10X2ui1;
3630 fRGBInverted := tfBGR10X2ui1;
3631 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3632 fShift := glBitmapRec4ub(22, 12, 2, 0);
3634 fOpenGLFormat := tfRGB10X2ui1;
3635 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3636 fglInternalFormat := GL_RGB10;
3637 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3639 fOpenGLFormat := tfRGB16us3;
3643 procedure TfdX2RGB10ui1.SetValues;
3645 inherited SetValues;
3646 fBitsPerPixel := 32;
3647 fFormat := tfX2RGB10ui1;
3648 fWithAlpha := tfA2RGB10ui1;
3649 fWithoutAlpha := tfX2RGB10ui1;
3650 fRGBInverted := tfX2BGR10ui1;
3651 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3652 fShift := glBitmapRec4ub(20, 10, 0, 0);
3654 fOpenGLFormat := tfX2RGB10ui1;
3655 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3656 fglInternalFormat := GL_RGB10;
3657 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3659 fOpenGLFormat := tfRGB16us3;
3663 procedure TfdRGB16us3.SetValues;
3665 inherited SetValues;
3666 fBitsPerPixel := 48;
3667 fFormat := tfRGB16us3;
3668 fWithAlpha := tfRGBA16us4;
3669 fWithoutAlpha := tfRGB16us3;
3670 fRGBInverted := tfBGR16us3;
3671 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
3672 fShift := glBitmapRec4ub( 0, 16, 32, 0);
3673 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
3674 fOpenGLFormat := tfRGB16us3;
3675 fglFormat := GL_RGB;
3676 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_RGB16{$ELSE}GL_RGB16UI{$ENDIF};
3677 fglDataFormat := GL_UNSIGNED_SHORT;
3679 fOpenGLFormat := tfRGB8ub3;
3683 procedure TfdRGBA4us1.SetValues;
3685 inherited SetValues;
3686 fBitsPerPixel := 16;
3687 fFormat := tfRGBA4us1;
3688 fWithAlpha := tfRGBA4us1;
3689 fWithoutAlpha := tfRGBX4us1;
3690 fOpenGLFormat := tfRGBA4us1;
3691 fRGBInverted := tfBGRA4us1;
3692 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3693 fShift := glBitmapRec4ub(12, 8, 4, 0);
3694 fglFormat := GL_RGBA;
3695 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGBA8{$ELSE}GL_RGBA{$IFEND};
3696 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3699 procedure TfdARGB4us1.SetValues;
3701 inherited SetValues;
3702 fBitsPerPixel := 16;
3703 fFormat := tfARGB4us1;
3704 fWithAlpha := tfARGB4us1;
3705 fWithoutAlpha := tfXRGB4us1;
3706 fRGBInverted := tfABGR4us1;
3707 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3708 fShift := glBitmapRec4ub( 8, 4, 0, 12);
3710 fOpenGLFormat := tfARGB4us1;
3711 fglFormat := GL_BGRA;
3712 fglInternalFormat := GL_RGBA4;
3713 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3715 fOpenGLFormat := tfRGBA4us1;
3719 procedure TfdRGB5A1us1.SetValues;
3721 inherited SetValues;
3722 fBitsPerPixel := 16;
3723 fFormat := tfRGB5A1us1;
3724 fWithAlpha := tfRGB5A1us1;
3725 fWithoutAlpha := tfRGB5X1us1;
3726 fOpenGLFormat := tfRGB5A1us1;
3727 fRGBInverted := tfBGR5A1us1;
3728 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3729 fShift := glBitmapRec4ub(11, 6, 1, 0);
3730 fglFormat := GL_RGBA;
3731 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}GL_RGB5_A1{$ELSE}GL_RGBA{$IFEND};
3732 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3735 procedure TfdA1RGB5us1.SetValues;
3737 inherited SetValues;
3738 fBitsPerPixel := 16;
3739 fFormat := tfA1RGB5us1;
3740 fWithAlpha := tfA1RGB5us1;
3741 fWithoutAlpha := tfX1RGB5us1;
3742 fRGBInverted := tfA1BGR5us1;
3743 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3744 fShift := glBitmapRec4ub(10, 5, 0, 15);
3746 fOpenGLFormat := tfA1RGB5us1;
3747 fglFormat := GL_BGRA;
3748 fglInternalFormat := GL_RGB5_A1;
3749 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3751 fOpenGLFormat := tfRGB5A1us1;
3755 procedure TfdRGBA8ui1.SetValues;
3757 inherited SetValues;
3758 fBitsPerPixel := 32;
3759 fFormat := tfRGBA8ui1;
3760 fWithAlpha := tfRGBA8ui1;
3761 fWithoutAlpha := tfRGBX8ui1;
3762 fRGBInverted := tfBGRA8ui1;
3763 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3764 fShift := glBitmapRec4ub(24, 16, 8, 0);
3766 fOpenGLFormat := tfRGBA8ui1;
3767 fglFormat := GL_RGBA;
3768 fglInternalFormat := GL_RGBA8;
3769 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3771 fOpenGLFormat := tfRGBA8ub4;
3775 procedure TfdARGB8ui1.SetValues;
3777 inherited SetValues;
3778 fBitsPerPixel := 32;
3779 fFormat := tfARGB8ui1;
3780 fWithAlpha := tfARGB8ui1;
3781 fWithoutAlpha := tfXRGB8ui1;
3782 fRGBInverted := tfABGR8ui1;
3783 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3784 fShift := glBitmapRec4ub(16, 8, 0, 24);
3786 fOpenGLFormat := tfARGB8ui1;
3787 fglFormat := GL_BGRA;
3788 fglInternalFormat := GL_RGBA8;
3789 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3791 fOpenGLFormat := tfRGBA8ub4;
3795 procedure TfdRGBA8ub4.SetValues;
3797 inherited SetValues;
3798 fBitsPerPixel := 32;
3799 fFormat := tfRGBA8ub4;
3800 fWithAlpha := tfRGBA8ub4;
3801 fWithoutAlpha := tfRGB8ub3;
3802 fOpenGLFormat := tfRGBA8ub4;
3803 fRGBInverted := tfBGRA8ub4;
3804 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3805 fShift := glBitmapRec4ub( 0, 8, 16, 24);
3806 fglFormat := GL_RGBA;
3807 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGBA8{$ELSE}GL_RGBA{$IFEND};
3808 fglDataFormat := GL_UNSIGNED_BYTE;
3811 procedure TfdRGB10A2ui1.SetValues;
3813 inherited SetValues;
3814 fBitsPerPixel := 32;
3815 fFormat := tfRGB10A2ui1;
3816 fWithAlpha := tfRGB10A2ui1;
3817 fWithoutAlpha := tfRGB10X2ui1;
3818 fRGBInverted := tfBGR10A2ui1;
3819 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3820 fShift := glBitmapRec4ub(22, 12, 2, 0);
3822 fOpenGLFormat := tfRGB10A2ui1;
3823 fglFormat := GL_RGBA;
3824 fglInternalFormat := GL_RGB10_A2;
3825 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3827 fOpenGLFormat := tfA2RGB10ui1;
3831 procedure TfdA2RGB10ui1.SetValues;
3833 inherited SetValues;
3834 fBitsPerPixel := 32;
3835 fFormat := tfA2RGB10ui1;
3836 fWithAlpha := tfA2RGB10ui1;
3837 fWithoutAlpha := tfX2RGB10ui1;
3838 fRGBInverted := tfA2BGR10ui1;
3839 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3840 fShift := glBitmapRec4ub(20, 10, 0, 30);
3841 {$IF NOT DEFINED(OPENGL_ES)}
3842 fOpenGLFormat := tfA2RGB10ui1;
3843 fglFormat := GL_BGRA;
3844 fglInternalFormat := GL_RGB10_A2;
3845 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3846 {$ELSEIF DEFINED(OPENGL_ES_3_0)}
3847 fOpenGLFormat := tfA2RGB10ui1;
3848 fglFormat := GL_RGBA;
3849 fglInternalFormat := GL_RGB10_A2;
3850 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3852 fOpenGLFormat := tfRGBA8ui1;
3856 procedure TfdRGBA16us4.SetValues;
3858 inherited SetValues;
3859 fBitsPerPixel := 64;
3860 fFormat := tfRGBA16us4;
3861 fWithAlpha := tfRGBA16us4;
3862 fWithoutAlpha := tfRGB16us3;
3863 fRGBInverted := tfBGRA16us4;
3864 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3865 fShift := glBitmapRec4ub( 0, 16, 32, 48);
3866 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
3867 fOpenGLFormat := tfRGBA16us4;
3868 fglFormat := GL_RGBA;
3869 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_RGBA16{$ELSE}GL_RGBA16UI{$ENDIF};
3870 fglDataFormat := GL_UNSIGNED_SHORT;
3872 fOpenGLFormat := tfRGBA8ub4;
3876 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3877 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3878 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3879 procedure TfdBGRX4us1.SetValues;
3881 inherited SetValues;
3882 fBitsPerPixel := 16;
3883 fFormat := tfBGRX4us1;
3884 fWithAlpha := tfBGRA4us1;
3885 fWithoutAlpha := tfBGRX4us1;
3886 fRGBInverted := tfRGBX4us1;
3887 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
3888 fShift := glBitmapRec4ub( 4, 8, 12, 0);
3890 fOpenGLFormat := tfBGRX4us1;
3891 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3892 fglInternalFormat := GL_RGB4;
3893 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3895 fOpenGLFormat := tfR5G6B5us1;
3899 procedure TfdXBGR4us1.SetValues;
3901 inherited SetValues;
3902 fBitsPerPixel := 16;
3903 fFormat := tfXBGR4us1;
3904 fWithAlpha := tfABGR4us1;
3905 fWithoutAlpha := tfXBGR4us1;
3906 fRGBInverted := tfXRGB4us1;
3907 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
3908 fShift := glBitmapRec4ub( 0, 4, 8, 0);
3910 fOpenGLFormat := tfXBGR4us1;
3911 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3912 fglInternalFormat := GL_RGB4;
3913 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3915 fOpenGLFormat := tfR5G6B5us1;
3919 procedure TfdB5G6R5us1.SetValues;
3921 inherited SetValues;
3922 fBitsPerPixel := 16;
3923 fFormat := tfB5G6R5us1;
3924 fWithAlpha := tfBGR5A1us1;
3925 fWithoutAlpha := tfB5G6R5us1;
3926 fRGBInverted := tfR5G6B5us1;
3927 fPrecision := glBitmapRec4ub( 5, 6, 5, 0);
3928 fShift := glBitmapRec4ub( 0, 5, 11, 0);
3930 fOpenGLFormat := tfB5G6R5us1;
3931 fglFormat := GL_RGB;
3932 fglInternalFormat := GL_RGB565;
3933 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5_REV;
3935 fOpenGLFormat := tfR5G6B5us1;
3939 procedure TfdBGR5X1us1.SetValues;
3941 inherited SetValues;
3942 fBitsPerPixel := 16;
3943 fFormat := tfBGR5X1us1;
3944 fWithAlpha := tfBGR5A1us1;
3945 fWithoutAlpha := tfBGR5X1us1;
3946 fRGBInverted := tfRGB5X1us1;
3947 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3948 fShift := glBitmapRec4ub( 1, 6, 11, 0);
3950 fOpenGLFormat := tfBGR5X1us1;
3951 fglFormat := GL_BGRA;
3952 fglInternalFormat := GL_RGB5;
3953 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3955 fOpenGLFormat := tfR5G6B5us1;
3959 procedure TfdX1BGR5us1.SetValues;
3961 inherited SetValues;
3962 fBitsPerPixel := 16;
3963 fFormat := tfX1BGR5us1;
3964 fWithAlpha := tfA1BGR5us1;
3965 fWithoutAlpha := tfX1BGR5us1;
3966 fRGBInverted := tfX1RGB5us1;
3967 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3968 fShift := glBitmapRec4ub( 0, 5, 10, 0);
3970 fOpenGLFormat := tfX1BGR5us1;
3971 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3972 fglInternalFormat := GL_RGB5;
3973 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3975 fOpenGLFormat := tfR5G6B5us1;
3979 procedure TfdBGR8ub3.SetValues;
3981 inherited SetValues;
3982 fBitsPerPixel := 24;
3983 fFormat := tfBGR8ub3;
3984 fWithAlpha := tfBGRA8ub4;
3985 fWithoutAlpha := tfBGR8ub3;
3986 fRGBInverted := tfRGB8ub3;
3987 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3988 fShift := glBitmapRec4ub(16, 8, 0, 0);
3990 fOpenGLFormat := tfBGR8ub3;
3991 fglFormat := GL_BGR;
3992 fglInternalFormat := GL_RGB8;
3993 fglDataFormat := GL_UNSIGNED_BYTE;
3995 fOpenGLFormat := tfRGB8ub3;
3999 procedure TfdBGRX8ui1.SetValues;
4001 inherited SetValues;
4002 fBitsPerPixel := 32;
4003 fFormat := tfBGRX8ui1;
4004 fWithAlpha := tfBGRA8ui1;
4005 fWithoutAlpha := tfBGRX8ui1;
4006 fRGBInverted := tfRGBX8ui1;
4007 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
4008 fShift := glBitmapRec4ub( 8, 16, 24, 0);
4010 fOpenGLFormat := tfBGRX8ui1;
4011 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
4012 fglInternalFormat := GL_RGB8;
4013 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
4015 fOpenGLFormat := tfRGB8ub3;
4019 procedure TfdXBGR8ui1.SetValues;
4021 inherited SetValues;
4022 fBitsPerPixel := 32;
4023 fFormat := tfXBGR8ui1;
4024 fWithAlpha := tfABGR8ui1;
4025 fWithoutAlpha := tfXBGR8ui1;
4026 fRGBInverted := tfXRGB8ui1;
4027 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
4028 fShift := glBitmapRec4ub( 0, 8, 16, 0);
4030 fOpenGLFormat := tfXBGR8ui1;
4031 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
4032 fglInternalFormat := GL_RGB8;
4033 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
4035 fOpenGLFormat := tfRGB8ub3;
4039 procedure TfdBGR10X2ui1.SetValues;
4041 inherited SetValues;
4042 fBitsPerPixel := 32;
4043 fFormat := tfBGR10X2ui1;
4044 fWithAlpha := tfBGR10A2ui1;
4045 fWithoutAlpha := tfBGR10X2ui1;
4046 fRGBInverted := tfRGB10X2ui1;
4047 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
4048 fShift := glBitmapRec4ub( 2, 12, 22, 0);
4050 fOpenGLFormat := tfBGR10X2ui1;
4051 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
4052 fglInternalFormat := GL_RGB10;
4053 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
4055 fOpenGLFormat := tfRGB16us3;
4059 procedure TfdX2BGR10ui1.SetValues;
4061 inherited SetValues;
4062 fBitsPerPixel := 32;
4063 fFormat := tfX2BGR10ui1;
4064 fWithAlpha := tfA2BGR10ui1;
4065 fWithoutAlpha := tfX2BGR10ui1;
4066 fRGBInverted := tfX2RGB10ui1;
4067 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
4068 fShift := glBitmapRec4ub( 0, 10, 20, 0);
4070 fOpenGLFormat := tfX2BGR10ui1;
4071 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
4072 fglInternalFormat := GL_RGB10;
4073 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
4075 fOpenGLFormat := tfRGB16us3;
4079 procedure TfdBGR16us3.SetValues;
4081 inherited SetValues;
4082 fBitsPerPixel := 48;
4083 fFormat := tfBGR16us3;
4084 fWithAlpha := tfBGRA16us4;
4085 fWithoutAlpha := tfBGR16us3;
4086 fRGBInverted := tfRGB16us3;
4087 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
4088 fShift := glBitmapRec4ub(32, 16, 0, 0);
4090 fOpenGLFormat := tfBGR16us3;
4091 fglFormat := GL_BGR;
4092 fglInternalFormat := GL_RGB16;
4093 fglDataFormat := GL_UNSIGNED_SHORT;
4095 fOpenGLFormat := tfRGB16us3;
4099 procedure TfdBGRA4us1.SetValues;
4101 inherited SetValues;
4102 fBitsPerPixel := 16;
4103 fFormat := tfBGRA4us1;
4104 fWithAlpha := tfBGRA4us1;
4105 fWithoutAlpha := tfBGRX4us1;
4106 fRGBInverted := tfRGBA4us1;
4107 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
4108 fShift := glBitmapRec4ub( 4, 8, 12, 0);
4110 fOpenGLFormat := tfBGRA4us1;
4111 fglFormat := GL_BGRA;
4112 fglInternalFormat := GL_RGBA4;
4113 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
4115 fOpenGLFormat := tfRGBA4us1;
4119 procedure TfdABGR4us1.SetValues;
4121 inherited SetValues;
4122 fBitsPerPixel := 16;
4123 fFormat := tfABGR4us1;
4124 fWithAlpha := tfABGR4us1;
4125 fWithoutAlpha := tfXBGR4us1;
4126 fRGBInverted := tfARGB4us1;
4127 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
4128 fShift := glBitmapRec4ub( 0, 4, 8, 12);
4130 fOpenGLFormat := tfABGR4us1;
4131 fglFormat := GL_RGBA;
4132 fglInternalFormat := GL_RGBA4;
4133 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
4135 fOpenGLFormat := tfRGBA4us1;
4139 procedure TfdBGR5A1us1.SetValues;
4141 inherited SetValues;
4142 fBitsPerPixel := 16;
4143 fFormat := tfBGR5A1us1;
4144 fWithAlpha := tfBGR5A1us1;
4145 fWithoutAlpha := tfBGR5X1us1;
4146 fRGBInverted := tfRGB5A1us1;
4147 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
4148 fShift := glBitmapRec4ub( 1, 6, 11, 0);
4150 fOpenGLFormat := tfBGR5A1us1;
4151 fglFormat := GL_BGRA;
4152 fglInternalFormat := GL_RGB5_A1;
4153 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
4155 fOpenGLFormat := tfRGB5A1us1;
4159 procedure TfdA1BGR5us1.SetValues;
4161 inherited SetValues;
4162 fBitsPerPixel := 16;
4163 fFormat := tfA1BGR5us1;
4164 fWithAlpha := tfA1BGR5us1;
4165 fWithoutAlpha := tfX1BGR5us1;
4166 fRGBInverted := tfA1RGB5us1;
4167 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
4168 fShift := glBitmapRec4ub( 0, 5, 10, 15);
4170 fOpenGLFormat := tfA1BGR5us1;
4171 fglFormat := GL_RGBA;
4172 fglInternalFormat := GL_RGB5_A1;
4173 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
4175 fOpenGLFormat := tfRGB5A1us1;
4179 procedure TfdBGRA8ui1.SetValues;
4181 inherited SetValues;
4182 fBitsPerPixel := 32;
4183 fFormat := tfBGRA8ui1;
4184 fWithAlpha := tfBGRA8ui1;
4185 fWithoutAlpha := tfBGRX8ui1;
4186 fRGBInverted := tfRGBA8ui1;
4187 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
4188 fShift := glBitmapRec4ub( 8, 16, 24, 0);
4190 fOpenGLFormat := tfBGRA8ui1;
4191 fglFormat := GL_BGRA;
4192 fglInternalFormat := GL_RGBA8;
4193 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
4195 fOpenGLFormat := tfRGBA8ub4;
4199 procedure TfdABGR8ui1.SetValues;
4201 inherited SetValues;
4202 fBitsPerPixel := 32;
4203 fFormat := tfABGR8ui1;
4204 fWithAlpha := tfABGR8ui1;
4205 fWithoutAlpha := tfXBGR8ui1;
4206 fRGBInverted := tfARGB8ui1;
4207 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
4208 fShift := glBitmapRec4ub( 0, 8, 16, 24);
4210 fOpenGLFormat := tfABGR8ui1;
4211 fglFormat := GL_RGBA;
4212 fglInternalFormat := GL_RGBA8;
4213 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
4215 fOpenGLFormat := tfRGBA8ub4
4219 procedure TfdBGRA8ub4.SetValues;
4221 inherited SetValues;
4222 fBitsPerPixel := 32;
4223 fFormat := tfBGRA8ub4;
4224 fWithAlpha := tfBGRA8ub4;
4225 fWithoutAlpha := tfBGR8ub3;
4226 fRGBInverted := tfRGBA8ub4;
4227 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
4228 fShift := glBitmapRec4ub(16, 8, 0, 24);
4230 fOpenGLFormat := tfBGRA8ub4;
4231 fglFormat := GL_BGRA;
4232 fglInternalFormat := GL_RGBA8;
4233 fglDataFormat := GL_UNSIGNED_BYTE;
4235 fOpenGLFormat := tfRGBA8ub4;
4239 procedure TfdBGR10A2ui1.SetValues;
4241 inherited SetValues;
4242 fBitsPerPixel := 32;
4243 fFormat := tfBGR10A2ui1;
4244 fWithAlpha := tfBGR10A2ui1;
4245 fWithoutAlpha := tfBGR10X2ui1;
4246 fRGBInverted := tfRGB10A2ui1;
4247 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
4248 fShift := glBitmapRec4ub( 2, 12, 22, 0);
4250 fOpenGLFormat := tfBGR10A2ui1;
4251 fglFormat := GL_BGRA;
4252 fglInternalFormat := GL_RGB10_A2;
4253 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
4255 fOpenGLFormat := tfA2RGB10ui1;
4259 procedure TfdA2BGR10ui1.SetValues;
4261 inherited SetValues;
4262 fBitsPerPixel := 32;
4263 fFormat := tfA2BGR10ui1;
4264 fWithAlpha := tfA2BGR10ui1;
4265 fWithoutAlpha := tfX2BGR10ui1;
4266 fRGBInverted := tfA2RGB10ui1;
4267 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
4268 fShift := glBitmapRec4ub( 0, 10, 20, 30);
4270 fOpenGLFormat := tfA2BGR10ui1;
4271 fglFormat := GL_RGBA;
4272 fglInternalFormat := GL_RGB10_A2;
4273 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
4275 fOpenGLFormat := tfA2RGB10ui1;
4279 procedure TfdBGRA16us4.SetValues;
4281 inherited SetValues;
4282 fBitsPerPixel := 64;
4283 fFormat := tfBGRA16us4;
4284 fWithAlpha := tfBGRA16us4;
4285 fWithoutAlpha := tfBGR16us3;
4286 fRGBInverted := tfRGBA16us4;
4287 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
4288 fShift := glBitmapRec4ub(32, 16, 0, 48);
4290 fOpenGLFormat := tfBGRA16us4;
4291 fglFormat := GL_BGRA;
4292 fglInternalFormat := GL_RGBA16;
4293 fglDataFormat := GL_UNSIGNED_SHORT;
4295 fOpenGLFormat := tfRGBA16us4;
4299 procedure TfdDepth16us1.SetValues;
4301 inherited SetValues;
4302 fBitsPerPixel := 16;
4303 fFormat := tfDepth16us1;
4304 fWithoutAlpha := tfDepth16us1;
4305 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
4306 fShift := glBitmapRec4ub( 0, 0, 0, 0);
4307 {$IF NOT DEFINED (OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
4308 fOpenGLFormat := tfDepth16us1;
4309 fglFormat := GL_DEPTH_COMPONENT;
4310 fglInternalFormat := GL_DEPTH_COMPONENT16;
4311 fglDataFormat := GL_UNSIGNED_SHORT;
4315 procedure TfdDepth24ui1.SetValues;
4317 inherited SetValues;
4318 fBitsPerPixel := 32;
4319 fFormat := tfDepth24ui1;
4320 fWithoutAlpha := tfDepth24ui1;
4321 fOpenGLFormat := tfDepth24ui1;
4322 fPrecision := glBitmapRec4ub(32, 32, 32, 32);
4323 fShift := glBitmapRec4ub( 0, 0, 0, 0);
4324 {$IF NOT DEFINED (OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
4325 fOpenGLFormat := tfDepth24ui1;
4326 fglFormat := GL_DEPTH_COMPONENT;
4327 fglInternalFormat := GL_DEPTH_COMPONENT24;
4328 fglDataFormat := GL_UNSIGNED_INT;
4332 procedure TfdDepth32ui1.SetValues;
4334 inherited SetValues;
4335 fBitsPerPixel := 32;
4336 fFormat := tfDepth32ui1;
4337 fWithoutAlpha := tfDepth32ui1;
4338 fPrecision := glBitmapRec4ub(32, 32, 32, 32);
4339 fShift := glBitmapRec4ub( 0, 0, 0, 0);
4340 {$IF NOT DEFINED(OPENGL_ES)}
4341 fOpenGLFormat := tfDepth32ui1;
4342 fglFormat := GL_DEPTH_COMPONENT;
4343 fglInternalFormat := GL_DEPTH_COMPONENT32;
4344 fglDataFormat := GL_UNSIGNED_INT;
4345 {$ELSEIF DEFINED(OPENGL_ES_3_0)}
4346 fOpenGLFormat := tfDepth24ui1;
4347 {$ELSEIF DEFINED(OPENGL_ES_2_0)}
4348 fOpenGLFormat := tfDepth16us1;
4352 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4353 //TfdS3tcDtx1RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4354 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4355 procedure TfdS3tcDtx1RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4357 raise EglBitmap.Create('mapping for compressed formats is not supported');
4360 procedure TfdS3tcDtx1RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4362 raise EglBitmap.Create('mapping for compressed formats is not supported');
4365 procedure TfdS3tcDtx1RGBA.SetValues;
4367 inherited SetValues;
4368 fFormat := tfS3tcDtx1RGBA;
4369 fWithAlpha := tfS3tcDtx1RGBA;
4370 fUncompressed := tfRGB5A1us1;
4372 fIsCompressed := true;
4374 fOpenGLFormat := tfS3tcDtx1RGBA;
4375 fglFormat := GL_COMPRESSED_RGBA;
4376 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
4377 fglDataFormat := GL_UNSIGNED_BYTE;
4379 fOpenGLFormat := fUncompressed;
4383 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4384 //TfdS3tcDtx3RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4385 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4386 procedure TfdS3tcDtx3RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4388 raise EglBitmap.Create('mapping for compressed formats is not supported');
4391 procedure TfdS3tcDtx3RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4393 raise EglBitmap.Create('mapping for compressed formats is not supported');
4396 procedure TfdS3tcDtx3RGBA.SetValues;
4398 inherited SetValues;
4399 fFormat := tfS3tcDtx3RGBA;
4400 fWithAlpha := tfS3tcDtx3RGBA;
4401 fUncompressed := tfRGBA8ub4;
4403 fIsCompressed := true;
4405 fOpenGLFormat := tfS3tcDtx3RGBA;
4406 fglFormat := GL_COMPRESSED_RGBA;
4407 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
4408 fglDataFormat := GL_UNSIGNED_BYTE;
4410 fOpenGLFormat := fUncompressed;
4414 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4415 //TfdS3tcDtx5RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4416 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4417 procedure TfdS3tcDtx5RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4419 raise EglBitmap.Create('mapping for compressed formats is not supported');
4422 procedure TfdS3tcDtx5RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4424 raise EglBitmap.Create('mapping for compressed formats is not supported');
4427 procedure TfdS3tcDtx5RGBA.SetValues;
4429 inherited SetValues;
4430 fFormat := tfS3tcDtx3RGBA;
4431 fWithAlpha := tfS3tcDtx3RGBA;
4432 fUncompressed := tfRGBA8ub4;
4434 fIsCompressed := true;
4436 fOpenGLFormat := tfS3tcDtx3RGBA;
4437 fglFormat := GL_COMPRESSED_RGBA;
4438 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
4439 fglDataFormat := GL_UNSIGNED_BYTE;
4441 fOpenGLFormat := fUncompressed;
4445 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4446 //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4447 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4448 function TglBitmapFormatDescriptor.GetHasRed: Boolean;
4450 result := (fPrecision.r > 0);
4453 function TglBitmapFormatDescriptor.GetHasGreen: Boolean;
4455 result := (fPrecision.g > 0);
4458 function TglBitmapFormatDescriptor.GetHasBlue: Boolean;
4460 result := (fPrecision.b > 0);
4463 function TglBitmapFormatDescriptor.GetHasAlpha: Boolean;
4465 result := (fPrecision.a > 0);
4468 function TglBitmapFormatDescriptor.GetHasColor: Boolean;
4470 result := HasRed or HasGreen or HasBlue;
4473 function TglBitmapFormatDescriptor.GetIsGrayscale: Boolean;
4475 result := (Mask.r = Mask.g) and (Mask.g = Mask.b) and (Mask.r > 0);
4478 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4479 procedure TglBitmapFormatDescriptor.SetValues;
4482 fWithAlpha := tfEmpty;
4483 fWithoutAlpha := tfEmpty;
4484 fOpenGLFormat := tfEmpty;
4485 fRGBInverted := tfEmpty;
4486 fUncompressed := tfEmpty;
4489 fIsCompressed := false;
4492 fglInternalFormat := 0;
4495 FillChar(fPrecision, 0, SizeOf(fPrecision));
4496 FillChar(fShift, 0, SizeOf(fShift));
4499 procedure TglBitmapFormatDescriptor.CalcValues;
4503 fBytesPerPixel := fBitsPerPixel / 8;
4505 for i := 0 to 3 do begin
4506 if (fPrecision.arr[i] > 0) then
4508 fRange.arr[i] := (1 shl fPrecision.arr[i]) - 1;
4509 fMask.arr[i] := fRange.arr[i] shl fShift.arr[i];
4513 constructor TglBitmapFormatDescriptor.Create;
4520 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4521 class function TglBitmapFormatDescriptor.GetByFormat(const aInternalFormat: GLenum): TglBitmapFormatDescriptor;
4525 for f := Low(TglBitmapFormat) to High(TglBitmapFormat) do begin
4526 result := TFormatDescriptor.Get(f);
4527 if (result.glInternalFormat = aInternalFormat) then
4530 result := TFormatDescriptor.Get(tfEmpty);
4533 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4534 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4535 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4536 class procedure TFormatDescriptor.Init;
4538 if not Assigned(FormatDescriptorCS) then
4539 FormatDescriptorCS := TCriticalSection.Create;
4542 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4543 class function TFormatDescriptor.Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
4545 FormatDescriptorCS.Enter;
4547 result := FormatDescriptors[aFormat];
4548 if not Assigned(result) then begin
4549 result := FORMAT_DESCRIPTOR_CLASSES[aFormat].Create;
4550 FormatDescriptors[aFormat] := result;
4553 FormatDescriptorCS.Leave;
4557 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4558 class function TFormatDescriptor.GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
4560 result := Get(Get(aFormat).WithAlpha);
4563 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4564 class function TFormatDescriptor.GetFromMask(const aMask: TglBitmapRec4ul; const aBitCount: Integer): TFormatDescriptor;
4566 ft: TglBitmapFormat;
4568 // find matching format with OpenGL support
4569 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4571 if (result.MaskMatch(aMask)) and
4572 (result.glFormat <> 0) and
4573 (result.glInternalFormat <> 0) and
4574 ((aBitCount = 0) or (aBitCount = result.BitsPerPixel))
4579 // find matching format without OpenGL Support
4580 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4582 if result.MaskMatch(aMask) and ((aBitCount = 0) or (aBitCount = result.BitsPerPixel)) then
4586 result := TFormatDescriptor.Get(tfEmpty);
4589 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4590 class function TFormatDescriptor.GetFromPrecShift(const aPrec, aShift: TglBitmapRec4ub; const aBitCount: Integer): TFormatDescriptor;
4592 ft: TglBitmapFormat;
4594 // find matching format with OpenGL support
4595 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4597 if glBitmapRec4ubCompare(result.Shift, aShift) and
4598 glBitmapRec4ubCompare(result.Precision, aPrec) and
4599 (result.glFormat <> 0) and
4600 (result.glInternalFormat <> 0) and
4601 ((aBitCount = 0) or (aBitCount = result.BitsPerPixel))
4606 // find matching format without OpenGL Support
4607 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4609 if glBitmapRec4ubCompare(result.Shift, aShift) and
4610 glBitmapRec4ubCompare(result.Precision, aPrec) and
4611 ((aBitCount = 0) or (aBitCount = result.BitsPerPixel)) then
4615 result := TFormatDescriptor.Get(tfEmpty);
4618 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4619 class procedure TFormatDescriptor.Clear;
4623 FormatDescriptorCS.Enter;
4625 for f := low(FormatDescriptors) to high(FormatDescriptors) do
4626 FreeAndNil(FormatDescriptors[f]);
4628 FormatDescriptorCS.Leave;
4632 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4633 class procedure TFormatDescriptor.Finalize;
4636 FreeAndNil(FormatDescriptorCS);
4639 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4640 //TBitfieldFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4641 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4642 procedure TbmpBitfieldFormat.SetCustomValues(const aBPP: Integer; aMask: TglBitmapRec4ul);
4646 for i := 0 to 3 do begin
4648 while (aMask.arr[i] > 0) and (aMask.arr[i] and 1 > 0) do begin
4649 aMask.arr[i] := aMask.arr[i] shr 1;
4652 fPrecision.arr[i] := CountSetBits(aMask.arr[i]);
4657 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4658 procedure TbmpBitfieldFormat.SetCustomValues(const aBBP: Integer; const aPrec, aShift: TglBitmapRec4ub);
4660 fBitsPerPixel := aBBP;
4661 fPrecision := aPrec;
4666 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4667 procedure TbmpBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4672 ((aPixel.Data.r and Range.r) shl Shift.r) or
4673 ((aPixel.Data.g and Range.g) shl Shift.g) or
4674 ((aPixel.Data.b and Range.b) shl Shift.b) or
4675 ((aPixel.Data.a and Range.a) shl Shift.a);
4676 case BitsPerPixel of
4678 16: PWord(aData)^ := data;
4679 32: PCardinal(aData)^ := data;
4680 64: PQWord(aData)^ := data;
4682 raise EglBitmap.CreateFmt('invalid pixel size: %d', [BitsPerPixel]);
4684 inc(aData, Round(BytesPerPixel));
4687 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4688 procedure TbmpBitfieldFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4693 case BitsPerPixel of
4695 16: data := PWord(aData)^;
4696 32: data := PCardinal(aData)^;
4697 64: data := PQWord(aData)^;
4699 raise EglBitmap.CreateFmt('invalid pixel size: %d', [BitsPerPixel]);
4702 aPixel.Data.arr[i] := (data shr fShift.arr[i]) and Range.arr[i];
4703 inc(aData, Round(BytesPerPixel));
4706 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4707 //TColorTableFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4708 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4709 procedure TbmpColorTableFormat.SetValues;
4711 inherited SetValues;
4712 fShift := glBitmapRec4ub(8, 8, 8, 0);
4715 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4716 procedure TbmpColorTableFormat.SetCustomValues(const aFormat: TglBitmapFormat; const aBPP: Integer; const aPrec, aShift: TglBitmapRec4ub);
4719 fBitsPerPixel := aBPP;
4720 fPrecision := aPrec;
4725 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4726 procedure TbmpColorTableFormat.CalcValues;
4728 inherited CalcValues;
4731 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4732 procedure TbmpColorTableFormat.CreateColorTable;
4736 SetLength(fColorTable, 256);
4737 if not HasColor then begin
4739 for i := 0 to High(fColorTable) do begin
4740 fColorTable[i].r := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4741 fColorTable[i].g := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4742 fColorTable[i].b := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4743 fColorTable[i].a := 0;
4747 for i := 0 to High(fColorTable) do begin
4748 fColorTable[i].r := Round(((i shr Shift.r) and Range.r) / Range.r * 255);
4749 fColorTable[i].g := Round(((i shr Shift.g) and Range.g) / Range.g * 255);
4750 fColorTable[i].b := Round(((i shr Shift.b) and Range.b) / Range.b * 255);
4751 fColorTable[i].a := 0;
4756 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4757 procedure TbmpColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4759 if (BitsPerPixel <> 8) then
4760 raise EglBitmapUnsupportedFormat.Create('color table are only supported for 8bit formats');
4761 if not HasColor then
4763 aData^ := aPixel.Data.a
4767 ((aPixel.Data.r and Range.r) shl Shift.r) or
4768 ((aPixel.Data.g and Range.g) shl Shift.g) or
4769 ((aPixel.Data.b and Range.b) shl Shift.b));
4773 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4774 procedure TbmpColorTableFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4776 if (BitsPerPixel <> 8) then
4777 raise EglBitmapUnsupportedFormat.Create('color table are only supported for 8bit formats');
4778 with fColorTable[aData^] do begin
4787 destructor TbmpColorTableFormat.Destroy;
4789 SetLength(fColorTable, 0);
4793 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4794 //TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4795 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4796 procedure glBitmapConvertPixel(var aPixel: TglBitmapPixelData; const aSourceFD, aDestFD: TFormatDescriptor);
4800 for i := 0 to 3 do begin
4801 if (aSourceFD.Range.arr[i] <> aDestFD.Range.arr[i]) then begin
4802 if (aSourceFD.Range.arr[i] > 0) then
4803 aPixel.Data.arr[i] := Round(aPixel.Data.arr[i] / aSourceFD.Range.arr[i] * aDestFD.Range.arr[i])
4805 aPixel.Data.arr[i] := 0;
4810 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4811 procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
4813 with aFuncRec do begin
4814 if (Source.Range.r > 0) then
4815 Dest.Data.r := Source.Data.r;
4816 if (Source.Range.g > 0) then
4817 Dest.Data.g := Source.Data.g;
4818 if (Source.Range.b > 0) then
4819 Dest.Data.b := Source.Data.b;
4820 if (Source.Range.a > 0) then
4821 Dest.Data.a := Source.Data.a;
4825 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4826 procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
4830 with aFuncRec do begin
4832 if (Source.Range.arr[i] > 0) then
4833 Dest.Data.arr[i] := Round(Dest.Range.arr[i] * Source.Data.arr[i] / Source.Range.arr[i]);
4838 TShiftData = packed record
4840 0: (r, g, b, a: SmallInt);
4841 1: (arr: array[0..3] of SmallInt);
4843 PShiftData = ^TShiftData;
4845 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4846 procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
4852 if (Source.Range.arr[i] > 0) then
4853 Dest.Data.arr[i] := Source.Data.arr[i] shr PShiftData(Args)^.arr[i];
4856 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4857 procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
4859 with aFuncRec do begin
4860 Dest.Data := Source.Data;
4861 if ({%H-}PtrUInt(Args) and $1 > 0) then begin
4862 Dest.Data.r := Dest.Data.r xor Dest.Range.r;
4863 Dest.Data.g := Dest.Data.g xor Dest.Range.g;
4864 Dest.Data.b := Dest.Data.b xor Dest.Range.b;
4866 if ({%H-}PtrUInt(Args) and $2 > 0) then begin
4867 Dest.Data.a := Dest.Data.a xor Dest.Range.a;
4872 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4873 procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
4877 with aFuncRec do begin
4879 Dest.Data.arr[i] := PglBitmapPixelData(Args)^.Data.arr[i];
4883 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4884 procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4888 with FuncRec do begin
4889 if (FuncRec.Args = nil) then begin //source has no alpha
4891 Source.Data.r / Source.Range.r * ALPHA_WEIGHT_R +
4892 Source.Data.g / Source.Range.g * ALPHA_WEIGHT_G +
4893 Source.Data.b / Source.Range.b * ALPHA_WEIGHT_B;
4894 Dest.Data.a := Round(Dest.Range.a * Temp);
4896 Dest.Data.a := Round(Source.Data.a / Source.Range.a * Dest.Range.a);
4900 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4901 procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4903 PglBitmapPixelData = ^TglBitmapPixelData;
4905 with FuncRec do begin
4906 Dest.Data.r := Source.Data.r;
4907 Dest.Data.g := Source.Data.g;
4908 Dest.Data.b := Source.Data.b;
4910 with PglBitmapPixelData(Args)^ do
4911 if ((Dest.Data.r <= Data.r) and (Dest.Data.r >= Range.r) and
4912 (Dest.Data.g <= Data.g) and (Dest.Data.g >= Range.g) and
4913 (Dest.Data.b <= Data.b) and (Dest.Data.b >= Range.b)) then
4916 Dest.Data.a := Dest.Range.a;
4920 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4921 procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4923 with FuncRec do begin
4924 Dest.Data.r := Source.Data.r;
4925 Dest.Data.g := Source.Data.g;
4926 Dest.Data.b := Source.Data.b;
4927 Dest.Data.a := PCardinal(Args)^;
4931 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4932 procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
4935 TRGBPix = array [0..2] of byte;
4939 while aWidth > 0 do begin
4940 Temp := PRGBPix(aData)^[0];
4941 PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
4942 PRGBPix(aData)^[2] := Temp;
4952 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4953 //TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4954 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4955 function TglBitmap.GetFormatDesc: TglBitmapFormatDescriptor;
4957 result := TFormatDescriptor.Get(Format);
4960 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4961 function TglBitmap.GetWidth: Integer;
4963 if (ffX in fDimension.Fields) then
4964 result := fDimension.X
4969 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4970 function TglBitmap.GetHeight: Integer;
4972 if (ffY in fDimension.Fields) then
4973 result := fDimension.Y
4978 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4979 function TglBitmap.GetFileWidth: Integer;
4981 result := Max(1, Width);
4984 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4985 function TglBitmap.GetFileHeight: Integer;
4987 result := Max(1, Height);
4990 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4991 procedure TglBitmap.SetCustomData(const aValue: Pointer);
4993 if fCustomData = aValue then
4995 fCustomData := aValue;
4998 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4999 procedure TglBitmap.SetCustomName(const aValue: String);
5001 if fCustomName = aValue then
5003 fCustomName := aValue;
5006 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5007 procedure TglBitmap.SetCustomNameW(const aValue: WideString);
5009 if fCustomNameW = aValue then
5011 fCustomNameW := aValue;
5014 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5015 procedure TglBitmap.SetFreeDataOnDestroy(const aValue: Boolean);
5017 if fFreeDataOnDestroy = aValue then
5019 fFreeDataOnDestroy := aValue;
5022 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5023 procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
5025 if fDeleteTextureOnFree = aValue then
5027 fDeleteTextureOnFree := aValue;
5030 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5031 procedure TglBitmap.SetFormat(const aValue: TglBitmapFormat);
5033 if fFormat = aValue then
5035 if TFormatDescriptor.Get(Format).BitsPerPixel <> TFormatDescriptor.Get(aValue).BitsPerPixel then
5036 raise EglBitmapUnsupportedFormat.Create(Format);
5037 SetDataPointer(fData, aValue, Width, Height); //be careful, Data could be freed by this method
5040 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5041 procedure TglBitmap.SetFreeDataAfterGenTexture(const aValue: Boolean);
5043 if fFreeDataAfterGenTexture = aValue then
5045 fFreeDataAfterGenTexture := aValue;
5048 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5049 procedure TglBitmap.SetID(const aValue: Cardinal);
5051 if fID = aValue then
5056 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5057 procedure TglBitmap.SetMipMap(const aValue: TglBitmapMipMap);
5059 if fMipMap = aValue then
5064 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5065 procedure TglBitmap.SetTarget(const aValue: Cardinal);
5067 if fTarget = aValue then
5072 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5073 procedure TglBitmap.SetAnisotropic(const aValue: Integer);
5074 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_EXT)}
5076 MaxAnisotropic: Integer;
5079 fAnisotropic := aValue;
5080 if (ID > 0) then begin
5081 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_EXT)}
5082 if GL_EXT_texture_filter_anisotropic then begin
5083 if fAnisotropic > 0 then begin
5085 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
5086 if aValue > MaxAnisotropic then
5087 fAnisotropic := MaxAnisotropic;
5088 glTexParameteri(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, fAnisotropic);
5099 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5100 procedure TglBitmap.CreateID;
5103 glDeleteTextures(1, @fID);
5104 glGenTextures(1, @fID);
5108 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5109 procedure TglBitmap.SetupParameters({$IFNDEF OPENGL_ES}out aBuildWithGlu: Boolean{$ENDIF});
5111 // Set Up Parameters
5112 SetWrap(fWrapS, fWrapT, fWrapR);
5113 SetFilter(fFilterMin, fFilterMag);
5114 SetAnisotropic(fAnisotropic);
5117 SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
5118 if (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
5119 SetSwizzle(fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
5123 // Mip Maps Generation Mode
5124 aBuildWithGlu := false;
5125 if (MipMap = mmMipmap) then begin
5126 if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
5127 glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
5129 aBuildWithGlu := true;
5130 end else if (MipMap = mmMipmapGlu) then
5131 aBuildWithGlu := true;
5133 if (MipMap = mmMipmap) then
5134 glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE);
5138 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5139 procedure TglBitmap.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
5140 const aWidth: Integer; const aHeight: Integer);
5144 if (Data <> aData) then begin
5145 if (Assigned(Data)) then
5150 if not Assigned(fData) then begin
5154 FillChar(fDimension, SizeOf(fDimension), 0);
5155 if aWidth <> -1 then begin
5156 fDimension.Fields := fDimension.Fields + [ffX];
5157 fDimension.X := aWidth;
5160 if aHeight <> -1 then begin
5161 fDimension.Fields := fDimension.Fields + [ffY];
5162 fDimension.Y := aHeight;
5165 s := TFormatDescriptor.Get(aFormat).BytesPerPixel;
5167 fPixelSize := Ceil(s);
5168 fRowSize := Ceil(s * aWidth);
5172 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5173 function TglBitmap.FlipHorz: Boolean;
5178 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5179 function TglBitmap.FlipVert: Boolean;
5184 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5185 //TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5186 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5187 procedure TglBitmap.AfterConstruction;
5189 inherited AfterConstruction;
5194 fIsResident := false;
5197 fMipMap := glBitmapDefaultMipmap;
5198 fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
5199 fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
5201 glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
5202 glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
5204 glBitmapGetDefaultSwizzle (fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
5208 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5209 procedure TglBitmap.BeforeDestruction;
5213 if fFreeDataOnDestroy then begin
5215 SetDataPointer(NewData, tfEmpty); //be careful, Data could be freed by this method
5217 if (fID > 0) and fDeleteTextureOnFree then
5218 glDeleteTextures(1, @fID);
5219 inherited BeforeDestruction;
5222 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5223 procedure TglBitmap.PrepareResType(var aResource: String; var aResType: PChar);
5227 if not Assigned(aResType) then begin
5228 TempPos := Pos('.', aResource);
5229 aResType := PChar(UpperCase(Copy(aResource, TempPos + 1, Length(aResource) - TempPos)));
5230 aResource := UpperCase(Copy(aResource, 0, TempPos -1));
5234 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5235 procedure TglBitmap.LoadFromFile(const aFilename: String);
5239 if not FileExists(aFilename) then
5240 raise EglBitmap.Create('file does not exist: ' + aFilename);
5241 fFilename := aFilename;
5242 fs := TFileStream.Create(fFilename, fmOpenRead);
5251 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5252 procedure TglBitmap.LoadFromStream(const aStream: TStream);
5254 {$IFDEF GLB_SUPPORT_PNG_READ}
5255 if not LoadPNG(aStream) then
5257 {$IFDEF GLB_SUPPORT_JPEG_READ}
5258 if not LoadJPEG(aStream) then
5260 if not LoadDDS(aStream) then
5261 if not LoadTGA(aStream) then
5262 if not LoadBMP(aStream) then
5263 if not LoadRAW(aStream) then
5264 raise EglBitmap.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
5267 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5268 procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapSize; const aFunc: TglBitmapFunction;
5269 const aFormat: TglBitmapFormat; const aArgs: Pointer);
5274 size := TFormatDescriptor.Get(aFormat).GetSize(aSize);
5275 GetMem(tmpData, size);
5277 FillChar(tmpData^, size, #$FF);
5278 SetDataPointer(tmpData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
5280 if Assigned(tmpData) then
5284 Convert(Self, aFunc, false, aFormat, aArgs);
5287 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5288 procedure TglBitmap.LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar);
5290 rs: TResourceStream;
5292 PrepareResType(aResource, aResType);
5293 rs := TResourceStream.Create(aInstance, aResource, aResType);
5301 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5302 procedure TglBitmap.LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
5304 rs: TResourceStream;
5306 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
5314 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5315 procedure TglBitmap.SaveToFile(const aFilename: String; const aFileType: TglBitmapFileType);
5319 fs := TFileStream.Create(aFileName, fmCreate);
5322 SaveToStream(fs, aFileType);
5328 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5329 procedure TglBitmap.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
5332 {$IFDEF GLB_SUPPORT_PNG_WRITE}
5333 ftPNG: SavePNG(aStream);
5335 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
5336 ftJPEG: SaveJPEG(aStream);
5338 ftDDS: SaveDDS(aStream);
5339 ftTGA: SaveTGA(aStream);
5340 ftBMP: SaveBMP(aStream);
5341 ftRAW: SaveRAW(aStream);
5345 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5346 function TglBitmap.Convert(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer): Boolean;
5348 result := Convert(Self, aFunc, aCreateTemp, Format, aArgs);
5351 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5352 function TglBitmap.Convert(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
5353 const aFormat: TglBitmapFormat; const aArgs: Pointer): Boolean;
5355 DestData, TmpData, SourceData: pByte;
5356 TempHeight, TempWidth: Integer;
5357 SourceFD, DestFD: TFormatDescriptor;
5358 SourceMD, DestMD: Pointer;
5360 FuncRec: TglBitmapFunctionRec;
5362 Assert(Assigned(Data));
5363 Assert(Assigned(aSource));
5364 Assert(Assigned(aSource.Data));
5367 if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
5368 SourceFD := TFormatDescriptor.Get(aSource.Format);
5369 DestFD := TFormatDescriptor.Get(aFormat);
5371 if (SourceFD.IsCompressed) then
5372 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', SourceFD.Format);
5373 if (DestFD.IsCompressed) then
5374 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', DestFD.Format);
5376 // inkompatible Formats so CreateTemp
5377 if (SourceFD.BitsPerPixel <> DestFD.BitsPerPixel) then
5378 aCreateTemp := true;
5381 TempHeight := Max(1, aSource.Height);
5382 TempWidth := Max(1, aSource.Width);
5384 FuncRec.Sender := Self;
5385 FuncRec.Args := aArgs;
5388 if aCreateTemp then begin
5389 GetMem(TmpData, DestFD.GetSize(TempWidth, TempHeight));
5390 DestData := TmpData;
5395 SourceFD.PreparePixel(FuncRec.Source);
5396 DestFD.PreparePixel (FuncRec.Dest);
5398 SourceMD := SourceFD.CreateMappingData;
5399 DestMD := DestFD.CreateMappingData;
5401 FuncRec.Size := aSource.Dimension;
5402 FuncRec.Position.Fields := FuncRec.Size.Fields;
5405 SourceData := aSource.Data;
5406 FuncRec.Position.Y := 0;
5407 while FuncRec.Position.Y < TempHeight do begin
5408 FuncRec.Position.X := 0;
5409 while FuncRec.Position.X < TempWidth do begin
5410 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
5412 DestFD.Map(FuncRec.Dest, DestData, DestMD);
5413 inc(FuncRec.Position.X);
5415 inc(FuncRec.Position.Y);
5418 // Updating Image or InternalFormat
5420 SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height) //be careful, Data could be freed by this method
5421 else if (aFormat <> fFormat) then
5426 SourceFD.FreeMappingData(SourceMD);
5427 DestFD.FreeMappingData(DestMD);
5430 if aCreateTemp and Assigned(TmpData) then
5437 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5438 function TglBitmap.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
5440 SourceFD, DestFD: TFormatDescriptor;
5441 SourcePD, DestPD: TglBitmapPixelData;
5442 ShiftData: TShiftData;
5444 function DataIsIdentical: Boolean;
5446 result := SourceFD.MaskMatch(DestFD.Mask);
5449 function CanCopyDirect: Boolean;
5452 ((SourcePD.Range.r = DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
5453 ((SourcePD.Range.g = DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
5454 ((SourcePD.Range.b = DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
5455 ((SourcePD.Range.a = DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
5458 function CanShift: Boolean;
5461 ((SourcePD.Range.r >= DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
5462 ((SourcePD.Range.g >= DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
5463 ((SourcePD.Range.b >= DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
5464 ((SourcePD.Range.a >= DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
5467 function GetShift(aSource, aDest: Cardinal) : ShortInt;
5470 while (aSource > aDest) and (aSource > 0) do begin
5472 aSource := aSource shr 1;
5477 if (aFormat <> fFormat) and (aFormat <> tfEmpty) then begin
5478 SourceFD := TFormatDescriptor.Get(Format);
5479 DestFD := TFormatDescriptor.Get(aFormat);
5481 if DataIsIdentical then begin
5487 SourceFD.PreparePixel(SourcePD);
5488 DestFD.PreparePixel (DestPD);
5490 if CanCopyDirect then
5491 result := Convert(Self, glBitmapConvertCopyFunc, false, aFormat)
5492 else if CanShift then begin
5493 ShiftData.r := GetShift(SourcePD.Range.r, DestPD.Range.r);
5494 ShiftData.g := GetShift(SourcePD.Range.g, DestPD.Range.g);
5495 ShiftData.b := GetShift(SourcePD.Range.b, DestPD.Range.b);
5496 ShiftData.a := GetShift(SourcePD.Range.a, DestPD.Range.a);
5497 result := Convert(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, @ShiftData);
5499 result := Convert(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
5505 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5506 function TglBitmap.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
5508 Row, RowSize: Integer;
5509 SourceData, TmpData: PByte;
5511 FormatDesc: TFormatDescriptor;
5513 function GetRowPointer(Row: Integer): pByte;
5515 result := aSurface.pixels;
5516 Inc(result, Row * RowSize);
5522 FormatDesc := TFormatDescriptor.Get(Format);
5523 if FormatDesc.IsCompressed then
5524 raise EglBitmapUnsupportedFormat.Create(Format);
5526 if Assigned(Data) then begin
5527 case Trunc(FormatDesc.PixelSize) of
5533 raise EglBitmapUnsupportedFormat.Create(Format);
5536 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
5537 FormatDesc.RedMask, FormatDesc.GreenMask, FormatDesc.BlueMask, FormatDesc.AlphaMask);
5539 RowSize := FormatDesc.GetSize(FileWidth, 1);
5541 for Row := 0 to FileHeight-1 do begin
5542 TmpData := GetRowPointer(Row);
5543 if Assigned(TmpData) then begin
5544 Move(SourceData^, TmpData^, RowSize);
5545 inc(SourceData, RowSize);
5552 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5553 function TglBitmap.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
5555 pSource, pData, pTempData: PByte;
5556 Row, RowSize, TempWidth, TempHeight: Integer;
5557 IntFormat: TglBitmapFormat;
5558 fd: TFormatDescriptor;
5559 Mask: TglBitmapMask;
5561 function GetRowPointer(Row: Integer): pByte;
5563 result := aSurface^.pixels;
5564 Inc(result, Row * RowSize);
5569 if (Assigned(aSurface)) then begin
5570 with aSurface^.format^ do begin
5575 IntFormat := TFormatDescriptor.GetFromMask(Mask).Format;
5576 if (IntFormat = tfEmpty) then
5577 raise EglBitmap.Create('AssignFromSurface - Invalid Pixelformat.');
5580 fd := TFormatDescriptor.Get(IntFormat);
5581 TempWidth := aSurface^.w;
5582 TempHeight := aSurface^.h;
5583 RowSize := fd.GetSize(TempWidth, 1);
5584 GetMem(pData, TempHeight * RowSize);
5587 for Row := 0 to TempHeight -1 do begin
5588 pSource := GetRowPointer(Row);
5589 if (Assigned(pSource)) then begin
5590 Move(pSource^, pTempData^, RowSize);
5591 Inc(pTempData, RowSize);
5594 SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
5597 if Assigned(pData) then
5604 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5605 function TglBitmap.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
5607 Row, Col, AlphaInterleave: Integer;
5608 pSource, pDest: PByte;
5610 function GetRowPointer(Row: Integer): pByte;
5612 result := aSurface.pixels;
5613 Inc(result, Row * Width);
5618 if Assigned(Data) then begin
5619 if Format in [tfAlpha8ub1, tfLuminance8Alpha8ub2, tfBGRA8ub4, tfRGBA8ub4] then begin
5620 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
5622 AlphaInterleave := 0;
5624 tfLuminance8Alpha8ub2:
5625 AlphaInterleave := 1;
5626 tfBGRA8ub4, tfRGBA8ub4:
5627 AlphaInterleave := 3;
5631 for Row := 0 to Height -1 do begin
5632 pDest := GetRowPointer(Row);
5633 if Assigned(pDest) then begin
5634 for Col := 0 to Width -1 do begin
5635 Inc(pSource, AlphaInterleave);
5647 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5648 function TglBitmap.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
5652 bmp := TglBitmap2D.Create;
5654 bmp.AssignFromSurface(aSurface);
5655 result := AddAlphaFromGlBitmap(bmp, aFunc, aArgs);
5663 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5664 function CreateGrayPalette: HPALETTE;
5669 GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
5671 Pal.palVersion := $300;
5672 Pal.palNumEntries := 256;
5674 for Idx := 0 to Pal.palNumEntries - 1 do begin
5675 Pal.palPalEntry[Idx].peRed := Idx;
5676 Pal.palPalEntry[Idx].peGreen := Idx;
5677 Pal.palPalEntry[Idx].peBlue := Idx;
5678 Pal.palPalEntry[Idx].peFlags := 0;
5680 Result := CreatePalette(Pal^);
5684 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5685 function TglBitmap.AssignToBitmap(const aBitmap: TBitmap): Boolean;
5688 pSource, pData: PByte;
5691 if Assigned(Data) then begin
5692 if Assigned(aBitmap) then begin
5693 aBitmap.Width := Width;
5694 aBitmap.Height := Height;
5697 tfAlpha8ub1, tfLuminance8ub1: begin
5698 aBitmap.PixelFormat := pf8bit;
5699 aBitmap.Palette := CreateGrayPalette;
5702 aBitmap.PixelFormat := pf15bit;
5704 aBitmap.PixelFormat := pf16bit;
5705 tfRGB8ub3, tfBGR8ub3:
5706 aBitmap.PixelFormat := pf24bit;
5707 tfRGBA8ub4, tfBGRA8ub4:
5708 aBitmap.PixelFormat := pf32bit;
5710 raise EglBitmap.Create('AssignToBitmap - Invalid Pixelformat.');
5714 for Row := 0 to FileHeight -1 do begin
5715 pData := aBitmap.Scanline[Row];
5716 Move(pSource^, pData^, fRowSize);
5717 Inc(pSource, fRowSize);
5718 if (Format in [tfRGB8ub3, tfRGBA8ub4]) then // swap RGB(A) to BGR(A)
5719 SwapRGB(pData, FileWidth, Format = tfRGBA8ub4);
5726 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5727 function TglBitmap.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
5729 pSource, pData, pTempData: PByte;
5730 Row, RowSize, TempWidth, TempHeight: Integer;
5731 IntFormat: TglBitmapFormat;
5735 if (Assigned(aBitmap)) then begin
5736 case aBitmap.PixelFormat of
5738 IntFormat := tfLuminance8ub1;
5740 IntFormat := tfRGB5A1us1;
5742 IntFormat := tfR5G6B5us1;
5744 IntFormat := tfBGR8ub3;
5746 IntFormat := tfBGRA8ub4;
5748 raise EglBitmap.Create('AssignFromBitmap - Invalid Pixelformat.');
5751 TempWidth := aBitmap.Width;
5752 TempHeight := aBitmap.Height;
5753 RowSize := TFormatDescriptor.Get(IntFormat).GetSize(TempWidth, 1);
5754 GetMem(pData, TempHeight * RowSize);
5757 for Row := 0 to TempHeight -1 do begin
5758 pSource := aBitmap.Scanline[Row];
5759 if (Assigned(pSource)) then begin
5760 Move(pSource^, pTempData^, RowSize);
5761 Inc(pTempData, RowSize);
5764 SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
5767 if Assigned(pData) then
5774 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5775 function TglBitmap.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
5777 Row, Col, AlphaInterleave: Integer;
5778 pSource, pDest: PByte;
5782 if Assigned(Data) then begin
5783 if (Format in [tfAlpha8ub1, tfLuminance8Alpha8ub2, tfRGBA8ub4, tfBGRA8ub4]) then begin
5784 if Assigned(aBitmap) then begin
5785 aBitmap.PixelFormat := pf8bit;
5786 aBitmap.Palette := CreateGrayPalette;
5787 aBitmap.Width := Width;
5788 aBitmap.Height := Height;
5791 tfLuminance8Alpha8ub2:
5792 AlphaInterleave := 1;
5793 tfRGBA8ub4, tfBGRA8ub4:
5794 AlphaInterleave := 3;
5796 AlphaInterleave := 0;
5802 for Row := 0 to Height -1 do begin
5803 pDest := aBitmap.Scanline[Row];
5804 if Assigned(pDest) then begin
5805 for Col := 0 to Width -1 do begin
5806 Inc(pSource, AlphaInterleave);
5819 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5820 function TglBitmap.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5824 tex := TglBitmap2D.Create;
5826 tex.AssignFromBitmap(ABitmap);
5827 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5834 {$IFDEF GLB_LAZARUS}
5835 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5836 function TglBitmap.AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
5838 rid: TRawImageDescription;
5839 FormatDesc: TFormatDescriptor;
5841 if not Assigned(Data) then
5842 raise EglBitmap.Create('no pixel data assigned. load data before save');
5845 if not Assigned(aImage) or (Format = tfEmpty) then
5847 FormatDesc := TFormatDescriptor.Get(Format);
5848 if FormatDesc.IsCompressed then
5851 FillChar(rid{%H-}, SizeOf(rid), 0);
5852 if FormatDesc.IsGrayscale then
5853 rid.Format := ricfGray
5855 rid.Format := ricfRGBA;
5858 rid.Height := Height;
5859 rid.Depth := FormatDesc.BitsPerPixel;
5860 rid.BitOrder := riboBitsInOrder;
5861 rid.ByteOrder := riboLSBFirst;
5862 rid.LineOrder := riloTopToBottom;
5863 rid.LineEnd := rileTight;
5864 rid.BitsPerPixel := FormatDesc.BitsPerPixel;
5865 rid.RedPrec := CountSetBits(FormatDesc.Range.r);
5866 rid.GreenPrec := CountSetBits(FormatDesc.Range.g);
5867 rid.BluePrec := CountSetBits(FormatDesc.Range.b);
5868 rid.AlphaPrec := CountSetBits(FormatDesc.Range.a);
5869 rid.RedShift := FormatDesc.Shift.r;
5870 rid.GreenShift := FormatDesc.Shift.g;
5871 rid.BlueShift := FormatDesc.Shift.b;
5872 rid.AlphaShift := FormatDesc.Shift.a;
5874 rid.MaskBitsPerPixel := 0;
5875 rid.PaletteColorCount := 0;
5877 aImage.DataDescription := rid;
5880 if not Assigned(aImage.PixelData) then
5881 raise EglBitmap.Create('error while creating LazIntfImage');
5882 Move(Data^, aImage.PixelData^, FormatDesc.GetSize(Dimension));
5887 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5888 function TglBitmap.AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
5891 FormatDesc: TFormatDescriptor;
5895 Mask: TglBitmapRec4ul;
5897 procedure CopyConvert;
5899 bfFormat: TbmpBitfieldFormat;
5900 pSourceLine, pDestLine: PByte;
5901 pSourceMD, pDestMD: Pointer;
5902 Shift, Prec: TglBitmapRec4ub;
5904 pixel: TglBitmapPixelData;
5906 bfFormat := TbmpBitfieldFormat.Create;
5907 with aImage.DataDescription do begin
5909 Prec.g := GreenPrec;
5911 Prec.a := AlphaPrec;
5912 Shift.r := RedShift;
5913 Shift.g := GreenShift;
5914 Shift.b := BlueShift;
5915 Shift.a := AlphaShift;
5916 bfFormat.SetCustomValues(BitsPerPixel, Prec, Shift);
5918 pSourceMD := bfFormat.CreateMappingData;
5919 pDestMD := FormatDesc.CreateMappingData;
5921 for y := 0 to aImage.Height-1 do begin
5922 pSourceLine := aImage.PixelData + y {%H-}* aImage.DataDescription.BytesPerLine;
5923 pDestLine := ImageData + y * Round(FormatDesc.BytesPerPixel * aImage.Width);
5924 for x := 0 to aImage.Width-1 do begin
5925 bfFormat.Unmap(pSourceLine, pixel, pSourceMD);
5926 FormatDesc.Map(pixel, pDestLine, pDestMD);
5930 FormatDesc.FreeMappingData(pDestMD);
5931 bfFormat.FreeMappingData(pSourceMD);
5938 if not Assigned(aImage) then
5941 with aImage.DataDescription do begin
5942 Mask.r := (QWord(1 shl RedPrec )-1) shl RedShift;
5943 Mask.g := (QWord(1 shl GreenPrec)-1) shl GreenShift;
5944 Mask.b := (QWord(1 shl BluePrec )-1) shl BlueShift;
5945 Mask.a := (QWord(1 shl AlphaPrec)-1) shl AlphaShift;
5947 FormatDesc := TFormatDescriptor.GetFromMask(Mask);
5948 f := FormatDesc.Format;
5949 if (f = tfEmpty) then
5953 (FormatDesc.BitsPerPixel = aImage.DataDescription.Depth) and
5954 (aImage.DataDescription.BitsPerPixel = aImage.DataDescription.Depth);
5956 ImageSize := FormatDesc.GetSize(aImage.Width, aImage.Height);
5957 ImageData := GetMem(ImageSize);
5960 Move(aImage.PixelData^, ImageData^, ImageSize)
5963 SetDataPointer(ImageData, f, aImage.Width, aImage.Height); //be careful, Data could be freed by this method
5965 if Assigned(ImageData) then
5973 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5974 function TglBitmap.AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
5976 rid: TRawImageDescription;
5977 FormatDesc: TFormatDescriptor;
5978 Pixel: TglBitmapPixelData;
5984 if not Assigned(aImage) or (Format = tfEmpty) then
5986 FormatDesc := TFormatDescriptor.Get(Format);
5987 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
5990 FillChar(rid{%H-}, SizeOf(rid), 0);
5991 rid.Format := ricfGray;
5993 rid.Height := Height;
5994 rid.Depth := CountSetBits(FormatDesc.Range.a);
5995 rid.BitOrder := riboBitsInOrder;
5996 rid.ByteOrder := riboLSBFirst;
5997 rid.LineOrder := riloTopToBottom;
5998 rid.LineEnd := rileTight;
5999 rid.BitsPerPixel := 8 * Ceil(rid.Depth / 8);
6000 rid.RedPrec := CountSetBits(FormatDesc.Range.a);
6005 rid.GreenShift := 0;
6007 rid.AlphaShift := 0;
6009 rid.MaskBitsPerPixel := 0;
6010 rid.PaletteColorCount := 0;
6012 aImage.DataDescription := rid;
6015 srcMD := FormatDesc.CreateMappingData;
6017 FormatDesc.PreparePixel(Pixel);
6019 dst := aImage.PixelData;
6020 for y := 0 to Height-1 do
6021 for x := 0 to Width-1 do begin
6022 FormatDesc.Unmap(src, Pixel, srcMD);
6023 case rid.BitsPerPixel of
6025 dst^ := Pixel.Data.a;
6029 PWord(dst)^ := Pixel.Data.a;
6033 PByteArray(dst)^[0] := PByteArray(@Pixel.Data.a)^[0];
6034 PByteArray(dst)^[1] := PByteArray(@Pixel.Data.a)^[1];
6035 PByteArray(dst)^[2] := PByteArray(@Pixel.Data.a)^[2];
6039 PCardinal(dst)^ := Pixel.Data.a;
6043 raise EglBitmapUnsupportedFormat.Create(Format);
6047 FormatDesc.FreeMappingData(srcMD);
6052 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6053 function TglBitmap.AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
6057 tex := TglBitmap2D.Create;
6059 tex.AssignFromLazIntfImage(aImage);
6060 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
6067 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6068 function TglBitmap.AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar;
6069 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
6071 rs: TResourceStream;
6073 PrepareResType(aResource, aResType);
6074 rs := TResourceStream.Create(aInstance, aResource, aResType);
6076 result := AddAlphaFromStream(rs, aFunc, aArgs);
6082 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6083 function TglBitmap.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
6084 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
6086 rs: TResourceStream;
6088 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
6090 result := AddAlphaFromStream(rs, aFunc, aArgs);
6096 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6097 function TglBitmap.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
6099 if TFormatDescriptor.Get(Format).IsCompressed then
6100 raise EglBitmapUnsupportedFormat.Create(Format);
6101 result := Convert(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs);
6104 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6105 function TglBitmap.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
6109 FS := TFileStream.Create(aFileName, fmOpenRead);
6111 result := AddAlphaFromStream(FS, aFunc, aArgs);
6117 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6118 function TglBitmap.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
6122 tex := TglBitmap2D.Create(aStream);
6124 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
6130 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6131 function TglBitmap.AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
6133 DestData, DestData2, SourceData: pByte;
6134 TempHeight, TempWidth: Integer;
6135 SourceFD, DestFD: TFormatDescriptor;
6136 SourceMD, DestMD, DestMD2: Pointer;
6138 FuncRec: TglBitmapFunctionRec;
6142 Assert(Assigned(Data));
6143 Assert(Assigned(aBitmap));
6144 Assert(Assigned(aBitmap.Data));
6146 if ((aBitmap.Width = Width) and (aBitmap.Height = Height)) then begin
6147 result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
6149 SourceFD := TFormatDescriptor.Get(aBitmap.Format);
6150 DestFD := TFormatDescriptor.Get(Format);
6152 if not Assigned(aFunc) then begin
6153 aFunc := glBitmapAlphaFunc;
6154 FuncRec.Args := {%H-}Pointer(SourceFD.HasAlpha);
6156 FuncRec.Args := aArgs;
6159 TempHeight := aBitmap.FileHeight;
6160 TempWidth := aBitmap.FileWidth;
6162 FuncRec.Sender := Self;
6163 FuncRec.Size := Dimension;
6164 FuncRec.Position.Fields := FuncRec.Size.Fields;
6168 SourceData := aBitmap.Data;
6171 SourceFD.PreparePixel(FuncRec.Source);
6172 DestFD.PreparePixel (FuncRec.Dest);
6174 SourceMD := SourceFD.CreateMappingData;
6175 DestMD := DestFD.CreateMappingData;
6176 DestMD2 := DestFD.CreateMappingData;
6178 FuncRec.Position.Y := 0;
6179 while FuncRec.Position.Y < TempHeight do begin
6180 FuncRec.Position.X := 0;
6181 while FuncRec.Position.X < TempWidth do begin
6182 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
6183 DestFD.Unmap (DestData, FuncRec.Dest, DestMD);
6185 DestFD.Map(FuncRec.Dest, DestData2, DestMD2);
6186 inc(FuncRec.Position.X);
6188 inc(FuncRec.Position.Y);
6191 SourceFD.FreeMappingData(SourceMD);
6192 DestFD.FreeMappingData(DestMD);
6193 DestFD.FreeMappingData(DestMD2);
6198 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6199 function TglBitmap.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
6201 result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
6204 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6205 function TglBitmap.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
6207 PixelData: TglBitmapPixelData;
6209 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
6210 result := AddAlphaFromColorKeyFloat(
6211 aRed / PixelData.Range.r,
6212 aGreen / PixelData.Range.g,
6213 aBlue / PixelData.Range.b,
6214 aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b)));
6217 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6218 function TglBitmap.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
6220 values: array[0..2] of Single;
6223 PixelData: TglBitmapPixelData;
6225 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
6226 with PixelData do begin
6228 values[1] := aGreen;
6231 for i := 0 to 2 do begin
6232 tmp := Trunc(Range.arr[i] * aDeviation);
6233 Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp));
6234 Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp));
6239 result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, @PixelData);
6242 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6243 function TglBitmap.AddAlphaFromValue(const aAlpha: Byte): Boolean;
6245 result := AddAlphaFromValueFloat(aAlpha / $FF);
6248 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6249 function TglBitmap.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
6251 PixelData: TglBitmapPixelData;
6253 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
6254 result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
6257 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6258 function TglBitmap.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
6260 PixelData: TglBitmapPixelData;
6262 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
6264 Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
6265 result := AddAlphaFromFunc(glBitmapValueAlphaFunc, @PixelData.Data.a);
6268 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6269 function TglBitmap.RemoveAlpha: Boolean;
6271 FormatDesc: TFormatDescriptor;
6274 FormatDesc := TFormatDescriptor.Get(Format);
6275 if Assigned(Data) then begin
6276 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
6277 raise EglBitmapUnsupportedFormat.Create(Format);
6278 result := ConvertTo(FormatDesc.WithoutAlpha);
6282 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6283 function TglBitmap.Clone: TglBitmap;
6290 Temp := (ClassType.Create as TglBitmap);
6292 // copy texture data if assigned
6293 if Assigned(Data) then begin
6294 Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
6295 GetMem(TempPtr, Size);
6297 Move(Data^, TempPtr^, Size);
6298 Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
6300 if Assigned(TempPtr) then
6306 Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
6311 Temp.fTarget := Target;
6312 Temp.fFormat := Format;
6313 Temp.fMipMap := MipMap;
6314 Temp.fAnisotropic := Anisotropic;
6315 Temp.fBorderColor := fBorderColor;
6316 Temp.fDeleteTextureOnFree := DeleteTextureOnFree;
6317 Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
6318 Temp.fFilterMin := fFilterMin;
6319 Temp.fFilterMag := fFilterMag;
6320 Temp.fWrapS := fWrapS;
6321 Temp.fWrapT := fWrapT;
6322 Temp.fWrapR := fWrapR;
6323 Temp.fFilename := fFilename;
6324 Temp.fCustomName := fCustomName;
6325 Temp.fCustomNameW := fCustomNameW;
6326 Temp.fCustomData := fCustomData;
6335 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6336 procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
6338 if aUseRGB or aUseAlpha then
6339 Convert(glBitmapInvertFunc, false, {%H-}Pointer(
6340 ((Byte(aUseAlpha) and 1) shl 1) or
6341 (Byte(aUseRGB) and 1) ));
6344 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6345 procedure TglBitmap.FreeData;
6350 SetDataPointer(TempPtr, tfEmpty); //be careful, Data could be freed by this method
6354 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6355 procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
6357 fBorderColor[0] := aRed;
6358 fBorderColor[1] := aGreen;
6359 fBorderColor[2] := aBlue;
6360 fBorderColor[3] := aAlpha;
6361 if (ID > 0) then begin
6363 glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
6368 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6369 procedure TglBitmap.FillWithColor(const aRed, aGreen, aBlue: Byte;
6370 const aAlpha: Byte);
6372 FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
6375 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6376 procedure TglBitmap.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
6378 PixelData: TglBitmapPixelData;
6380 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
6382 aRed / PixelData.Range.r,
6383 aGreen / PixelData.Range.g,
6384 aBlue / PixelData.Range.b,
6385 aAlpha / PixelData.Range.a);
6388 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6389 procedure TglBitmap.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
6391 PixelData: TglBitmapPixelData;
6393 TFormatDescriptor.Get(Format).PreparePixel(PixelData);
6394 with PixelData do begin
6395 Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed)));
6396 Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen)));
6397 Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue)));
6398 Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha)));
6400 Convert(glBitmapFillWithColorFunc, false, @PixelData);
6403 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6404 procedure TglBitmap.SetFilter(const aMin, aMag: GLenum);
6409 fFilterMin := GL_NEAREST;
6411 fFilterMin := GL_LINEAR;
6412 GL_NEAREST_MIPMAP_NEAREST:
6413 fFilterMin := GL_NEAREST_MIPMAP_NEAREST;
6414 GL_LINEAR_MIPMAP_NEAREST:
6415 fFilterMin := GL_LINEAR_MIPMAP_NEAREST;
6416 GL_NEAREST_MIPMAP_LINEAR:
6417 fFilterMin := GL_NEAREST_MIPMAP_LINEAR;
6418 GL_LINEAR_MIPMAP_LINEAR:
6419 fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
6421 raise EglBitmap.Create('SetFilter - Unknow MIN filter.');
6427 fFilterMag := GL_NEAREST;
6429 fFilterMag := GL_LINEAR;
6431 raise EglBitmap.Create('SetFilter - Unknow MAG filter.');
6435 if (ID > 0) then begin
6437 glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
6439 if (MipMap = mmNone) {$IFNDEF OPENGL_ES}or (Target = GL_TEXTURE_RECTANGLE){$ENDIF} then begin
6441 GL_NEAREST, GL_LINEAR:
6442 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
6443 GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR:
6444 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6445 GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR:
6446 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6449 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
6453 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6454 procedure TglBitmap.SetWrap(const S: GLenum; const T: GLenum; const R: GLenum);
6456 procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
6461 aTarget := GL_CLAMP;
6465 aTarget := GL_REPEAT;
6467 GL_CLAMP_TO_EDGE: begin
6469 if not GL_VERSION_1_2 and not GL_EXT_texture_edge_clamp then
6473 aTarget := GL_CLAMP_TO_EDGE;
6477 GL_CLAMP_TO_BORDER: begin
6478 if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
6479 aTarget := GL_CLAMP_TO_BORDER
6481 aTarget := GL_CLAMP;
6485 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
6486 GL_MIRRORED_REPEAT: begin
6488 if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
6490 if GL_VERSION_2_0 then
6492 aTarget := GL_MIRRORED_REPEAT
6494 raise EglBitmap.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
6498 raise EglBitmap.Create('SetWrap - Unknow Texturewrap');
6503 CheckAndSetWrap(S, fWrapS);
6504 CheckAndSetWrap(T, fWrapT);
6505 CheckAndSetWrap(R, fWrapR);
6507 if (ID > 0) then begin
6509 glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
6510 glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
6511 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
6512 {$IFDEF OPENGL_ES} if GL_VERSION_3_0 then{$ENDIF}
6513 glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
6518 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
6519 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6520 procedure TglBitmap.SetSwizzle(const r, g, b, a: GLenum);
6522 procedure CheckAndSetValue(const aValue: GLenum; const aIndex: Integer);
6524 if (aValue = GL_ZERO) or (aValue = GL_ONE) or (aValue = GL_ALPHA) or
6525 (aValue = GL_RED) or (aValue = GL_GREEN) or (aValue = GL_BLUE) then
6526 fSwizzle[aIndex] := aValue
6528 raise EglBitmap.Create('SetSwizzle - Unknow Swizle Value');
6533 if not (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
6534 raise EglBitmapNotSupported.Create('texture swizzle is not supported');
6536 if not GL_VERSION_3_0 then
6537 raise EglBitmapNotSupported.Create('texture swizzle is not supported');
6539 CheckAndSetValue(r, 0);
6540 CheckAndSetValue(g, 1);
6541 CheckAndSetValue(b, 2);
6542 CheckAndSetValue(a, 3);
6544 if (ID > 0) then begin
6547 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_RGBA, PGLint(@fSwizzle[0]));
6549 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_R, PGLint(@fSwizzle[0]));
6550 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_G, PGLint(@fSwizzle[1]));
6551 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_B, PGLint(@fSwizzle[2]));
6552 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_A, PGLint(@fSwizzle[3]));
6558 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6559 procedure TglBitmap.Bind(const aEnableTextureUnit: Boolean);
6561 if aEnableTextureUnit then
6564 glBindTexture(Target, ID);
6567 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6568 procedure TglBitmap.Unbind(const aDisableTextureUnit: Boolean);
6570 if aDisableTextureUnit then
6572 glBindTexture(Target, 0);
6575 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6576 constructor TglBitmap.Create;
6578 if (ClassType = TglBitmap) then
6579 raise EglBitmap.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
6580 {$IFDEF GLB_NATIVE_OGL}
6581 glbReadOpenGLExtensions;
6584 fFormat := glBitmapGetDefaultFormat;
6585 fFreeDataOnDestroy := true;
6588 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6589 constructor TglBitmap.Create(const aFileName: String);
6592 LoadFromFile(aFileName);
6595 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6596 constructor TglBitmap.Create(const aStream: TStream);
6599 LoadFromStream(aStream);
6602 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6603 constructor TglBitmap.Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; aData: PByte);
6608 if not Assigned(aData) then begin
6609 ImageSize := TFormatDescriptor.Get(aFormat).GetSize(aSize);
6610 GetMem(aData, ImageSize);
6612 FillChar(aData^, ImageSize, #$FF);
6613 SetDataPointer(aData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
6615 if Assigned(aData) then
6620 SetDataPointer(aData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
6624 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6625 constructor TglBitmap.Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer);
6628 LoadFromFunc(aSize, aFunc, aFormat, aArgs);
6631 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6632 constructor TglBitmap.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
6635 LoadFromResource(aInstance, aResource, aResType);
6638 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6639 constructor TglBitmap.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
6642 LoadFromResourceID(aInstance, aResourceID, aResType);
6645 {$IFDEF GLB_SUPPORT_PNG_READ}
6646 {$IF DEFINED(GLB_LAZ_PNG)}
6647 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6648 //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6649 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6650 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6653 PNG_MAGIC: String[MAGIC_LEN] = #$89#$50#$4E#$47#$0D#$0A#$1A#$0A;
6655 reader: TLazReaderPNG;
6656 intf: TLazIntfImage;
6658 magic: String[MAGIC_LEN];
6661 StreamPos := aStream.Position;
6663 SetLength(magic, MAGIC_LEN);
6664 aStream.Read(magic[1], MAGIC_LEN);
6665 aStream.Position := StreamPos;
6666 if (magic <> PNG_MAGIC) then begin
6671 intf := TLazIntfImage.Create(0, 0);
6672 reader := TLazReaderPNG.Create;
6674 reader.UpdateDescription := true;
6675 reader.ImageRead(aStream, intf);
6676 AssignFromLazIntfImage(intf);
6679 aStream.Position := StreamPos;
6688 {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
6689 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6690 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6692 Surface: PSDL_Surface;
6696 RWops := glBitmapCreateRWops(aStream);
6698 if IMG_isPNG(RWops) > 0 then begin
6699 Surface := IMG_LoadPNG_RW(RWops);
6701 AssignFromSurface(Surface);
6704 SDL_FreeSurface(Surface);
6712 {$ELSEIF DEFINED(GLB_LIB_PNG)}
6713 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6714 procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
6716 TStream(png_get_io_ptr(png)).Read(buffer^, size);
6719 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6720 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6723 signature: array [0..7] of byte;
6725 png_info: png_infop;
6727 TempHeight, TempWidth: Integer;
6728 Format: TglBitmapFormat;
6731 png_rows: array of pByte;
6732 Row, LineSize: Integer;
6736 if not init_libPNG then
6737 raise Exception.Create('LoadPNG - unable to initialize libPNG.');
6741 StreamPos := aStream.Position;
6742 aStream.Read(signature{%H-}, 8);
6743 aStream.Position := StreamPos;
6745 if png_check_sig(@signature, 8) <> 0 then begin
6747 png := png_create_read_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
6749 raise EglBitmapException.Create('LoadPng - couldn''t create read struct.');
6752 png_info := png_create_info_struct(png);
6753 if png_info = nil then begin
6754 png_destroy_read_struct(@png, nil, nil);
6755 raise EglBitmapException.Create('LoadPng - couldn''t create info struct.');
6758 // set read callback
6759 png_set_read_fn(png, aStream, glBitmap_libPNG_read_func);
6761 // read informations
6762 png_read_info(png, png_info);
6765 TempHeight := png_get_image_height(png, png_info);
6766 TempWidth := png_get_image_width(png, png_info);
6769 case png_get_color_type(png, png_info) of
6770 PNG_COLOR_TYPE_GRAY:
6771 Format := tfLuminance8ub1;
6772 PNG_COLOR_TYPE_GRAY_ALPHA:
6773 Format := tfLuminance8Alpha8us1;
6775 Format := tfRGB8ub3;
6776 PNG_COLOR_TYPE_RGB_ALPHA:
6777 Format := tfRGBA8ub4;
6779 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6782 // cut upper 8 bit from 16 bit formats
6783 if png_get_bit_depth(png, png_info) > 8 then
6784 png_set_strip_16(png);
6786 // expand bitdepth smaller than 8
6787 if png_get_bit_depth(png, png_info) < 8 then
6788 png_set_expand(png);
6790 // allocating mem for scanlines
6791 LineSize := png_get_rowbytes(png, png_info);
6792 GetMem(png_data, TempHeight * LineSize);
6794 SetLength(png_rows, TempHeight);
6795 for Row := Low(png_rows) to High(png_rows) do begin
6796 png_rows[Row] := png_data;
6797 Inc(png_rows[Row], Row * LineSize);
6800 // read complete image into scanlines
6801 png_read_image(png, @png_rows[0]);
6804 png_read_end(png, png_info);
6806 // destroy read struct
6807 png_destroy_read_struct(@png, @png_info, nil);
6809 SetLength(png_rows, 0);
6812 SetDataPointer(png_data, Format, TempWidth, TempHeight); //be careful, Data could be freed by this method
6816 if Assigned(png_data) then
6826 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
6827 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6828 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6833 Row, Col, PixSize, LineSize: Integer;
6834 NewImage, pSource, pDest, pAlpha: pByte;
6835 PngFormat: TglBitmapFormat;
6836 FormatDesc: TFormatDescriptor;
6839 PngHeader: String[8] = #137#80#78#71#13#10#26#10;
6844 StreamPos := aStream.Position;
6845 aStream.Read(Header[0], SizeOf(Header));
6846 aStream.Position := StreamPos;
6848 {Test if the header matches}
6849 if Header = PngHeader then begin
6850 Png := TPNGObject.Create;
6852 Png.LoadFromStream(aStream);
6854 case Png.Header.ColorType of
6856 PngFormat := tfLuminance8ub1;
6857 COLOR_GRAYSCALEALPHA:
6858 PngFormat := tfLuminance8Alpha8us1;
6860 PngFormat := tfBGR8ub3;
6862 PngFormat := tfBGRA8ub4;
6864 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6867 FormatDesc := TFormatDescriptor.Get(PngFormat);
6868 PixSize := Round(FormatDesc.PixelSize);
6869 LineSize := FormatDesc.GetSize(Png.Header.Width, 1);
6871 GetMem(NewImage, LineSize * Integer(Png.Header.Height));
6875 case Png.Header.ColorType of
6876 COLOR_RGB, COLOR_GRAYSCALE:
6878 for Row := 0 to Png.Height -1 do begin
6879 Move (Png.Scanline[Row]^, pDest^, LineSize);
6880 Inc(pDest, LineSize);
6883 COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA:
6885 PixSize := PixSize -1;
6887 for Row := 0 to Png.Height -1 do begin
6888 pSource := Png.Scanline[Row];
6889 pAlpha := pByte(Png.AlphaScanline[Row]);
6891 for Col := 0 to Png.Width -1 do begin
6892 Move (pSource^, pDest^, PixSize);
6893 Inc(pSource, PixSize);
6894 Inc(pDest, PixSize);
6903 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6906 SetDataPointer(NewImage, PngFormat, Png.Header.Width, Png.Header.Height); //be careful, Data could be freed by this method
6910 if Assigned(NewImage) then
6922 {$IFDEF GLB_SUPPORT_PNG_WRITE}
6923 {$IFDEF GLB_LIB_PNG}
6924 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6925 procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
6927 TStream(png_get_io_ptr(png)).Write(buffer^, size);
6931 {$IF DEFINED(GLB_LAZ_PNG)}
6932 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6933 procedure TglBitmap.SavePNG(const aStream: TStream);
6935 png: TPortableNetworkGraphic;
6936 intf: TLazIntfImage;
6939 png := TPortableNetworkGraphic.Create;
6940 intf := TLazIntfImage.Create(0, 0);
6942 if not AssignToLazIntfImage(intf) then
6943 raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
6944 intf.GetRawImage(raw);
6945 png.LoadFromRawImage(raw, false);
6946 png.SaveToStream(aStream);
6953 {$ELSEIF DEFINED(GLB_LIB_PNG)}
6954 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6955 procedure TglBitmap.SavePNG(const aStream: TStream);
6958 png_info: png_infop;
6959 png_rows: array of pByte;
6963 FormatDesc: TFormatDescriptor;
6965 if not (ftPNG in FormatGetSupportedFiles(Format)) then
6966 raise EglBitmapUnsupportedFormat.Create(Format);
6968 if not init_libPNG then
6969 raise Exception.Create('unable to initialize libPNG.');
6973 tfAlpha8ub1, tfLuminance8ub1:
6974 ColorType := PNG_COLOR_TYPE_GRAY;
6975 tfLuminance8Alpha8us1:
6976 ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
6977 tfBGR8ub3, tfRGB8ub3:
6978 ColorType := PNG_COLOR_TYPE_RGB;
6979 tfBGRA8ub4, tfRGBA8ub4:
6980 ColorType := PNG_COLOR_TYPE_RGBA;
6982 raise EglBitmapUnsupportedFormat.Create(Format);
6985 FormatDesc := TFormatDescriptor.Get(Format);
6986 LineSize := FormatDesc.GetSize(Width, 1);
6988 // creating array for scanline
6989 SetLength(png_rows, Height);
6991 for Row := 0 to Height - 1 do begin
6992 png_rows[Row] := Data;
6993 Inc(png_rows[Row], Row * LineSize)
6997 png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
6999 raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
7002 png_info := png_create_info_struct(png);
7003 if png_info = nil then begin
7004 png_destroy_write_struct(@png, nil);
7005 raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
7008 // set read callback
7009 png_set_write_fn(png, aStream, glBitmap_libPNG_write_func, nil);
7012 png_set_compression_level(png, 6);
7014 if Format in [tfBGR8ub3, tfBGRA8ub4] then
7017 png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
7018 png_write_info(png, png_info);
7019 png_write_image(png, @png_rows[0]);
7020 png_write_end(png, png_info);
7021 png_destroy_write_struct(@png, @png_info);
7023 SetLength(png_rows, 0);
7030 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
7031 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7032 procedure TglBitmap.SavePNG(const aStream: TStream);
7036 pSource, pDest: pByte;
7037 X, Y, PixSize: Integer;
7038 ColorType: Cardinal;
7044 if not (ftPNG in FormatGetSupportedFiles (Format)) then
7045 raise EglBitmapUnsupportedFormat.Create(Format);
7048 tfAlpha8ub1, tfLuminance8ub1: begin
7049 ColorType := COLOR_GRAYSCALE;
7053 tfLuminance8Alpha8us1: begin
7054 ColorType := COLOR_GRAYSCALEALPHA;
7058 tfBGR8ub3, tfRGB8ub3: begin
7059 ColorType := COLOR_RGB;
7063 tfBGRA8ub4, tfRGBA8ub4: begin
7064 ColorType := COLOR_RGBALPHA;
7069 raise EglBitmapUnsupportedFormat.Create(Format);
7072 Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
7076 for Y := 0 to Height -1 do begin
7077 pDest := png.ScanLine[Y];
7078 for X := 0 to Width -1 do begin
7079 Move(pSource^, pDest^, PixSize);
7080 Inc(pDest, PixSize);
7081 Inc(pSource, PixSize);
7083 png.AlphaScanline[Y]^[X] := pSource^;
7088 // convert RGB line to BGR
7089 if Format in [tfRGB8ub3, tfRGBA8ub4] then begin
7090 pTemp := png.ScanLine[Y];
7091 for X := 0 to Width -1 do begin
7092 Temp := pByteArray(pTemp)^[0];
7093 pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
7094 pByteArray(pTemp)^[2] := Temp;
7101 Png.CompressionLevel := 6;
7102 Png.SaveToStream(aStream);
7110 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7111 //JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7112 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7113 {$IFDEF GLB_LIB_JPEG}
7115 glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
7116 glBitmap_libJPEG_source_mgr = record
7117 pub: jpeg_source_mgr;
7120 SrcBuffer: array [1..4096] of byte;
7123 glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
7124 glBitmap_libJPEG_dest_mgr = record
7125 pub: jpeg_destination_mgr;
7127 DestStream: TStream;
7128 DestBuffer: array [1..4096] of byte;
7131 procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
7137 procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
7143 procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
7148 procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
7154 procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
7160 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7161 function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
7163 src: glBitmap_libJPEG_source_mgr_ptr;
7166 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
7168 bytes := src^.SrcStream.Read(src^.SrcBuffer[1], 4096);
7169 if (bytes <= 0) then begin
7170 src^.SrcBuffer[1] := $FF;
7171 src^.SrcBuffer[2] := JPEG_EOI;
7175 src^.pub.next_input_byte := @(src^.SrcBuffer[1]);
7176 src^.pub.bytes_in_buffer := bytes;
7181 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7182 procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
7184 src: glBitmap_libJPEG_source_mgr_ptr;
7186 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
7188 if num_bytes > 0 then begin
7189 // wanted byte isn't in buffer so set stream position and read buffer
7190 if num_bytes > src^.pub.bytes_in_buffer then begin
7191 src^.SrcStream.Position := src^.SrcStream.Position + num_bytes - src^.pub.bytes_in_buffer;
7192 src^.pub.fill_input_buffer(cinfo);
7194 // wanted byte is in buffer so only skip
7195 inc(src^.pub.next_input_byte, num_bytes);
7196 dec(src^.pub.bytes_in_buffer, num_bytes);
7201 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7202 function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
7204 dest: glBitmap_libJPEG_dest_mgr_ptr;
7206 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
7208 if dest^.pub.free_in_buffer < Cardinal(Length(dest^.DestBuffer)) then begin
7209 // write complete buffer
7210 dest^.DestStream.Write(dest^.DestBuffer[1], SizeOf(dest^.DestBuffer));
7213 dest^.pub.next_output_byte := @dest^.DestBuffer[1];
7214 dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
7220 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7221 procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
7224 dest: glBitmap_libJPEG_dest_mgr_ptr;
7226 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
7228 for Idx := Low(dest^.DestBuffer) to High(dest^.DestBuffer) do begin
7229 // check for endblock
7230 if (Idx < High(dest^.DestBuffer)) and (dest^.DestBuffer[Idx] = $FF) and (dest^.DestBuffer[Idx +1] = JPEG_EOI) then begin
7232 dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
7237 dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
7242 {$IFDEF GLB_SUPPORT_JPEG_READ}
7243 {$IF DEFINED(GLB_LAZ_JPEG)}
7244 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7245 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
7248 JPEG_MAGIC: String[MAGIC_LEN] = #$FF#$D8;
7250 intf: TLazIntfImage;
7251 reader: TFPReaderJPEG;
7253 magic: String[MAGIC_LEN];
7256 StreamPos := aStream.Position;
7258 SetLength(magic, MAGIC_LEN);
7259 aStream.Read(magic[1], MAGIC_LEN);
7260 aStream.Position := StreamPos;
7261 if (magic <> JPEG_MAGIC) then begin
7266 reader := TFPReaderJPEG.Create;
7267 intf := TLazIntfImage.Create(0, 0);
7269 intf.DataDescription := GetDescriptionFromDevice(0, 0, 0);
7270 reader.ImageRead(aStream, intf);
7271 AssignFromLazIntfImage(intf);
7274 aStream.Position := StreamPos;
7283 {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
7284 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7285 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
7287 Surface: PSDL_Surface;
7292 RWops := glBitmapCreateRWops(aStream);
7294 if IMG_isJPG(RWops) > 0 then begin
7295 Surface := IMG_LoadJPG_RW(RWops);
7297 AssignFromSurface(Surface);
7300 SDL_FreeSurface(Surface);
7308 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
7309 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7310 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
7313 Temp: array[0..1]of Byte;
7315 jpeg: jpeg_decompress_struct;
7316 jpeg_err: jpeg_error_mgr;
7318 IntFormat: TglBitmapFormat;
7320 TempHeight, TempWidth: Integer;
7325 FormatDesc: TFormatDescriptor;
7329 if not init_libJPEG then
7330 raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
7333 // reading first two bytes to test file and set cursor back to begin
7334 StreamPos := aStream.Position;
7335 aStream.Read({%H-}Temp[0], 2);
7336 aStream.Position := StreamPos;
7338 // if Bitmap then read file.
7339 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
7340 FillChar(jpeg{%H-}, SizeOf(jpeg_decompress_struct), $00);
7341 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
7344 jpeg.err := jpeg_std_error(@jpeg_err);
7345 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
7346 jpeg_err.output_message := glBitmap_libJPEG_output_message;
7348 // decompression struct
7349 jpeg_create_decompress(@jpeg);
7351 // allocation space for streaming methods
7352 jpeg.src := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_source_mgr));
7354 // seeting up custom functions
7355 with glBitmap_libJPEG_source_mgr_ptr(jpeg.src)^ do begin
7356 pub.init_source := glBitmap_libJPEG_init_source;
7357 pub.fill_input_buffer := glBitmap_libJPEG_fill_input_buffer;
7358 pub.skip_input_data := glBitmap_libJPEG_skip_input_data;
7359 pub.resync_to_restart := jpeg_resync_to_restart; // use default method
7360 pub.term_source := glBitmap_libJPEG_term_source;
7362 pub.bytes_in_buffer := 0; // forces fill_input_buffer on first read
7363 pub.next_input_byte := nil; // until buffer loaded
7365 SrcStream := aStream;
7368 // set global decoding state
7369 jpeg.global_state := DSTATE_START;
7371 // read header of jpeg
7372 jpeg_read_header(@jpeg, false);
7374 // setting output parameter
7375 case jpeg.jpeg_color_space of
7378 jpeg.out_color_space := JCS_GRAYSCALE;
7379 IntFormat := tfLuminance8ub1;
7382 jpeg.out_color_space := JCS_RGB;
7383 IntFormat := tfRGB8ub3;
7387 jpeg_start_decompress(@jpeg);
7389 TempHeight := jpeg.output_height;
7390 TempWidth := jpeg.output_width;
7392 FormatDesc := TFormatDescriptor.Get(IntFormat);
7394 // creating new image
7395 GetMem(pImage, FormatDesc.GetSize(TempWidth, TempHeight));
7399 for Row := 0 to TempHeight -1 do begin
7400 jpeg_read_scanlines(@jpeg, @pTemp, 1);
7401 Inc(pTemp, FormatDesc.GetSize(TempWidth, 1));
7404 // finish decompression
7405 jpeg_finish_decompress(@jpeg);
7407 // destroy decompression
7408 jpeg_destroy_decompress(@jpeg);
7410 SetDataPointer(pImage, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
7414 if Assigned(pImage) then
7424 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
7425 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7426 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
7431 Temp: array[0..1]of Byte;
7435 // reading first two bytes to test file and set cursor back to begin
7436 StreamPos := aStream.Position;
7437 aStream.Read(Temp[0], 2);
7438 aStream.Position := StreamPos;
7440 // if Bitmap then read file.
7441 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
7442 bmp := TBitmap.Create;
7444 jpg := TJPEGImage.Create;
7446 jpg.LoadFromStream(aStream);
7448 result := AssignFromBitmap(bmp);
7460 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
7461 {$IF DEFINED(GLB_LAZ_JPEG)}
7462 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7463 procedure TglBitmap.SaveJPEG(const aStream: TStream);
7466 intf: TLazIntfImage;
7469 jpeg := TJPEGImage.Create;
7470 intf := TLazIntfImage.Create(0, 0);
7472 if not AssignToLazIntfImage(intf) then
7473 raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
7474 intf.GetRawImage(raw);
7475 jpeg.LoadFromRawImage(raw, false);
7476 jpeg.SaveToStream(aStream);
7483 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
7484 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7485 procedure TglBitmap.SaveJPEG(const aStream: TStream);
7487 jpeg: jpeg_compress_struct;
7488 jpeg_err: jpeg_error_mgr;
7490 pTemp, pTemp2: pByte;
7492 procedure CopyRow(pDest, pSource: pByte);
7496 for X := 0 to Width - 1 do begin
7497 pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
7498 pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
7499 pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
7506 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
7507 raise EglBitmapUnsupportedFormat.Create(Format);
7509 if not init_libJPEG then
7510 raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
7513 FillChar(jpeg{%H-}, SizeOf(jpeg_compress_struct), $00);
7514 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
7517 jpeg.err := jpeg_std_error(@jpeg_err);
7518 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
7519 jpeg_err.output_message := glBitmap_libJPEG_output_message;
7521 // compression struct
7522 jpeg_create_compress(@jpeg);
7524 // allocation space for streaming methods
7525 jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
7527 // seeting up custom functions
7528 with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
7529 pub.init_destination := glBitmap_libJPEG_init_destination;
7530 pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
7531 pub.term_destination := glBitmap_libJPEG_term_destination;
7533 pub.next_output_byte := @DestBuffer[1];
7534 pub.free_in_buffer := Length(DestBuffer);
7536 DestStream := aStream;
7539 // very important state
7540 jpeg.global_state := CSTATE_START;
7541 jpeg.image_width := Width;
7542 jpeg.image_height := Height;
7544 tfAlpha8ub1, tfLuminance8ub1: begin
7545 jpeg.input_components := 1;
7546 jpeg.in_color_space := JCS_GRAYSCALE;
7548 tfRGB8ub3, tfBGR8ub3: begin
7549 jpeg.input_components := 3;
7550 jpeg.in_color_space := JCS_RGB;
7554 jpeg_set_defaults(@jpeg);
7555 jpeg_set_quality(@jpeg, 95, true);
7556 jpeg_start_compress(@jpeg, true);
7559 if Format = tfBGR8ub3 then
7560 GetMem(pTemp2, fRowSize)
7565 for Row := 0 to jpeg.image_height -1 do begin
7567 if Format = tfBGR8ub3 then
7568 CopyRow(pTemp2, pTemp)
7573 jpeg_write_scanlines(@jpeg, @pTemp2, 1);
7574 inc(pTemp, fRowSize);
7578 if Format = tfBGR8ub3 then
7581 jpeg_finish_compress(@jpeg);
7582 jpeg_destroy_compress(@jpeg);
7588 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
7589 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7590 procedure TglBitmap.SaveJPEG(const aStream: TStream);
7595 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
7596 raise EglBitmapUnsupportedFormat.Create(Format);
7598 Bmp := TBitmap.Create;
7600 Jpg := TJPEGImage.Create;
7602 AssignToBitmap(Bmp);
7603 if (Format in [tfAlpha8ub1, tfLuminance8ub1]) then begin
7604 Jpg.Grayscale := true;
7605 Jpg.PixelFormat := jf8Bit;
7608 Jpg.SaveToStream(aStream);
7619 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7620 //RAW/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7621 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7623 RawHeader = packed record
7629 BitsPerPixel: Integer;
7630 Precision: TglBitmapRec4ub;
7631 Shift: TglBitmapRec4ub;
7634 function TglBitmap.LoadRAW(const aStream: TStream): Boolean;
7638 fd: TFormatDescriptor;
7642 StartPos := aStream.Position;
7643 aStream.Read(header{%H-}, SizeOf(header));
7644 if (header.Magic <> 'glBMP') then begin
7645 aStream.Position := StartPos;
7649 fd := TFormatDescriptor.GetFromPrecShift(header.Precision, header.Shift, header.BitsPerPixel);
7650 if (fd.Format = tfEmpty) then
7651 raise EglBitmapUnsupportedFormat.Create('no supported format found');
7653 buf := GetMemory(header.DataSize);
7654 aStream.Read(buf^, header.DataSize);
7655 SetDataPointer(buf, fd.Format, header.Width, header.Height);
7660 procedure TglBitmap.SaveRAW(const aStream: TStream);
7663 fd: TFormatDescriptor;
7665 fd := TFormatDescriptor.Get(Format);
7666 header.Magic := 'glBMP';
7667 header.Version := 1;
7668 header.Width := Width;
7669 header.Height := Height;
7670 header.DataSize := fd.GetSize(fDimension);
7671 header.BitsPerPixel := fd.BitsPerPixel;
7672 header.Precision := fd.Precision;
7673 header.Shift := fd.Shift;
7674 aStream.Write(header, SizeOf(header));
7675 aStream.Write(Data^, header.DataSize);
7678 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7679 //BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7680 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7687 BMP_COMP_BITFIELDS = 3;
7690 TBMPHeader = packed record
7695 bfOffBits: Cardinal;
7698 TBMPInfo = packed record
7704 biCompression: Cardinal;
7705 biSizeImage: Cardinal;
7706 biXPelsPerMeter: Longint;
7707 biYPelsPerMeter: Longint;
7708 biClrUsed: Cardinal;
7709 biClrImportant: Cardinal;
7712 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7713 function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
7715 //////////////////////////////////////////////////////////////////////////////////////////////////
7716 function ReadInfo(out aInfo: TBMPInfo; out aMask: TglBitmapRec4ul): TglBitmapFormat;
7719 aStream.Read(aInfo{%H-}, SizeOf(aInfo));
7720 FillChar(aMask{%H-}, SizeOf(aMask), 0);
7723 case aInfo.biCompression of
7725 BMP_COMP_RLE8: begin
7726 raise EglBitmap.Create('RLE compression is not supported');
7728 BMP_COMP_BITFIELDS: begin
7729 if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
7730 aStream.Read(aMask.r, SizeOf(aMask.r));
7731 aStream.Read(aMask.g, SizeOf(aMask.g));
7732 aStream.Read(aMask.b, SizeOf(aMask.b));
7733 aStream.Read(aMask.a, SizeOf(aMask.a));
7735 raise EglBitmap.Create('Bitfields are only supported for 16bit and 32bit formats');
7739 //get suitable format
7740 case aInfo.biBitCount of
7741 8: result := tfLuminance8ub1;
7742 16: result := tfX1RGB5us1;
7743 24: result := tfBGR8ub3;
7744 32: result := tfXRGB8ui1;
7748 function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TbmpColorTableFormat;
7751 ColorTable: TbmpColorTable;
7754 if (aInfo.biBitCount >= 16) then
7756 aFormat := tfLuminance8ub1;
7757 c := aInfo.biClrUsed;
7759 c := 1 shl aInfo.biBitCount;
7760 SetLength(ColorTable, c);
7761 for i := 0 to c-1 do begin
7762 aStream.Read(ColorTable[i], SizeOf(TbmpColorTableEnty));
7763 if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then
7764 aFormat := tfRGB8ub3;
7767 result := TbmpColorTableFormat.Create;
7768 result.BitsPerPixel := aInfo.biBitCount;
7769 result.ColorTable := ColorTable;
7773 //////////////////////////////////////////////////////////////////////////////////////////////////
7774 function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapRec4ul; const aInfo: TBMPInfo): TbmpBitfieldFormat;
7776 FormatDesc: TFormatDescriptor;
7779 if (aMask.r <> 0) or (aMask.g <> 0) or (aMask.b <> 0) or (aMask.a <> 0) then begin
7780 FormatDesc := TFormatDescriptor.GetFromMask(aMask);
7781 if (FormatDesc.Format = tfEmpty) then
7783 aFormat := FormatDesc.Format;
7784 if (aMask.a = 0) and TFormatDescriptor.Get(aFormat).HasAlpha then
7785 aFormat := TFormatDescriptor.Get(aFormat).WithoutAlpha;
7786 if (aMask.a <> 0) and not TFormatDescriptor.Get(aFormat).HasAlpha then
7787 aFormat := TFormatDescriptor.Get(aFormat).WithAlpha;
7789 result := TbmpBitfieldFormat.Create;
7790 result.SetCustomValues(aInfo.biBitCount, aMask);
7797 ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
7798 PaddingBuff: Cardinal;
7799 LineBuf, ImageData, TmpData: PByte;
7800 SourceMD, DestMD: Pointer;
7801 BmpFormat: TglBitmapFormat;
7804 Mask: TglBitmapRec4ul;
7809 SpecialFormat: TFormatDescriptor;
7810 FormatDesc: TFormatDescriptor;
7812 //////////////////////////////////////////////////////////////////////////////////////////////////
7813 procedure SpecialFormatReadLine(aData: PByte; aLineBuf: PByte);
7816 Pixel: TglBitmapPixelData;
7818 aStream.Read(aLineBuf^, rbLineSize);
7819 SpecialFormat.PreparePixel(Pixel);
7820 for i := 0 to Info.biWidth-1 do begin
7821 SpecialFormat.Unmap(aLineBuf, Pixel, SourceMD);
7822 glBitmapConvertPixel(Pixel, SpecialFormat, FormatDesc);
7823 FormatDesc.Map(Pixel, aData, DestMD);
7829 BmpFormat := tfEmpty;
7830 SpecialFormat := nil;
7836 StartPos := aStream.Position;
7837 aStream.Read(Header{%H-}, SizeOf(Header));
7839 if Header.bfType = BMP_MAGIC then begin
7841 BmpFormat := ReadInfo(Info, Mask);
7842 SpecialFormat := ReadColorTable(BmpFormat, Info);
7843 if not Assigned(SpecialFormat) then
7844 SpecialFormat := CheckBitfields(BmpFormat, Mask, Info);
7845 aStream.Position := StartPos + Header.bfOffBits;
7847 if (BmpFormat <> tfEmpty) then begin
7848 FormatDesc := TFormatDescriptor.Get(BmpFormat);
7849 rbLineSize := Round(Info.biWidth * Info.biBitCount / 8); //ReadBuffer LineSize
7850 wbLineSize := Trunc(Info.biWidth * FormatDesc.BytesPerPixel);
7851 Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
7854 DestMD := FormatDesc.CreateMappingData;
7855 ImageSize := FormatDesc.GetSize(Info.biWidth, abs(Info.biHeight));
7856 GetMem(ImageData, ImageSize);
7857 if Assigned(SpecialFormat) then begin
7858 GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
7859 SourceMD := SpecialFormat.CreateMappingData;
7864 FillChar(ImageData^, ImageSize, $FF);
7865 TmpData := ImageData;
7866 if (Info.biHeight > 0) then
7867 Inc(TmpData, wbLineSize * (Info.biHeight-1));
7868 for i := 0 to Abs(Info.biHeight)-1 do begin
7869 if Assigned(SpecialFormat) then
7870 SpecialFormatReadLine(TmpData, LineBuf) //if is special format read and convert data
7872 aStream.Read(TmpData^, wbLineSize); //else only read data
7873 if (Info.biHeight > 0) then
7874 dec(TmpData, wbLineSize)
7876 inc(TmpData, wbLineSize);
7877 aStream.Read(PaddingBuff{%H-}, Padding);
7879 SetDataPointer(ImageData, BmpFormat, Info.biWidth, abs(Info.biHeight)); //be careful, Data could be freed by this method
7882 if Assigned(LineBuf) then
7884 if Assigned(SourceMD) then
7885 SpecialFormat.FreeMappingData(SourceMD);
7886 FormatDesc.FreeMappingData(DestMD);
7889 if Assigned(ImageData) then
7894 raise EglBitmap.Create('LoadBMP - No suitable format found');
7896 aStream.Position := StartPos;
7900 FreeAndNil(SpecialFormat);
7903 else aStream.Position := StartPos;
7906 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7907 procedure TglBitmap.SaveBMP(const aStream: TStream);
7911 Converter: TFormatDescriptor;
7912 FormatDesc: TFormatDescriptor;
7913 SourceFD, DestFD: Pointer;
7914 pData, srcData, dstData, ConvertBuffer: pByte;
7916 Pixel: TglBitmapPixelData;
7917 ImageSize, wbLineSize, rbLineSize, Padding, LineIdx, PixelIdx: Integer;
7918 RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
7920 PaddingBuff: Cardinal;
7922 function GetLineWidth : Integer;
7924 result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
7928 if not (ftBMP in FormatGetSupportedFiles(Format)) then
7929 raise EglBitmapUnsupportedFormat.Create(Format);
7932 FormatDesc := TFormatDescriptor.Get(Format);
7933 ImageSize := FormatDesc.GetSize(Dimension);
7935 FillChar(Header{%H-}, SizeOf(Header), 0);
7936 Header.bfType := BMP_MAGIC;
7937 Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
7938 Header.bfReserved1 := 0;
7939 Header.bfReserved2 := 0;
7940 Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
7942 FillChar(Info{%H-}, SizeOf(Info), 0);
7943 Info.biSize := SizeOf(Info);
7944 Info.biWidth := Width;
7945 Info.biHeight := Height;
7947 Info.biCompression := BMP_COMP_RGB;
7948 Info.biSizeImage := ImageSize;
7952 tfAlpha4ub1, tfAlpha8ub1, tfLuminance4ub1, tfLuminance8ub1, tfR3G3B2ub1:
7954 Info.biBitCount := 8;
7955 Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
7956 Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal); //256 ColorTable entries
7957 Converter := TbmpColorTableFormat.Create;
7958 with (Converter as TbmpColorTableFormat) do begin
7959 SetCustomValues(fFormat, 1, FormatDesc.Precision, FormatDesc.Shift);
7964 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
7965 tfRGBX4us1, tfXRGB4us1, tfRGB5X1us1, tfX1RGB5us1, tfR5G6B5us1, tfRGB5A1us1, tfA1RGB5us1, tfRGBA4us1, tfARGB4us1,
7966 tfBGRX4us1, tfXBGR4us1, tfBGR5X1us1, tfX1BGR5us1, tfB5G6R5us1, tfBGR5A1us1, tfA1BGR5us1, tfBGRA4us1, tfABGR4us1:
7968 Info.biBitCount := 16;
7969 Info.biCompression := BMP_COMP_BITFIELDS;
7972 tfBGR8ub3, tfRGB8ub3:
7974 Info.biBitCount := 24;
7975 if (Format = tfRGB8ub3) then
7976 Converter := TfdBGR8ub3.Create; //use BGR8 Format Descriptor to Swap RGB Values
7979 tfRGBX8ui1, tfXRGB8ui1, tfRGB10X2ui1, tfX2RGB10ui1, tfRGBA8ui1, tfARGB8ui1, tfRGBA8ub4, tfRGB10A2ui1, tfA2RGB10ui1,
7980 tfBGRX8ui1, tfXBGR8ui1, tfBGR10X2ui1, tfX2BGR10ui1, tfBGRA8ui1, tfABGR8ui1, tfBGRA8ub4, tfBGR10A2ui1, tfA2BGR10ui1:
7982 Info.biBitCount := 32;
7983 Info.biCompression := BMP_COMP_BITFIELDS;
7986 raise EglBitmapUnsupportedFormat.Create(Format);
7988 Info.biXPelsPerMeter := 2835;
7989 Info.biYPelsPerMeter := 2835;
7992 if Info.biCompression = BMP_COMP_BITFIELDS then begin
7993 Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
7994 Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
7996 RedMask := FormatDesc.Mask.r;
7997 GreenMask := FormatDesc.Mask.g;
7998 BlueMask := FormatDesc.Mask.b;
7999 AlphaMask := FormatDesc.Mask.a;
8003 aStream.Write(Header, SizeOf(Header));
8004 aStream.Write(Info, SizeOf(Info));
8007 if Assigned(Converter) and (Converter is TbmpColorTableFormat) then
8008 with (Converter as TbmpColorTableFormat) do
8009 aStream.Write(ColorTable[0].b,
8010 SizeOf(TbmpColorTableEnty) * Length(ColorTable));
8013 if Info.biCompression = BMP_COMP_BITFIELDS then begin
8014 aStream.Write(RedMask, SizeOf(Cardinal));
8015 aStream.Write(GreenMask, SizeOf(Cardinal));
8016 aStream.Write(BlueMask, SizeOf(Cardinal));
8017 aStream.Write(AlphaMask, SizeOf(Cardinal));
8021 rbLineSize := Round(Info.biWidth * FormatDesc.BytesPerPixel);
8022 wbLineSize := Round(Info.biWidth * Info.biBitCount / 8);
8023 Padding := GetLineWidth - wbLineSize;
8027 inc(pData, (Height-1) * rbLineSize);
8029 // prepare row buffer. But only for RGB because RGBA supports color masks
8030 // so it's possible to change color within the image.
8031 if Assigned(Converter) then begin
8032 FormatDesc.PreparePixel(Pixel);
8033 GetMem(ConvertBuffer, wbLineSize);
8034 SourceFD := FormatDesc.CreateMappingData;
8035 DestFD := Converter.CreateMappingData;
8037 ConvertBuffer := nil;
8040 for LineIdx := 0 to Height - 1 do begin
8042 if Assigned(Converter) then begin
8044 dstData := ConvertBuffer;
8045 for PixelIdx := 0 to Info.biWidth-1 do begin
8046 FormatDesc.Unmap(srcData, Pixel, SourceFD);
8047 glBitmapConvertPixel(Pixel, FormatDesc, Converter);
8048 Converter.Map(Pixel, dstData, DestFD);
8050 aStream.Write(ConvertBuffer^, wbLineSize);
8052 aStream.Write(pData^, rbLineSize);
8054 dec(pData, rbLineSize);
8055 if (Padding > 0) then
8056 aStream.Write(PaddingBuff, Padding);
8059 // destroy row buffer
8060 if Assigned(ConvertBuffer) then begin
8061 FormatDesc.FreeMappingData(SourceFD);
8062 Converter.FreeMappingData(DestFD);
8063 FreeMem(ConvertBuffer);
8067 if Assigned(Converter) then
8072 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8073 //TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8074 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8076 TTGAHeader = packed record
8080 //ColorMapSpec: Array[0..4] of Byte;
8081 ColorMapStart: Word;
8082 ColorMapLength: Word;
8083 ColorMapEntrySize: Byte;
8093 TGA_UNCOMPRESSED_RGB = 2;
8094 TGA_UNCOMPRESSED_GRAY = 3;
8095 TGA_COMPRESSED_RGB = 10;
8096 TGA_COMPRESSED_GRAY = 11;
8098 TGA_NONE_COLOR_TABLE = 0;
8100 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8101 function TglBitmap.LoadTGA(const aStream: TStream): Boolean;
8104 ImageData: System.PByte;
8105 StartPosition: Int64;
8106 PixelSize, LineSize: Integer;
8107 tgaFormat: TglBitmapFormat;
8108 FormatDesc: TFormatDescriptor;
8109 Counter: packed record
8111 low, high, dir: Integer;
8118 ////////////////////////////////////////////////////////////////////////////////////////
8119 procedure ReadUncompressed;
8122 buf, tmp1, tmp2: System.PByte;
8125 if (Counter.X.dir < 0) then
8126 GetMem(buf, LineSize);
8128 while (Counter.Y.low <> Counter.Y.high + counter.Y.dir) do begin
8130 inc(tmp1, (Counter.Y.low * LineSize)); //pointer to LineStart
8131 if (Counter.X.dir < 0) then begin //flip X
8132 aStream.Read(buf^, LineSize);
8134 inc(tmp2, LineSize - PixelSize); //pointer to last pixel in line
8135 for i := 0 to Header.Width-1 do begin //for all pixels in line
8136 for j := 0 to PixelSize-1 do begin //for all bytes in pixel
8141 dec(tmp2, 2*PixelSize); //move 2 backwards, because j-loop moved 1 forward
8144 aStream.Read(tmp1^, LineSize);
8145 inc(Counter.Y.low, Counter.Y.dir); //move to next line index
8148 if Assigned(buf) then
8153 ////////////////////////////////////////////////////////////////////////////////////////
8154 procedure ReadCompressed;
8156 /////////////////////////////////////////////////////////////////
8158 TmpData: System.PByte;
8159 LinePixelsRead: Integer;
8160 procedure CheckLine;
8162 if (LinePixelsRead >= Header.Width) then begin
8163 LinePixelsRead := 0;
8164 inc(Counter.Y.low, Counter.Y.dir); //next line index
8165 TmpData := ImageData;
8166 inc(TmpData, Counter.Y.low * LineSize); //set line
8167 if (Counter.X.dir < 0) then //if x flipped then
8168 inc(TmpData, LineSize - PixelSize); //set last pixel
8172 /////////////////////////////////////////////////////////////////
8175 CacheSize, CachePos: Integer;
8176 procedure CachedRead(out Buffer; Count: Integer);
8180 if (CachePos + Count > CacheSize) then begin
8181 //if buffer overflow save non read bytes
8183 if (CacheSize - CachePos > 0) then begin
8184 BytesRead := CacheSize - CachePos;
8185 Move(PByteArray(Cache)^[CachePos], Buffer{%H-}, BytesRead);
8186 inc(CachePos, BytesRead);
8189 //load cache from file
8190 CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
8191 aStream.Read(Cache^, CacheSize);
8194 //read rest of requested bytes
8195 if (Count - BytesRead > 0) then begin
8196 Move(PByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
8197 inc(CachePos, Count - BytesRead);
8200 //if no buffer overflow just read the data
8201 Move(PByteArray(Cache)^[CachePos], Buffer, Count);
8202 inc(CachePos, Count);
8206 procedure PixelToBuffer(const aData: PByte; var aBuffer: PByte);
8211 inc(aBuffer, Counter.X.dir);
8214 PWord(aBuffer)^ := PWord(aData)^;
8215 inc(aBuffer, 2 * Counter.X.dir);
8218 PByteArray(aBuffer)^[0] := PByteArray(aData)^[0];
8219 PByteArray(aBuffer)^[1] := PByteArray(aData)^[1];
8220 PByteArray(aBuffer)^[2] := PByteArray(aData)^[2];
8221 inc(aBuffer, 3 * Counter.X.dir);
8224 PCardinal(aBuffer)^ := PCardinal(aData)^;
8225 inc(aBuffer, 4 * Counter.X.dir);
8231 TotalPixelsToRead, TotalPixelsRead: Integer;
8233 buf: array [0..3] of Byte; //1 pixel is max 32bit long
8234 PixelRepeat: Boolean;
8235 PixelsToRead, PixelCount: Integer;
8240 TotalPixelsToRead := Header.Width * Header.Height;
8241 TotalPixelsRead := 0;
8242 LinePixelsRead := 0;
8244 GetMem(Cache, CACHE_SIZE);
8246 TmpData := ImageData;
8247 inc(TmpData, Counter.Y.low * LineSize); //set line
8248 if (Counter.X.dir < 0) then //if x flipped then
8249 inc(TmpData, LineSize - PixelSize); //set last pixel
8253 CachedRead(Temp, 1);
8254 PixelRepeat := (Temp and $80) > 0;
8255 PixelsToRead := (Temp and $7F) + 1;
8256 inc(TotalPixelsRead, PixelsToRead);
8259 CachedRead(buf[0], PixelSize);
8260 while (PixelsToRead > 0) do begin
8262 PixelCount := Min(Header.Width - LinePixelsRead, PixelsToRead); //max read to EOL or EOF
8263 while (PixelCount > 0) do begin
8264 if not PixelRepeat then
8265 CachedRead(buf[0], PixelSize);
8266 PixelToBuffer(@buf[0], TmpData);
8267 inc(LinePixelsRead);
8272 until (TotalPixelsRead >= TotalPixelsToRead);
8278 function IsGrayFormat: Boolean;
8280 result := Header.ImageType in [TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_GRAY];
8286 // reading header to test file and set cursor back to begin
8287 StartPosition := aStream.Position;
8288 aStream.Read(Header{%H-}, SizeOf(Header));
8290 // no colormapped files
8291 if (Header.ColorMapType = TGA_NONE_COLOR_TABLE) and (Header.ImageType in [
8292 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY]) then
8295 if Header.ImageID <> 0 then // skip image ID
8296 aStream.Position := aStream.Position + Header.ImageID;
8298 tgaFormat := tfEmpty;
8300 8: if IsGrayFormat then case (Header.ImageDesc and $F) of
8301 0: tgaFormat := tfLuminance8ub1;
8302 8: tgaFormat := tfAlpha8ub1;
8305 16: if IsGrayFormat then case (Header.ImageDesc and $F) of
8306 0: tgaFormat := tfLuminance16us1;
8307 8: tgaFormat := tfLuminance8Alpha8ub2;
8308 end else case (Header.ImageDesc and $F) of
8309 0: tgaFormat := tfX1RGB5us1;
8310 1: tgaFormat := tfA1RGB5us1;
8311 4: tgaFormat := tfARGB4us1;
8314 24: if not IsGrayFormat then case (Header.ImageDesc and $F) of
8315 0: tgaFormat := tfBGR8ub3;
8318 32: if IsGrayFormat then case (Header.ImageDesc and $F) of
8319 0: tgaFormat := tfDepth32ui1;
8320 end else case (Header.ImageDesc and $F) of
8321 0: tgaFormat := tfX2RGB10ui1;
8322 2: tgaFormat := tfA2RGB10ui1;
8323 8: tgaFormat := tfARGB8ui1;
8327 if (tgaFormat = tfEmpty) then
8328 raise EglBitmap.Create('LoadTga - unsupported format');
8330 FormatDesc := TFormatDescriptor.Get(tgaFormat);
8331 PixelSize := FormatDesc.GetSize(1, 1);
8332 LineSize := FormatDesc.GetSize(Header.Width, 1);
8334 GetMem(ImageData, LineSize * Header.Height);
8337 if ((Header.ImageDesc and (1 shl 4)) > 0) then begin
8338 Counter.X.low := Header.Height-1;;
8339 Counter.X.high := 0;
8340 Counter.X.dir := -1;
8343 Counter.X.high := Header.Height-1;
8348 if ((Header.ImageDesc and (1 shl 5)) > 0) then begin
8350 Counter.Y.high := Header.Height-1;
8353 Counter.Y.low := Header.Height-1;;
8354 Counter.Y.high := 0;
8355 Counter.Y.dir := -1;
8359 case Header.ImageType of
8360 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY:
8362 TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY:
8366 SetDataPointer(ImageData, tgaFormat, Header.Width, Header.Height); //be careful, Data could be freed by this method
8369 if Assigned(ImageData) then
8374 aStream.Position := StartPosition;
8377 else aStream.Position := StartPosition;
8380 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8381 procedure TglBitmap.SaveTGA(const aStream: TStream);
8385 FormatDesc: TFormatDescriptor;
8387 if not (ftTGA in FormatGetSupportedFiles(Format)) then
8388 raise EglBitmapUnsupportedFormat.Create(Format);
8391 FormatDesc := TFormatDescriptor.Get(Format);
8392 FillChar(Header{%H-}, SizeOf(Header), 0);
8393 Header.ImageDesc := CountSetBits(FormatDesc.Range.a) and $F;
8394 Header.Bpp := FormatDesc.BitsPerPixel;
8395 Header.Width := Width;
8396 Header.Height := Height;
8397 Header.ImageDesc := Header.ImageDesc or $20; //flip y
8398 if FormatDesc.IsGrayscale or (not FormatDesc.IsGrayscale and not FormatDesc.HasRed and FormatDesc.HasAlpha) then
8399 Header.ImageType := TGA_UNCOMPRESSED_GRAY
8401 Header.ImageType := TGA_UNCOMPRESSED_RGB;
8402 aStream.Write(Header, SizeOf(Header));
8405 Size := FormatDesc.GetSize(Dimension);
8406 aStream.Write(Data^, Size);
8409 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8410 //DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8411 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8413 DDS_MAGIC: Cardinal = $20534444;
8415 // DDS_header.dwFlags
8416 DDSD_CAPS = $00000001;
8417 DDSD_HEIGHT = $00000002;
8418 DDSD_WIDTH = $00000004;
8419 DDSD_PIXELFORMAT = $00001000;
8421 // DDS_header.sPixelFormat.dwFlags
8422 DDPF_ALPHAPIXELS = $00000001;
8423 DDPF_ALPHA = $00000002;
8424 DDPF_FOURCC = $00000004;
8425 DDPF_RGB = $00000040;
8426 DDPF_LUMINANCE = $00020000;
8428 // DDS_header.sCaps.dwCaps1
8429 DDSCAPS_TEXTURE = $00001000;
8431 // DDS_header.sCaps.dwCaps2
8432 DDSCAPS2_CUBEMAP = $00000200;
8434 D3DFMT_DXT1 = $31545844;
8435 D3DFMT_DXT3 = $33545844;
8436 D3DFMT_DXT5 = $35545844;
8439 TDDSPixelFormat = packed record
8443 dwRGBBitCount: Cardinal;
8444 dwRBitMask: Cardinal;
8445 dwGBitMask: Cardinal;
8446 dwBBitMask: Cardinal;
8447 dwABitMask: Cardinal;
8450 TDDSCaps = packed record
8454 dwReserved: Cardinal;
8457 TDDSHeader = packed record
8462 dwPitchOrLinearSize: Cardinal;
8464 dwMipMapCount: Cardinal;
8465 dwReserved: array[0..10] of Cardinal;
8466 PixelFormat: TDDSPixelFormat;
8468 dwReserved2: Cardinal;
8471 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8472 function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
8475 Converter: TbmpBitfieldFormat;
8477 function GetDDSFormat: TglBitmapFormat;
8479 fd: TFormatDescriptor;
8481 Mask: TglBitmapRec4ul;
8482 Range: TglBitmapRec4ui;
8486 with Header.PixelFormat do begin
8488 if ((dwFlags and DDPF_FOURCC) > 0) then begin
8489 case Header.PixelFormat.dwFourCC of
8490 D3DFMT_DXT1: result := tfS3tcDtx1RGBA;
8491 D3DFMT_DXT3: result := tfS3tcDtx3RGBA;
8492 D3DFMT_DXT5: result := tfS3tcDtx5RGBA;
8494 end else if ((dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE or DDPF_ALPHA)) > 0) then begin
8496 if ((dwFlags and DDPF_LUMINANCE) = 0) then begin
8497 Mask.r := dwRBitMask;
8498 Mask.g := dwGBitMask;
8499 Mask.b := dwBBitMask;
8501 Mask.r := dwRBitMask;
8502 Mask.g := dwRBitMask;
8503 Mask.b := dwRBitMask;
8505 if (dwFlags and DDPF_ALPHAPIXELS > 0) then
8506 Mask.a := dwABitMask
8510 //find matching format
8511 fd := TFormatDescriptor.GetFromMask(Mask, dwRGBBitCount);
8512 result := fd.Format;
8513 if (result <> tfEmpty) then
8516 //find format with same Range
8518 Range.arr[i] := (2 shl CountSetBits(Mask.arr[i])) - 1;
8519 for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
8520 fd := TFormatDescriptor.Get(result);
8523 if (fd.Range.arr[i] <> Range.arr[i]) then begin
8531 //no format with same range found -> use default
8532 if (result = tfEmpty) then begin
8533 if (dwABitMask > 0) then
8534 result := tfRGBA8ui1
8536 result := tfRGB8ub3;
8539 Converter := TbmpBitfieldFormat.Create;
8540 Converter.SetCustomValues(dwRGBBitCount, glBitmapRec4ul(dwRBitMask, dwGBitMask, dwBBitMask, dwABitMask));
8547 x, y, LineSize, RowSize, Magic: Cardinal;
8548 NewImage, TmpData, RowData, SrcData: System.PByte;
8549 SourceMD, DestMD: Pointer;
8550 Pixel: TglBitmapPixelData;
8551 ddsFormat: TglBitmapFormat;
8552 FormatDesc: TFormatDescriptor;
8557 StreamPos := aStream.Position;
8560 aStream.Read(Magic{%H-}, sizeof(Magic));
8561 if (Magic <> DDS_MAGIC) then begin
8562 aStream.Position := StreamPos;
8567 aStream.Read(Header{%H-}, sizeof(Header));
8568 if (Header.dwSize <> SizeOf(Header)) or
8569 ((Header.dwFlags and (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) <>
8570 (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) then
8572 aStream.Position := StreamPos;
8576 if ((Header.Caps.dwCaps1 and DDSCAPS2_CUBEMAP) > 0) then
8577 raise EglBitmap.Create('LoadDDS - CubeMaps are not supported');
8579 ddsFormat := GetDDSFormat;
8581 if (ddsFormat = tfEmpty) then
8582 raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
8584 FormatDesc := TFormatDescriptor.Get(ddsFormat);
8585 LineSize := Trunc(Header.dwWidth * FormatDesc.BytesPerPixel);
8586 GetMem(NewImage, Header.dwHeight * LineSize);
8588 TmpData := NewImage;
8591 if Assigned(Converter) then begin
8592 RowSize := Round(Header.dwWidth * Header.PixelFormat.dwRGBBitCount / 8);
8593 GetMem(RowData, RowSize);
8594 SourceMD := Converter.CreateMappingData;
8595 DestMD := FormatDesc.CreateMappingData;
8597 for y := 0 to Header.dwHeight-1 do begin
8598 TmpData := NewImage;
8599 inc(TmpData, y * LineSize);
8601 aStream.Read(SrcData^, RowSize);
8602 for x := 0 to Header.dwWidth-1 do begin
8603 Converter.Unmap(SrcData, Pixel, SourceMD);
8604 glBitmapConvertPixel(Pixel, Converter, FormatDesc);
8605 FormatDesc.Map(Pixel, TmpData, DestMD);
8609 Converter.FreeMappingData(SourceMD);
8610 FormatDesc.FreeMappingData(DestMD);
8616 if ((Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0) then begin
8617 RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
8618 for Y := 0 to Header.dwHeight-1 do begin
8619 aStream.Read(TmpData^, RowSize);
8620 Inc(TmpData, LineSize);
8625 if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0 then begin
8626 RowSize := (Header.PixelFormat.dwRGBBitCount * Header.dwWidth) shr 3;
8627 for Y := 0 to Header.dwHeight-1 do begin
8628 aStream.Read(TmpData^, RowSize);
8629 Inc(TmpData, LineSize);
8632 raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
8634 SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight); //be careful, Data could be freed by this method
8637 if Assigned(NewImage) then
8642 FreeAndNil(Converter);
8646 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8647 procedure TglBitmap.SaveDDS(const aStream: TStream);
8650 FormatDesc: TFormatDescriptor;
8652 if not (ftDDS in FormatGetSupportedFiles(Format)) then
8653 raise EglBitmapUnsupportedFormat.Create(Format);
8655 FormatDesc := TFormatDescriptor.Get(Format);
8658 FillChar(Header{%H-}, SizeOf(Header), 0);
8659 Header.dwSize := SizeOf(Header);
8660 Header.dwFlags := DDSD_WIDTH or DDSD_HEIGHT or DDSD_CAPS or DDSD_PIXELFORMAT;
8662 Header.dwWidth := Max(1, Width);
8663 Header.dwHeight := Max(1, Height);
8666 Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
8669 Header.PixelFormat.dwSize := sizeof(Header);
8670 if (FormatDesc.IsCompressed) then begin
8671 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_FOURCC;
8673 tfS3tcDtx1RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT1;
8674 tfS3tcDtx3RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT3;
8675 tfS3tcDtx5RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT5;
8677 end else if not FormatDesc.HasColor and FormatDesc.HasAlpha then begin
8678 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHA;
8679 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
8680 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
8681 end else if FormatDesc.IsGrayscale then begin
8682 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_LUMINANCE;
8683 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
8684 Header.PixelFormat.dwRBitMask := FormatDesc.Mask.r;
8685 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
8687 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_RGB;
8688 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
8689 Header.PixelFormat.dwRBitMask := FormatDesc.Mask.r;
8690 Header.PixelFormat.dwGBitMask := FormatDesc.Mask.g;
8691 Header.PixelFormat.dwBBitMask := FormatDesc.Mask.b;
8692 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
8695 if (FormatDesc.HasAlpha) then
8696 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
8698 aStream.Write(DDS_MAGIC, sizeof(DDS_MAGIC));
8699 aStream.Write(Header, SizeOf(Header));
8700 aStream.Write(Data^, FormatDesc.GetSize(Dimension));
8704 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8705 //TglBitmap1D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8706 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8707 procedure TglBitmap1D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
8708 const aWidth: Integer; const aHeight: Integer);
8713 if (aHeight > 1) then begin
8714 Size := TFormatDescriptor.Get(aFormat).GetSize(aWidth, 1);
8715 GetMem(pTemp, Size);
8717 Move(aData^, pTemp^, Size);
8726 inherited SetDataPointer(pTemp, aFormat, aWidth);
8729 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8730 function TglBitmap1D.FlipHorz: Boolean;
8733 pTempDest, pDest, pSource: PByte;
8735 result := inherited FlipHorz;
8736 if Assigned(Data) and not TFormatDescriptor.Get(Format).IsCompressed then begin
8738 GetMem(pDest, fRowSize);
8741 Inc(pTempDest, fRowSize);
8742 for Col := 0 to Width-1 do begin
8743 dec(pTempDest, fPixelSize); //dec before, because ptr is behind last byte of data
8744 Move(pSource^, pTempDest^, fPixelSize);
8745 Inc(pSource, fPixelSize);
8747 SetDataPointer(pDest, Format, Width); //be careful, Data could be freed by this method
8750 if Assigned(pDest) then
8757 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8758 procedure TglBitmap1D.UploadData(const aBuildWithGlu: Boolean);
8760 FormatDesc: TFormatDescriptor;
8763 FormatDesc := TFormatDescriptor.Get(Format);
8764 if (FormatDesc.glInternalFormat = 0) or (FormatDesc.glDataFormat = 0) then
8765 raise EglBitmap.Create('format is not supported by video adapter, please convert before uploading data');
8767 if FormatDesc.IsCompressed then begin
8768 if not Assigned(glCompressedTexImage1D) then
8769 raise EglBitmap.Create('compressed formats not supported by video adapter');
8770 glCompressedTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.GetSize(Width, 1), Data)
8771 end else if aBuildWithGlu then
8772 gluBuild1DMipmaps(Target, FormatDesc.glInternalFormat, Width, FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
8774 glTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
8777 if (FreeDataAfterGenTexture) then
8781 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8782 procedure TglBitmap1D.GenTexture(const aTestTextureSize: Boolean);
8784 BuildWithGlu, TexRec: Boolean;
8787 if Assigned(Data) then begin
8788 // Check Texture Size
8789 if (aTestTextureSize) then begin
8790 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
8792 if (Width > TexSize) then
8793 raise EglBitmapSizeToLarge.Create('TglBitmap1D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
8795 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
8796 (Target = GL_TEXTURE_RECTANGLE);
8797 if not (IsPowerOfTwo(Width) or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
8798 raise EglBitmapNonPowerOfTwo.Create('TglBitmap1D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8802 SetupParameters(BuildWithGlu);
8803 UploadData(BuildWithGlu);
8804 glAreTexturesResident(1, @fID, @fIsResident);
8808 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8809 procedure TglBitmap1D.AfterConstruction;
8812 Target := GL_TEXTURE_1D;
8816 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8817 //TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8818 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8819 function TglBitmap2D.GetScanline(const aIndex: Integer): Pointer;
8821 if (aIndex >= Low(fLines)) and (aIndex <= High(fLines)) then
8822 result := fLines[aIndex]
8827 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8828 procedure TglBitmap2D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
8829 const aWidth: Integer; const aHeight: Integer);
8831 Idx, LineWidth: Integer;
8833 inherited SetDataPointer(aData, aFormat, aWidth, aHeight);
8835 if not TFormatDescriptor.Get(aFormat).IsCompressed then begin
8837 if Assigned(Data) then begin
8838 SetLength(fLines, GetHeight);
8839 LineWidth := Trunc(GetWidth * TFormatDescriptor.Get(Format).BytesPerPixel);
8841 for Idx := 0 to GetHeight-1 do begin
8842 fLines[Idx] := Data;
8843 Inc(fLines[Idx], Idx * LineWidth);
8846 else SetLength(fLines, 0);
8848 SetLength(fLines, 0);
8852 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8853 procedure TglBitmap2D.UploadData(const aTarget: GLenum{$IFNDEF OPENGL_ES}; const aBuildWithGlu: Boolean{$ENDIF});
8855 FormatDesc: TFormatDescriptor;
8857 FormatDesc := TFormatDescriptor.Get(Format);
8858 if (FormatDesc.glInternalFormat = 0) or (FormatDesc.glDataFormat = 0) then
8859 raise EglBitmap.Create('format is not supported by video adapter, please convert before uploading data');
8861 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
8863 if FormatDesc.IsCompressed then begin
8864 if not Assigned(glCompressedTexImage2D) then
8865 raise EglBitmap.Create('compressed formats not supported by video adapter');
8866 glCompressedTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0, FormatDesc.GetSize(fDimension), Data)
8868 end else if aBuildWithGlu then begin
8869 gluBuild2DMipmaps(aTarget, FormatDesc.ChannelCount, Width, Height,
8870 FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
8873 glTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0,
8874 FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
8878 if (FreeDataAfterGenTexture) then
8882 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8883 procedure TglBitmap2D.AfterConstruction;
8886 Target := GL_TEXTURE_2D;
8889 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8890 procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
8893 Size, w, h: Integer;
8894 FormatDesc: TFormatDescriptor;
8896 FormatDesc := TFormatDescriptor.Get(aFormat);
8897 if FormatDesc.IsCompressed then
8898 raise EglBitmapUnsupportedFormat.Create(aFormat);
8900 w := aRight - aLeft;
8901 h := aBottom - aTop;
8902 Size := FormatDesc.GetSize(w, h);
8905 glPixelStorei(GL_PACK_ALIGNMENT, 1);
8906 glReadPixels(aLeft, aTop, w, h, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
8907 SetDataPointer(Temp, aFormat, w, h); //be careful, Data could be freed by this method
8910 if Assigned(Temp) then
8917 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8918 procedure TglBitmap2D.GetDataFromTexture;
8921 TempWidth, TempHeight: Integer;
8922 TempIntFormat: GLint;
8923 IntFormat: TglBitmapFormat;
8924 FormatDesc: TFormatDescriptor;
8929 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
8930 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
8931 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
8933 FormatDesc := (TglBitmapFormatDescriptor.GetByFormat(TempIntFormat) as TFormatDescriptor);
8934 IntFormat := FormatDesc.Format;
8936 // Getting data from OpenGL
8937 FormatDesc := TFormatDescriptor.Get(IntFormat);
8938 GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
8940 if FormatDesc.IsCompressed then begin
8941 if not Assigned(glGetCompressedTexImage) then
8942 raise EglBitmap.Create('compressed formats not supported by video adapter');
8943 glGetCompressedTexImage(Target, 0, Temp)
8945 glGetTexImage(Target, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
8946 SetDataPointer(Temp, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
8948 if Assigned(Temp) then
8955 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8956 procedure TglBitmap2D.GenTexture(const aTestTextureSize: Boolean);
8959 BuildWithGlu, TexRec: Boolean;
8964 if Assigned(Data) then begin
8965 // Check Texture Size
8966 if (aTestTextureSize) then begin
8967 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
8969 if ((Height > TexSize) or (Width > TexSize)) then
8970 raise EglBitmapSizeToLarge.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
8972 PotTex := IsPowerOfTwo(Height) and IsPowerOfTwo(Width);
8973 {$IF NOT DEFINED(OPENGL_ES)}
8974 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE);
8975 if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
8976 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8977 {$ELSEIF DEFINED(OPENGL_ES_EXT)}
8978 if not PotTex and not GL_OES_texture_npot then
8979 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8982 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8987 SetupParameters({$IFNDEF OPENGL_ES}BuildWithGlu{$ENDIF});
8988 UploadData(Target{$IFNDEF OPENGL_ES}, BuildWithGlu{$ENDIF});
8990 glAreTexturesResident(1, @fID, @fIsResident);
8995 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8996 function TglBitmap2D.FlipHorz: Boolean;
8999 TempDestData, DestData, SourceData: PByte;
9002 result := inherited FlipHorz;
9003 if Assigned(Data) then begin
9005 ImgSize := Height * fRowSize;
9006 GetMem(DestData, ImgSize);
9008 TempDestData := DestData;
9009 Dec(TempDestData, fRowSize + fPixelSize);
9010 for Row := 0 to Height -1 do begin
9011 Inc(TempDestData, fRowSize * 2);
9012 for Col := 0 to Width -1 do begin
9013 Move(SourceData^, TempDestData^, fPixelSize);
9014 Inc(SourceData, fPixelSize);
9015 Dec(TempDestData, fPixelSize);
9018 SetDataPointer(DestData, Format, Width, Height); //be careful, Data could be freed by this method
9021 if Assigned(DestData) then
9028 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9029 function TglBitmap2D.FlipVert: Boolean;
9032 TempDestData, DestData, SourceData: PByte;
9034 result := inherited FlipVert;
9035 if Assigned(Data) then begin
9037 GetMem(DestData, Height * fRowSize);
9039 TempDestData := DestData;
9040 Inc(TempDestData, Width * (Height -1) * fPixelSize);
9041 for Row := 0 to Height -1 do begin
9042 Move(SourceData^, TempDestData^, fRowSize);
9043 Dec(TempDestData, fRowSize);
9044 Inc(SourceData, fRowSize);
9046 SetDataPointer(DestData, Format, Width, Height); //be careful, Data could be freed by this method
9049 if Assigned(DestData) then
9056 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9057 //TglBitmap2D - ToNormalMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9058 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9060 TMatrixItem = record
9065 PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
9066 TglBitmapToNormalMapRec = Record
9068 Heights: array of Single;
9069 MatrixU : array of TMatrixItem;
9070 MatrixV : array of TMatrixItem;
9074 ONE_OVER_255 = 1 / 255;
9076 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9077 procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
9081 with FuncRec do begin
9083 Source.Data.r * LUMINANCE_WEIGHT_R +
9084 Source.Data.g * LUMINANCE_WEIGHT_G +
9085 Source.Data.b * LUMINANCE_WEIGHT_B;
9086 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255;
9090 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9091 procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
9094 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
9097 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9098 procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
9100 TVec = Array[0..2] of Single;
9107 function GetHeight(X, Y: Integer): Single;
9109 with FuncRec do begin
9110 X := Max(0, Min(Size.X -1, X));
9111 Y := Max(0, Min(Size.Y -1, Y));
9112 result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
9117 with FuncRec do begin
9118 with PglBitmapToNormalMapRec(Args)^ do begin
9120 for Idx := Low(MatrixU) to High(MatrixU) do
9121 du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
9124 for Idx := Low(MatrixU) to High(MatrixU) do
9125 dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
9127 Vec[0] := -du * Scale;
9128 Vec[1] := -dv * Scale;
9133 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
9134 if Len <> 0 then begin
9135 Vec[0] := Vec[0] * Len;
9136 Vec[1] := Vec[1] * Len;
9137 Vec[2] := Vec[2] * Len;
9141 Dest.Data.r := Trunc((Vec[0] + 1) * 127.5);
9142 Dest.Data.g := Trunc((Vec[1] + 1) * 127.5);
9143 Dest.Data.b := Trunc((Vec[2] + 1) * 127.5);
9147 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9148 procedure TglBitmap2D.GenerateNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
9150 Rec: TglBitmapToNormalMapRec;
9152 procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
9154 if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
9155 Matrix[Index].X := X;
9156 Matrix[Index].Y := Y;
9157 Matrix[Index].W := W;
9162 if TFormatDescriptor.Get(Format).IsCompressed then
9163 raise EglBitmapUnsupportedFormat.Create(Format);
9165 if aScale > 100 then
9167 else if aScale < -100 then
9170 Rec.Scale := aScale;
9172 SetLength(Rec.Heights, Width * Height);
9176 SetLength(Rec.MatrixU, 2);
9177 SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
9178 SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
9180 SetLength(Rec.MatrixV, 2);
9181 SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
9182 SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
9186 SetLength(Rec.MatrixU, 6);
9187 SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
9188 SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
9189 SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
9190 SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
9191 SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
9192 SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
9194 SetLength(Rec.MatrixV, 6);
9195 SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
9196 SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
9197 SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
9198 SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
9199 SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
9200 SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
9204 SetLength(Rec.MatrixU, 6);
9205 SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
9206 SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
9207 SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
9208 SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
9209 SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
9210 SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
9212 SetLength(Rec.MatrixV, 6);
9213 SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
9214 SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
9215 SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
9216 SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
9217 SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
9218 SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
9222 SetLength(Rec.MatrixU, 20);
9223 SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
9224 SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
9225 SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
9226 SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
9227 SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
9228 SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
9229 SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
9230 SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
9231 SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
9232 SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
9233 SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
9234 SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
9235 SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
9236 SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
9237 SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
9238 SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
9239 SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
9240 SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
9241 SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
9242 SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
9244 SetLength(Rec.MatrixV, 20);
9245 SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
9246 SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
9247 SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
9248 SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
9249 SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
9250 SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
9251 SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
9252 SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
9253 SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
9254 SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
9255 SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
9256 SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
9257 SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
9258 SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
9259 SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
9260 SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
9261 SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
9262 SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
9263 SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
9264 SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
9269 if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
9270 Convert(glBitmapToNormalMapPrepareAlphaFunc, false, @Rec)
9272 Convert(glBitmapToNormalMapPrepareFunc, false, @Rec);
9273 Convert(glBitmapToNormalMapFunc, false, @Rec);
9275 SetLength(Rec.Heights, 0);
9279 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
9280 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9281 //TglBitmapCubeMap////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9282 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9283 procedure TglBitmapCubeMap.GenTexture(const aTestTextureSize: Boolean);
9285 Assert(false, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
9288 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9289 procedure TglBitmapCubeMap.AfterConstruction;
9294 if not (GL_VERSION_1_3 or GL_ARB_texture_cube_map or GL_EXT_texture_cube_map) then
9295 raise EglBitmap.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
9297 if not (GL_VERSION_2_0) then
9298 raise EglBitmap.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
9302 Target := GL_TEXTURE_CUBE_MAP;
9304 fGenMode := GL_REFLECTION_MAP;
9308 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9309 procedure TglBitmapCubeMap.GenerateCubeMap(const aCubeTarget: Cardinal; const aTestTextureSize: Boolean);
9312 BuildWithGlu: Boolean;
9316 if (aTestTextureSize) then begin
9317 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @TexSize);
9319 if (Height > TexSize) or (Width > TexSize) then
9320 raise EglBitmapSizeToLarge.Create('TglBitmapCubeMap.GenerateCubeMap - The size for the Cubemap is to large. It''s may be not conform with the Hardware.');
9322 {$IF NOT DEFINED(OPENGL_ES)}
9323 if not ((IsPowerOfTwo(Height) and IsPowerOfTwo(Width)) or GL_VERSION_2_0 or GL_ARB_texture_non_power_of_two) then
9324 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenerateCubeMap - Cubemaps dosn''t support non power of two texture.');
9325 {$ELSEIF DEFINED(OPENGL_ES_EXT)}
9326 if not (IsPowerOfTwo(Height) and IsPowerOfTwo(Width)) and not GL_OES_texture_npot then
9327 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenerateCubeMap - Cubemaps dosn''t support non power of two texture.');
9329 if not (IsPowerOfTwo(Height) and IsPowerOfTwo(Width)) then
9330 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenerateCubeMap - Cubemaps dosn''t support non power of two texture.');
9336 SetupParameters({$IFNDEF OPENGL_ES}BuildWithGlu{$ENDIF});
9337 UploadData(aCubeTarget{$IFNDEF OPENGL_ES}, BuildWithGlu{$ENDIF});
9340 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9341 procedure TglBitmapCubeMap.Bind({$IFNDEF OPENGL_ES}const aEnableTexCoordsGen: Boolean;{$ENDIF} const aEnableTextureUnit: Boolean);
9343 inherited Bind (aEnableTextureUnit);
9345 if aEnableTexCoordsGen then begin
9346 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, fGenMode);
9347 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, fGenMode);
9348 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, fGenMode);
9349 glEnable(GL_TEXTURE_GEN_S);
9350 glEnable(GL_TEXTURE_GEN_T);
9351 glEnable(GL_TEXTURE_GEN_R);
9356 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9357 procedure TglBitmapCubeMap.Unbind({$IFNDEF OPENGL_ES}const aDisableTexCoordsGen: Boolean;{$ENDIF} const aDisableTextureUnit: Boolean);
9359 inherited Unbind(aDisableTextureUnit);
9361 if aDisableTexCoordsGen then begin
9362 glDisable(GL_TEXTURE_GEN_S);
9363 glDisable(GL_TEXTURE_GEN_T);
9364 glDisable(GL_TEXTURE_GEN_R);
9370 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
9371 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9372 //TglBitmapNormalMap//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9373 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9375 TVec = Array[0..2] of Single;
9376 TglBitmapNormalMapGetVectorFunc = procedure (out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9378 PglBitmapNormalMapRec = ^TglBitmapNormalMapRec;
9379 TglBitmapNormalMapRec = record
9381 Func: TglBitmapNormalMapGetVectorFunc;
9384 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9385 procedure glBitmapNormalMapPosX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9387 aVec[0] := aHalfSize;
9388 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
9389 aVec[2] := - (aPosition.X + 0.5 - aHalfSize);
9392 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9393 procedure glBitmapNormalMapNegX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9395 aVec[0] := - aHalfSize;
9396 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
9397 aVec[2] := aPosition.X + 0.5 - aHalfSize;
9400 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9401 procedure glBitmapNormalMapPosY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9403 aVec[0] := aPosition.X + 0.5 - aHalfSize;
9404 aVec[1] := aHalfSize;
9405 aVec[2] := aPosition.Y + 0.5 - aHalfSize;
9408 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9409 procedure glBitmapNormalMapNegY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9411 aVec[0] := aPosition.X + 0.5 - aHalfSize;
9412 aVec[1] := - aHalfSize;
9413 aVec[2] := - (aPosition.Y + 0.5 - aHalfSize);
9416 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9417 procedure glBitmapNormalMapPosZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9419 aVec[0] := aPosition.X + 0.5 - aHalfSize;
9420 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
9421 aVec[2] := aHalfSize;
9424 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9425 procedure glBitmapNormalMapNegZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9427 aVec[0] := - (aPosition.X + 0.5 - aHalfSize);
9428 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
9429 aVec[2] := - aHalfSize;
9432 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9433 procedure glBitmapNormalMapFunc(var FuncRec: TglBitmapFunctionRec);
9439 with FuncRec do begin
9440 with PglBitmapNormalMapRec(Args)^ do begin
9441 Func(Vec, Position, HalfSize);
9444 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
9445 if Len <> 0 then begin
9446 Vec[0] := Vec[0] * Len;
9447 Vec[1] := Vec[1] * Len;
9448 Vec[2] := Vec[2] * Len;
9451 // Scale Vector and AddVectro
9452 Vec[0] := Vec[0] * 0.5 + 0.5;
9453 Vec[1] := Vec[1] * 0.5 + 0.5;
9454 Vec[2] := Vec[2] * 0.5 + 0.5;
9459 Dest.Data.arr[i] := Round(Vec[i] * 255);
9463 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9464 procedure TglBitmapNormalMap.AfterConstruction;
9468 fGenMode := GL_NORMAL_MAP;
9472 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9473 procedure TglBitmapNormalMap.GenerateNormalMap(const aSize: Integer; const aTestTextureSize: Boolean);
9475 Rec: TglBitmapNormalMapRec;
9476 SizeRec: TglBitmapSize;
9478 Rec.HalfSize := aSize div 2;
9479 FreeDataAfterGenTexture := false;
9481 SizeRec.Fields := [ffX, ffY];
9486 Rec.Func := glBitmapNormalMapPosX;
9487 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
9488 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X, aTestTextureSize);
9491 Rec.Func := glBitmapNormalMapNegX;
9492 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
9493 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, aTestTextureSize);
9496 Rec.Func := glBitmapNormalMapPosY;
9497 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
9498 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, aTestTextureSize);
9501 Rec.Func := glBitmapNormalMapNegY;
9502 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
9503 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, aTestTextureSize);
9506 Rec.Func := glBitmapNormalMapPosZ;
9507 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
9508 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, aTestTextureSize);
9511 Rec.Func := glBitmapNormalMapNegZ;
9512 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
9513 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, aTestTextureSize);
9518 glBitmapSetDefaultFormat (tfEmpty);
9519 glBitmapSetDefaultMipmap (mmMipmap);
9520 glBitmapSetDefaultFilter (GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
9521 glBitmapSetDefaultWrap (GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
9522 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
9523 glBitmapSetDefaultSwizzle(GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA);
9526 glBitmapSetDefaultFreeDataAfterGenTexture(true);
9527 glBitmapSetDefaultDeleteTextureOnFree (true);
9529 TFormatDescriptor.Init;
9531 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
9532 OpenGLInitialized := false;
9533 InitOpenGLCS := TCriticalSection.Create;
9537 TFormatDescriptor.Finalize;
9539 {$IFDEF GLB_NATIVE_OGL}
9540 if Assigned(GL_LibHandle) then
9541 glbFreeLibrary(GL_LibHandle);
9543 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
9544 if Assigned(GLU_LibHandle) then
9545 glbFreeLibrary(GLU_LibHandle);
9546 FreeAndNil(InitOpenGLCS);