You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

9551 lines
346 KiB

  1. { glBitmap by Steffen Xonna aka Lossy eX (2003-2008)
  2. http://www.opengl24.de/index.php?cat=header&file=glbitmap
  3. modified by Delphi OpenGL Community (http://delphigl.com/) (2013)
  4. The contents of this file are used with permission, subject to
  5. the Mozilla Public License Version 1.1 (the "License"); you may
  6. not use this file except in compliance with the License. You may
  7. obtain a copy of the License at
  8. http://www.mozilla.org/MPL/MPL-1.1.html
  9. The glBitmap is a Delphi/FPC unit that contains several wrapper classes
  10. to manage OpenGL texture objects. Below you can find a list of the main
  11. functionality of this classes:
  12. - load texture data from file (e.g. BMP, TGA, DDS, PNG, JPEG, ...)
  13. - load texture data from several other image objects (e.g. TBitmap, TLazIntfImage, SDL Surface)
  14. - save texture data to file (e.g. BMP, TGA, DDS, PNG, JPEG, ...)
  15. - save texture data to several other image objects (e.g. TBitmap, TLazIntfImage, SDL Surface)
  16. - support for many texture formats (e.g. RGB8, BGR8, RGBA8, BGRA8, ...)
  17. - manage texture properties (e.g. Filter, Clamp, Mipmap, ...)
  18. - upload texture data to video card
  19. - download texture data from video card
  20. - manipulate texture data (e.g. add alpha, remove alpha, convert to other format, switch RGB, ...) }
  21. unit glBitmap;
  22. // Please uncomment the defines below to configure the glBitmap to your preferences.
  23. // If you have configured the unit you can uncomment the warning above.
  24. {$MESSAGE error 'Hey. I''m the glBitmap.pas and i need to be configured. My master tell me your preferences! ;)'}
  25. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  26. // Preferences ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  27. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  28. // enable support for OpenGL ES 1.1
  29. {.$DEFINE OPENGL_ES_1_1}
  30. // enable support for OpenGL ES 2.0
  31. {.$DEFINE OPENGL_ES_2_0}
  32. // enable support for OpenGL ES 3.0
  33. {.$DEFINE OPENGL_ES_3_0}
  34. // enable support for all OpenGL ES extensions
  35. {.$DEFINE OPENGL_ES_EXT}
  36. // activate to enable build-in OpenGL support with statically linked methods
  37. // use dglOpenGL.pas if not enabled
  38. {.$DEFINE GLB_NATIVE_OGL_STATIC}
  39. // activate to enable build-in OpenGL support with dynamically linked methods
  40. // use dglOpenGL.pas if not enabled
  41. {.$DEFINE GLB_NATIVE_OGL_DYNAMIC}
  42. // activate to enable the support for SDL_surfaces
  43. {.$DEFINE GLB_SDL}
  44. // activate to enable the support for Delphi (including support for Delphi's (not Lazarus') TBitmap)
  45. {.$DEFINE GLB_DELPHI}
  46. // activate to enable the support for TLazIntfImage from Lazarus
  47. {.$DEFINE GLB_LAZARUS}
  48. // activate to enable the support of SDL_image to load files. (READ ONLY)
  49. // If you enable SDL_image all other libraries will be ignored!
  50. {.$DEFINE GLB_SDL_IMAGE}
  51. // activate to enable Lazarus TPortableNetworkGraphic support
  52. // if you enable this pngImage and libPNG will be ignored
  53. {.$DEFINE GLB_LAZ_PNG}
  54. // activate to enable png support with the unit pngimage -> http://pngdelphi.sourceforge.net/
  55. // if you enable pngimage the libPNG will be ignored
  56. {.$DEFINE GLB_PNGIMAGE}
  57. // activate to use the libPNG -> http://www.libpng.org/
  58. // You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libpng
  59. {.$DEFINE GLB_LIB_PNG}
  60. // activate to enable Lazarus TJPEGImage support
  61. // if you enable this delphi jpegs and libJPEG will be ignored
  62. {.$DEFINE GLB_LAZ_JPEG}
  63. // if you enable delphi jpegs the libJPEG will be ignored
  64. {.$DEFINE GLB_DELPHI_JPEG}
  65. // activate to use the libJPEG -> http://www.ijg.org/
  66. // You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libjpeg
  67. {.$DEFINE GLB_LIB_JPEG}
  68. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  69. // PRIVATE: do not change anything! //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  70. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  71. // Delphi Versions
  72. {$IFDEF fpc}
  73. {$MODE Delphi}
  74. {$IFDEF CPUI386}
  75. {$DEFINE CPU386}
  76. {$ASMMODE INTEL}
  77. {$ENDIF}
  78. {$IFNDEF WINDOWS}
  79. {$linklib c}
  80. {$ENDIF}
  81. {$ENDIF}
  82. // Operation System
  83. {$IF DEFINED(WIN32) or DEFINED(WIN64) or DEFINED(WINDOWS)}
  84. {$DEFINE GLB_WIN}
  85. {$ELSEIF DEFINED(LINUX)}
  86. {$DEFINE GLB_LINUX}
  87. {$IFEND}
  88. // OpenGL ES
  89. {$IF DEFINED(OPENGL_ES_EXT)} {$DEFINE OPENGL_ES_1_1} {$IFEND}
  90. {$IF DEFINED(OPENGL_ES_3_0)} {$DEFINE OPENGL_ES_2_0} {$IFEND}
  91. {$IF DEFINED(OPENGL_ES_2_0)} {$DEFINE OPENGL_ES_1_1} {$IFEND}
  92. {$IF DEFINED(OPENGL_ES_1_1)} {$DEFINE OPENGL_ES} {$IFEND}
  93. // native OpenGL Support
  94. {$IF DEFINED(GLB_NATIVE_OGL_STATIC) OR DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
  95. {$IFDEF OPENGL_ES}
  96. {$ERROR 'native OpenGL is not supported yet for OpenGL ES, please use dglOpenGLES.pas instead'}
  97. {$ELSE}
  98. {$DEFINE GLB_NATIVE_OGL}
  99. {$ENDIF}
  100. {$IFEND}
  101. // checking define combinations
  102. //SDL Image
  103. {$IFDEF GLB_SDL_IMAGE}
  104. {$IFNDEF GLB_SDL}
  105. {$MESSAGE warn 'SDL_image won''t work without SDL. SDL will be activated.'}
  106. {$DEFINE GLB_SDL}
  107. {$ENDIF}
  108. {$IFDEF GLB_LAZ_PNG}
  109. {$MESSAGE warn 'The Lazarus TPortableNetworkGraphics will be ignored because you are using SDL_image.'}
  110. {$undef GLB_LAZ_PNG}
  111. {$ENDIF}
  112. {$IFDEF GLB_PNGIMAGE}
  113. {$MESSAGE warn 'The unit pngimage will be ignored because you are using SDL_image.'}
  114. {$undef GLB_PNGIMAGE}
  115. {$ENDIF}
  116. {$IFDEF GLB_LAZ_JPEG}
  117. {$MESSAGE warn 'The Lazarus TJPEGImage will be ignored because you are using SDL_image.'}
  118. {$undef GLB_LAZ_JPEG}
  119. {$ENDIF}
  120. {$IFDEF GLB_DELPHI_JPEG}
  121. {$MESSAGE warn 'The unit JPEG will be ignored because you are using SDL_image.'}
  122. {$undef GLB_DELPHI_JPEG}
  123. {$ENDIF}
  124. {$IFDEF GLB_LIB_PNG}
  125. {$MESSAGE warn 'The library libPNG will be ignored because you are using SDL_image.'}
  126. {$undef GLB_LIB_PNG}
  127. {$ENDIF}
  128. {$IFDEF GLB_LIB_JPEG}
  129. {$MESSAGE warn 'The library libJPEG will be ignored because you are using SDL_image.'}
  130. {$undef GLB_LIB_JPEG}
  131. {$ENDIF}
  132. {$DEFINE GLB_SUPPORT_PNG_READ}
  133. {$DEFINE GLB_SUPPORT_JPEG_READ}
  134. {$ENDIF}
  135. // Lazarus TPortableNetworkGraphic
  136. {$IFDEF GLB_LAZ_PNG}
  137. {$IFNDEF GLB_LAZARUS}
  138. {$MESSAGE warn 'Lazarus TPortableNetworkGraphic won''t work without Lazarus. Lazarus will be activated.'}
  139. {$DEFINE GLB_LAZARUS}
  140. {$ENDIF}
  141. {$IFDEF GLB_PNGIMAGE}
  142. {$MESSAGE warn 'The pngimage will be ignored if you are using Lazarus TPortableNetworkGraphic.'}
  143. {$undef GLB_PNGIMAGE}
  144. {$ENDIF}
  145. {$IFDEF GLB_LIB_PNG}
  146. {$MESSAGE warn 'The library libPNG will be ignored if you are using Lazarus TPortableNetworkGraphic.'}
  147. {$undef GLB_LIB_PNG}
  148. {$ENDIF}
  149. {$DEFINE GLB_SUPPORT_PNG_READ}
  150. {$DEFINE GLB_SUPPORT_PNG_WRITE}
  151. {$ENDIF}
  152. // PNG Image
  153. {$IFDEF GLB_PNGIMAGE}
  154. {$IFDEF GLB_LIB_PNG}
  155. {$MESSAGE warn 'The library libPNG will be ignored if you are using pngimage.'}
  156. {$undef GLB_LIB_PNG}
  157. {$ENDIF}
  158. {$DEFINE GLB_SUPPORT_PNG_READ}
  159. {$DEFINE GLB_SUPPORT_PNG_WRITE}
  160. {$ENDIF}
  161. // libPNG
  162. {$IFDEF GLB_LIB_PNG}
  163. {$DEFINE GLB_SUPPORT_PNG_READ}
  164. {$DEFINE GLB_SUPPORT_PNG_WRITE}
  165. {$ENDIF}
  166. // Lazarus TJPEGImage
  167. {$IFDEF GLB_LAZ_JPEG}
  168. {$IFNDEF GLB_LAZARUS}
  169. {$MESSAGE warn 'Lazarus TJPEGImage won''t work without Lazarus. Lazarus will be activated.'}
  170. {$DEFINE GLB_LAZARUS}
  171. {$ENDIF}
  172. {$IFDEF GLB_DELPHI_JPEG}
  173. {$MESSAGE warn 'The Delphi JPEGImage will be ignored if you are using the Lazarus TJPEGImage.'}
  174. {$undef GLB_DELPHI_JPEG}
  175. {$ENDIF}
  176. {$IFDEF GLB_LIB_JPEG}
  177. {$MESSAGE warn 'The library libJPEG will be ignored if you are using the Lazarus TJPEGImage.'}
  178. {$undef GLB_LIB_JPEG}
  179. {$ENDIF}
  180. {$DEFINE GLB_SUPPORT_JPEG_READ}
  181. {$DEFINE GLB_SUPPORT_JPEG_WRITE}
  182. {$ENDIF}
  183. // JPEG Image
  184. {$IFDEF GLB_DELPHI_JPEG}
  185. {$IFDEF GLB_LIB_JPEG}
  186. {$MESSAGE warn 'The library libJPEG will be ignored if you are using the unit JPEG.'}
  187. {$undef GLB_LIB_JPEG}
  188. {$ENDIF}
  189. {$DEFINE GLB_SUPPORT_JPEG_READ}
  190. {$DEFINE GLB_SUPPORT_JPEG_WRITE}
  191. {$ENDIF}
  192. // libJPEG
  193. {$IFDEF GLB_LIB_JPEG}
  194. {$DEFINE GLB_SUPPORT_JPEG_READ}
  195. {$DEFINE GLB_SUPPORT_JPEG_WRITE}
  196. {$ENDIF}
  197. // native OpenGL
  198. {$IF DEFINED(GLB_NATIVE_OGL_STATIC) AND DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
  199. {$MESSAGE warn 'GLB_NATIVE_OGL_STATIC will be ignored because you enabled GLB_NATIVE_OGL_DYNAMIC'}
  200. {$IFEND}
  201. // general options
  202. {$EXTENDEDSYNTAX ON}
  203. {$LONGSTRINGS ON}
  204. {$ALIGN ON}
  205. {$IFNDEF FPC}
  206. {$OPTIMIZATION ON}
  207. {$ENDIF}
  208. interface
  209. uses
  210. {$IFNDEF GLB_NATIVE_OGL}
  211. {$IFDEF OPENGL_ES} dglOpenGLES,
  212. {$ELSE} dglOpenGL, {$ENDIF}
  213. {$ENDIF}
  214. {$IF DEFINED(GLB_WIN) AND
  215. (DEFINED(GLB_NATIVE_OGL) OR
  216. DEFINED(GLB_DELPHI))} windows, {$IFEND}
  217. {$IFDEF GLB_SDL} SDL, {$ENDIF}
  218. {$IFDEF GLB_LAZARUS} IntfGraphics, GraphType, Graphics, {$ENDIF}
  219. {$IFDEF GLB_DELPHI} Dialogs, Graphics, Types, {$ENDIF}
  220. {$IFDEF GLB_SDL_IMAGE} SDL_image, {$ENDIF}
  221. {$IFDEF GLB_PNGIMAGE} pngimage, {$ENDIF}
  222. {$IFDEF GLB_LIB_PNG} libPNG, {$ENDIF}
  223. {$IFDEF GLB_DELPHI_JPEG} JPEG, {$ENDIF}
  224. {$IFDEF GLB_LIB_JPEG} libJPEG, {$ENDIF}
  225. Classes, SysUtils;
  226. {$IFDEF GLB_NATIVE_OGL}
  227. const
  228. GL_TRUE = 1;
  229. GL_FALSE = 0;
  230. GL_ZERO = 0;
  231. GL_ONE = 1;
  232. GL_VERSION = $1F02;
  233. GL_EXTENSIONS = $1F03;
  234. GL_TEXTURE_1D = $0DE0;
  235. GL_TEXTURE_2D = $0DE1;
  236. GL_TEXTURE_RECTANGLE = $84F5;
  237. GL_NORMAL_MAP = $8511;
  238. GL_TEXTURE_CUBE_MAP = $8513;
  239. GL_REFLECTION_MAP = $8512;
  240. GL_TEXTURE_CUBE_MAP_POSITIVE_X = $8515;
  241. GL_TEXTURE_CUBE_MAP_NEGATIVE_X = $8516;
  242. GL_TEXTURE_CUBE_MAP_POSITIVE_Y = $8517;
  243. GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = $8518;
  244. GL_TEXTURE_CUBE_MAP_POSITIVE_Z = $8519;
  245. GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = $851A;
  246. GL_TEXTURE_WIDTH = $1000;
  247. GL_TEXTURE_HEIGHT = $1001;
  248. GL_TEXTURE_INTERNAL_FORMAT = $1003;
  249. GL_TEXTURE_SWIZZLE_RGBA = $8E46;
  250. GL_S = $2000;
  251. GL_T = $2001;
  252. GL_R = $2002;
  253. GL_Q = $2003;
  254. GL_TEXTURE_GEN_S = $0C60;
  255. GL_TEXTURE_GEN_T = $0C61;
  256. GL_TEXTURE_GEN_R = $0C62;
  257. GL_TEXTURE_GEN_Q = $0C63;
  258. GL_RED = $1903;
  259. GL_GREEN = $1904;
  260. GL_BLUE = $1905;
  261. GL_ALPHA = $1906;
  262. GL_ALPHA4 = $803B;
  263. GL_ALPHA8 = $803C;
  264. GL_ALPHA12 = $803D;
  265. GL_ALPHA16 = $803E;
  266. GL_LUMINANCE = $1909;
  267. GL_LUMINANCE4 = $803F;
  268. GL_LUMINANCE8 = $8040;
  269. GL_LUMINANCE12 = $8041;
  270. GL_LUMINANCE16 = $8042;
  271. GL_LUMINANCE_ALPHA = $190A;
  272. GL_LUMINANCE4_ALPHA4 = $8043;
  273. GL_LUMINANCE6_ALPHA2 = $8044;
  274. GL_LUMINANCE8_ALPHA8 = $8045;
  275. GL_LUMINANCE12_ALPHA4 = $8046;
  276. GL_LUMINANCE12_ALPHA12 = $8047;
  277. GL_LUMINANCE16_ALPHA16 = $8048;
  278. GL_RGB = $1907;
  279. GL_BGR = $80E0;
  280. GL_R3_G3_B2 = $2A10;
  281. GL_RGB4 = $804F;
  282. GL_RGB5 = $8050;
  283. GL_RGB565 = $8D62;
  284. GL_RGB8 = $8051;
  285. GL_RGB10 = $8052;
  286. GL_RGB12 = $8053;
  287. GL_RGB16 = $8054;
  288. GL_RGBA = $1908;
  289. GL_BGRA = $80E1;
  290. GL_RGBA2 = $8055;
  291. GL_RGBA4 = $8056;
  292. GL_RGB5_A1 = $8057;
  293. GL_RGBA8 = $8058;
  294. GL_RGB10_A2 = $8059;
  295. GL_RGBA12 = $805A;
  296. GL_RGBA16 = $805B;
  297. GL_DEPTH_COMPONENT = $1902;
  298. GL_DEPTH_COMPONENT16 = $81A5;
  299. GL_DEPTH_COMPONENT24 = $81A6;
  300. GL_DEPTH_COMPONENT32 = $81A7;
  301. GL_COMPRESSED_RGB = $84ED;
  302. GL_COMPRESSED_RGBA = $84EE;
  303. GL_COMPRESSED_RGB_S3TC_DXT1_EXT = $83F0;
  304. GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = $83F1;
  305. GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = $83F2;
  306. GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = $83F3;
  307. GL_UNSIGNED_BYTE = $1401;
  308. GL_UNSIGNED_BYTE_3_3_2 = $8032;
  309. GL_UNSIGNED_BYTE_2_3_3_REV = $8362;
  310. GL_UNSIGNED_SHORT = $1403;
  311. GL_UNSIGNED_SHORT_5_6_5 = $8363;
  312. GL_UNSIGNED_SHORT_4_4_4_4 = $8033;
  313. GL_UNSIGNED_SHORT_5_5_5_1 = $8034;
  314. GL_UNSIGNED_SHORT_5_6_5_REV = $8364;
  315. GL_UNSIGNED_SHORT_4_4_4_4_REV = $8365;
  316. GL_UNSIGNED_SHORT_1_5_5_5_REV = $8366;
  317. GL_UNSIGNED_INT = $1405;
  318. GL_UNSIGNED_INT_8_8_8_8 = $8035;
  319. GL_UNSIGNED_INT_10_10_10_2 = $8036;
  320. GL_UNSIGNED_INT_8_8_8_8_REV = $8367;
  321. GL_UNSIGNED_INT_2_10_10_10_REV = $8368;
  322. { Texture Filter }
  323. GL_TEXTURE_MAG_FILTER = $2800;
  324. GL_TEXTURE_MIN_FILTER = $2801;
  325. GL_NEAREST = $2600;
  326. GL_NEAREST_MIPMAP_NEAREST = $2700;
  327. GL_NEAREST_MIPMAP_LINEAR = $2702;
  328. GL_LINEAR = $2601;
  329. GL_LINEAR_MIPMAP_NEAREST = $2701;
  330. GL_LINEAR_MIPMAP_LINEAR = $2703;
  331. { Texture Wrap }
  332. GL_TEXTURE_WRAP_S = $2802;
  333. GL_TEXTURE_WRAP_T = $2803;
  334. GL_TEXTURE_WRAP_R = $8072;
  335. GL_CLAMP = $2900;
  336. GL_REPEAT = $2901;
  337. GL_CLAMP_TO_EDGE = $812F;
  338. GL_CLAMP_TO_BORDER = $812D;
  339. GL_MIRRORED_REPEAT = $8370;
  340. { Other }
  341. GL_GENERATE_MIPMAP = $8191;
  342. GL_TEXTURE_BORDER_COLOR = $1004;
  343. GL_MAX_TEXTURE_SIZE = $0D33;
  344. GL_PACK_ALIGNMENT = $0D05;
  345. GL_UNPACK_ALIGNMENT = $0CF5;
  346. GL_TEXTURE_MAX_ANISOTROPY_EXT = $84FE;
  347. GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = $84FF;
  348. GL_MAX_CUBE_MAP_TEXTURE_SIZE = $851C;
  349. GL_TEXTURE_GEN_MODE = $2500;
  350. {$IF DEFINED(GLB_WIN)}
  351. libglu = 'glu32.dll';
  352. libopengl = 'opengl32.dll';
  353. {$ELSEIF DEFINED(GLB_LINUX)}
  354. libglu = 'libGLU.so.1';
  355. libopengl = 'libGL.so.1';
  356. {$IFEND}
  357. type
  358. GLboolean = BYTEBOOL;
  359. GLint = Integer;
  360. GLsizei = Integer;
  361. GLuint = Cardinal;
  362. GLfloat = Single;
  363. GLenum = Cardinal;
  364. PGLvoid = Pointer;
  365. PGLboolean = ^GLboolean;
  366. PGLint = ^GLint;
  367. PGLuint = ^GLuint;
  368. PGLfloat = ^GLfloat;
  369. TglCompressedTexImage1D = procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  370. 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}
  371. TglGetCompressedTexImage = procedure(target: GLenum; level: GLint; img: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  372. {$IF DEFINED(GLB_WIN)}
  373. TwglGetProcAddress = function (ProcName: PAnsiChar): Pointer; stdcall;
  374. {$ELSEIF DEFINED(GLB_LINUX)}
  375. TglXGetProcAddress = function(ProcName: PAnsiChar): Pointer; cdecl;
  376. TglXGetProcAddressARB = function(const name: PAnsiChar): pointer; cdecl;
  377. {$IFEND}
  378. {$IF DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
  379. TglEnable = procedure(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  380. TglDisable = procedure(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  381. TglGetString = function(name: GLenum): PAnsiChar; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  382. TglGetIntegerv = procedure(pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  383. TglTexParameteri = procedure(target: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  384. TglTexParameteriv = procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  385. TglTexParameterfv = procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  386. TglGetTexParameteriv = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  387. TglGetTexParameterfv = procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  388. TglGetTexLevelParameteriv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  389. TglGetTexLevelParameterfv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  390. TglTexGeni = procedure(coord: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  391. TglGenTextures = procedure(n: GLsizei; textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  392. TglBindTexture = procedure(target: GLenum; texture: GLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  393. TglDeleteTextures = procedure(n: GLsizei; const textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  394. TglAreTexturesResident = function(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  395. TglReadPixels = procedure(x: GLint; y: GLint; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  396. TglPixelStorei = procedure(pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  397. 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}
  398. 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}
  399. TglGetTexImage = procedure(target: GLenum; level: GLint; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  400. TgluBuild1DMipmaps = function(target: GLEnum; components, width: GLint; format, atype: GLEnum; const data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  401. TgluBuild2DMipmaps = function(target: GLEnum; components, width, height: GLint; format, atype: GLEnum; const Data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  402. {$ELSEIF DEFINED(GLB_NATIVE_OGL_STATIC)}
  403. procedure glEnable(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  404. procedure glDisable(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  405. function glGetString(name: GLenum): PAnsiChar; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  406. procedure glGetIntegerv(pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  407. procedure glTexParameteri(target: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  408. procedure glTexParameteriv(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  409. procedure glTexParameterfv(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  410. procedure glGetTexParameteriv(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  411. procedure glGetTexParameterfv(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  412. procedure glGetTexLevelParameteriv(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  413. procedure glGetTexLevelParameterfv(target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  414. procedure glTexGeni(coord: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  415. procedure glGenTextures(n: GLsizei; textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  416. procedure glBindTexture(target: GLenum; texture: GLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  417. procedure glDeleteTextures(n: GLsizei; const textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  418. function glAreTexturesResident(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  419. 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;
  420. procedure glPixelStorei(pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  421. 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;
  422. 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;
  423. procedure glGetTexImage(target: GLenum; level: GLint; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  424. function gluBuild1DMipmaps(target: GLEnum; components, width: GLint; format, atype: GLEnum; const data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libglu;
  425. function gluBuild2DMipmaps(target: GLEnum; components, width, height: GLint; format, atype: GLEnum; const Data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libglu;
  426. {$IFEND}
  427. var
  428. GL_VERSION_1_2,
  429. GL_VERSION_1_3,
  430. GL_VERSION_1_4,
  431. GL_VERSION_2_0,
  432. GL_VERSION_3_3,
  433. GL_SGIS_generate_mipmap,
  434. GL_ARB_texture_border_clamp,
  435. GL_ARB_texture_mirrored_repeat,
  436. GL_ARB_texture_rectangle,
  437. GL_ARB_texture_non_power_of_two,
  438. GL_ARB_texture_swizzle,
  439. GL_ARB_texture_cube_map,
  440. GL_IBM_texture_mirrored_repeat,
  441. GL_NV_texture_rectangle,
  442. GL_EXT_texture_edge_clamp,
  443. GL_EXT_texture_rectangle,
  444. GL_EXT_texture_swizzle,
  445. GL_EXT_texture_cube_map,
  446. GL_EXT_texture_filter_anisotropic: Boolean;
  447. glCompressedTexImage1D: TglCompressedTexImage1D;
  448. glCompressedTexImage2D: TglCompressedTexImage2D;
  449. glGetCompressedTexImage: TglGetCompressedTexImage;
  450. {$IF DEFINED(GLB_WIN)}
  451. wglGetProcAddress: TwglGetProcAddress;
  452. {$ELSEIF DEFINED(GLB_LINUX)}
  453. glXGetProcAddress: TglXGetProcAddress;
  454. glXGetProcAddressARB: TglXGetProcAddress;
  455. {$IFEND}
  456. {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
  457. glEnable: TglEnable;
  458. glDisable: TglDisable;
  459. glGetString: TglGetString;
  460. glGetIntegerv: TglGetIntegerv;
  461. glTexParameteri: TglTexParameteri;
  462. glTexParameteriv: TglTexParameteriv;
  463. glTexParameterfv: TglTexParameterfv;
  464. glGetTexParameteriv: TglGetTexParameteriv;
  465. glGetTexParameterfv: TglGetTexParameterfv;
  466. glGetTexLevelParameteriv: TglGetTexLevelParameteriv;
  467. glGetTexLevelParameterfv: TglGetTexLevelParameterfv;
  468. glTexGeni: TglTexGeni;
  469. glGenTextures: TglGenTextures;
  470. glBindTexture: TglBindTexture;
  471. glDeleteTextures: TglDeleteTextures;
  472. glAreTexturesResident: TglAreTexturesResident;
  473. glReadPixels: TglReadPixels;
  474. glPixelStorei: TglPixelStorei;
  475. glTexImage1D: TglTexImage1D;
  476. glTexImage2D: TglTexImage2D;
  477. glGetTexImage: TglGetTexImage;
  478. gluBuild1DMipmaps: TgluBuild1DMipmaps;
  479. gluBuild2DMipmaps: TgluBuild2DMipmaps;
  480. {$ENDIF}
  481. {$ENDIF}
  482. type
  483. {$IFNDEF fpc}
  484. QWord = System.UInt64;
  485. PQWord = ^QWord;
  486. PtrInt = Longint;
  487. PtrUInt = DWord;
  488. {$ENDIF}
  489. { type that describes the format of the data stored in a texture.
  490. the name of formats is composed of the following constituents:
  491. - multiple channels:
  492. - channel (e.g. R, G, B, A or Alpha, Luminance or X (reserved))
  493. - width of the chanel in bit (4, 8, 16, ...)
  494. - data type (e.g. ub, us, ui)
  495. - number of elements of data types }
  496. TglBitmapFormat = (
  497. tfEmpty = 0,
  498. tfAlpha4ub1, //< 1 x unsigned byte
  499. tfAlpha8ub1, //< 1 x unsigned byte
  500. tfAlpha16us1, //< 1 x unsigned short
  501. tfLuminance4ub1, //< 1 x unsigned byte
  502. tfLuminance8ub1, //< 1 x unsigned byte
  503. tfLuminance16us1, //< 1 x unsigned short
  504. tfLuminance4Alpha4ub2, //< 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
  505. tfLuminance6Alpha2ub2, //< 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
  506. tfLuminance8Alpha8ub2, //< 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
  507. tfLuminance12Alpha4us2, //< 1 x unsigned short (lum), 1 x unsigned short (alpha)
  508. tfLuminance16Alpha16us2, //< 1 x unsigned short (lum), 1 x unsigned short (alpha)
  509. tfR3G3B2ub1, //< 1 x unsigned byte (3bit red, 3bit green, 2bit blue)
  510. tfRGBX4us1, //< 1 x unsigned short (4bit red, 4bit green, 4bit blue, 4bit reserverd)
  511. tfXRGB4us1, //< 1 x unsigned short (4bit reserved, 4bit red, 4bit green, 4bit blue)
  512. tfR5G6B5us1, //< 1 x unsigned short (5bit red, 6bit green, 5bit blue)
  513. tfRGB5X1us1, //< 1 x unsigned short (5bit red, 5bit green, 5bit blue, 1bit reserved)
  514. tfX1RGB5us1, //< 1 x unsigned short (1bit reserved, 5bit red, 5bit green, 5bit blue)
  515. tfRGB8ub3, //< 1 x unsigned byte (red), 1 x unsigned byte (green), 1 x unsigned byte (blue)
  516. tfRGBX8ui1, //< 1 x unsigned int (8bit red, 8bit green, 8bit blue, 8bit reserved)
  517. tfXRGB8ui1, //< 1 x unsigned int (8bit reserved, 8bit red, 8bit green, 8bit blue)
  518. tfRGB10X2ui1, //< 1 x unsigned int (10bit red, 10bit green, 10bit blue, 2bit reserved)
  519. tfX2RGB10ui1, //< 1 x unsigned int (2bit reserved, 10bit red, 10bit green, 10bit blue)
  520. tfRGB16us3, //< 1 x unsigned short (red), 1 x unsigned short (green), 1 x unsigned short (blue)
  521. tfRGBA4us1, //< 1 x unsigned short (4bit red, 4bit green, 4bit blue, 4bit alpha)
  522. tfARGB4us1, //< 1 x unsigned short (4bit alpha, 4bit red, 4bit green, 4bit blue)
  523. tfRGB5A1us1, //< 1 x unsigned short (5bit red, 5bit green, 5bit blue, 1bit alpha)
  524. tfA1RGB5us1, //< 1 x unsigned short (1bit alpha, 5bit red, 5bit green, 5bit blue)
  525. tfRGBA8ui1, //< 1 x unsigned int (8bit red, 8bit green, 8bit blue, 8 bit alpha)
  526. tfARGB8ui1, //< 1 x unsigned int (8 bit alpha, 8bit red, 8bit green, 8bit blue)
  527. tfRGBA8ub4, //< 1 x unsigned byte (red), 1 x unsigned byte (green), 1 x unsigned byte (blue), 1 x unsigned byte (alpha)
  528. tfRGB10A2ui1, //< 1 x unsigned int (10bit red, 10bit green, 10bit blue, 2bit alpha)
  529. tfA2RGB10ui1, //< 1 x unsigned int (2bit alpha, 10bit red, 10bit green, 10bit blue)
  530. tfRGBA16us4, //< 1 x unsigned short (red), 1 x unsigned short (green), 1 x unsigned short (blue), 1 x unsigned short (alpha)
  531. tfBGRX4us1, //< 1 x unsigned short (4bit blue, 4bit green, 4bit red, 4bit reserved)
  532. tfXBGR4us1, //< 1 x unsigned short (4bit reserved, 4bit blue, 4bit green, 4bit red)
  533. tfB5G6R5us1, //< 1 x unsigned short (5bit blue, 6bit green, 5bit red)
  534. tfBGR5X1us1, //< 1 x unsigned short (5bit blue, 5bit green, 5bit red, 1bit reserved)
  535. tfX1BGR5us1, //< 1 x unsigned short (1bit reserved, 5bit blue, 5bit green, 5bit red)
  536. tfBGR8ub3, //< 1 x unsigned byte (blue), 1 x unsigned byte (green), 1 x unsigned byte (red)
  537. tfBGRX8ui1, //< 1 x unsigned int (8bit blue, 8bit green, 8bit red, 8bit reserved)
  538. tfXBGR8ui1, //< 1 x unsigned int (8bit reserved, 8bit blue, 8bit green, 8bit red)
  539. tfBGR10X2ui1, //< 1 x unsigned int (10bit blue, 10bit green, 10bit red, 2bit reserved)
  540. tfX2BGR10ui1, //< 1 x unsigned int (2bit reserved, 10bit blue, 10bit green, 10bit red)
  541. tfBGR16us3, //< 1 x unsigned short (blue), 1 x unsigned short (green), 1 x unsigned short (red)
  542. tfBGRA4us1, //< 1 x unsigned short (4bit blue, 4bit green, 4bit red, 4bit alpha)
  543. tfABGR4us1, //< 1 x unsigned short (4bit alpha, 4bit blue, 4bit green, 4bit red)
  544. tfBGR5A1us1, //< 1 x unsigned short (5bit blue, 5bit green, 5bit red, 1bit alpha)
  545. tfA1BGR5us1, //< 1 x unsigned short (1bit alpha, 5bit blue, 5bit green, 5bit red)
  546. tfBGRA8ui1, //< 1 x unsigned int (8bit blue, 8bit green, 8bit red, 8bit alpha)
  547. tfABGR8ui1, //< 1 x unsigned int (8bit alpha, 8bit blue, 8bit green, 8bit red)
  548. tfBGRA8ub4, //< 1 x unsigned byte (blue), 1 x unsigned byte (green), 1 x unsigned byte (red), 1 x unsigned byte (alpha)
  549. tfBGR10A2ui1, //< 1 x unsigned int (10bit blue, 10bit green, 10bit red, 2bit alpha)
  550. tfA2BGR10ui1, //< 1 x unsigned int (2bit alpha, 10bit blue, 10bit green, 10bit red)
  551. tfBGRA16us4, //< 1 x unsigned short (blue), 1 x unsigned short (green), 1 x unsigned short (red), 1 x unsigned short (alpha)
  552. tfDepth16us1, //< 1 x unsigned short (depth)
  553. tfDepth24ui1, //< 1 x unsigned int (depth)
  554. tfDepth32ui1, //< 1 x unsigned int (depth)
  555. tfS3tcDtx1RGBA,
  556. tfS3tcDtx3RGBA,
  557. tfS3tcDtx5RGBA
  558. );
  559. { type to define suitable file formats }
  560. TglBitmapFileType = (
  561. {$IFDEF GLB_SUPPORT_PNG_WRITE} ftPNG, {$ENDIF} //< Portable Network Graphic file (PNG)
  562. {$IFDEF GLB_SUPPORT_JPEG_WRITE}ftJPEG, {$ENDIF} //< JPEG file
  563. ftDDS, //< Direct Draw Surface file (DDS)
  564. ftTGA, //< Targa Image File (TGA)
  565. ftBMP, //< Windows Bitmap File (BMP)
  566. ftRAW); //< glBitmap RAW file format
  567. TglBitmapFileTypes = set of TglBitmapFileType;
  568. { possible mipmap types }
  569. TglBitmapMipMap = (
  570. mmNone, //< no mipmaps
  571. mmMipmap, //< normal mipmaps
  572. mmMipmapGlu); //< mipmaps generated with glu functions
  573. { possible normal map functions }
  574. TglBitmapNormalMapFunc = (
  575. nm4Samples,
  576. nmSobel,
  577. nm3x3,
  578. nm5x5);
  579. ////////////////////////////////////////////////////////////////////////////////////////////////////
  580. EglBitmap = class(Exception); //< glBitmap exception
  581. EglBitmapNotSupported = class(Exception); //< exception for not supported functions
  582. EglBitmapSizeToLarge = class(EglBitmap); //< exception for to large textures
  583. EglBitmapNonPowerOfTwo = class(EglBitmap); //< exception for non power of two textures
  584. EglBitmapUnsupportedFormat = class(EglBitmap) //< exception for unsupporetd formats
  585. public
  586. constructor Create(const aFormat: TglBitmapFormat); overload;
  587. constructor Create(const aMsg: String; const aFormat: TglBitmapFormat); overload;
  588. end;
  589. ////////////////////////////////////////////////////////////////////////////////////////////////////
  590. { record that stores 4 unsigned integer values }
  591. TglBitmapRec4ui = packed record
  592. case Integer of
  593. 0: (r, g, b, a: Cardinal);
  594. 1: (arr: array[0..3] of Cardinal);
  595. end;
  596. { record that stores 4 unsigned byte values }
  597. TglBitmapRec4ub = packed record
  598. case Integer of
  599. 0: (r, g, b, a: Byte);
  600. 1: (arr: array[0..3] of Byte);
  601. end;
  602. { record that stores 4 unsigned long integer values }
  603. TglBitmapRec4ul = packed record
  604. case Integer of
  605. 0: (r, g, b, a: QWord);
  606. 1: (arr: array[0..3] of QWord);
  607. end;
  608. { describes the properties of a given texture data format }
  609. TglBitmapFormatDescriptor = class(TObject)
  610. private
  611. // cached properties
  612. fBytesPerPixel: Single; //< number of bytes for each pixel
  613. fChannelCount: Integer; //< number of color channels
  614. fMask: TglBitmapRec4ul; //< bitmask for each color channel
  615. fRange: TglBitmapRec4ui; //< maximal value of each color channel
  616. { @return @true if the format has a red color channel, @false otherwise }
  617. function GetHasRed: Boolean;
  618. { @return @true if the format has a green color channel, @false otherwise }
  619. function GetHasGreen: Boolean;
  620. { @return @true if the format has a blue color channel, @false otherwise }
  621. function GetHasBlue: Boolean;
  622. { @return @true if the format has a alpha color channel, @false otherwise }
  623. function GetHasAlpha: Boolean;
  624. { @return @true if the format has any color color channel, @false otherwise }
  625. function GetHasColor: Boolean;
  626. { @return @true if the format is a grayscale format, @false otherwise }
  627. function GetIsGrayscale: Boolean;
  628. protected
  629. fFormat: TglBitmapFormat; //< format this descriptor belongs to
  630. fWithAlpha: TglBitmapFormat; //< suitable format with alpha channel
  631. fWithoutAlpha: TglBitmapFormat; //< suitable format without alpha channel
  632. fOpenGLFormat: TglBitmapFormat; //< suitable format that is supported by OpenGL
  633. fRGBInverted: TglBitmapFormat; //< suitable format with inverted RGB channels
  634. fUncompressed: TglBitmapFormat; //< suitable format with uncompressed data
  635. fBitsPerPixel: Integer; //< number of bits per pixel
  636. fIsCompressed: Boolean; //< @true if the format is compressed, @false otherwise
  637. fPrecision: TglBitmapRec4ub; //< number of bits for each color channel
  638. fShift: TglBitmapRec4ub; //< bit offset for each color channel
  639. fglFormat: GLenum; //< OpenGL format enum (e.g. GL_RGB)
  640. fglInternalFormat: GLenum; //< OpenGL internal format enum (e.g. GL_RGB8)
  641. fglDataFormat: GLenum; //< OpenGL data format enum (e.g. GL_UNSIGNED_BYTE)
  642. { set values for this format descriptor }
  643. procedure SetValues; virtual;
  644. { calculate cached values }
  645. procedure CalcValues;
  646. public
  647. property Format: TglBitmapFormat read fFormat; //< format this descriptor belongs to
  648. property ChannelCount: Integer read fChannelCount; //< number of color channels
  649. property IsCompressed: Boolean read fIsCompressed; //< @true if the format is compressed, @false otherwise
  650. property BitsPerPixel: Integer read fBitsPerPixel; //< number of bytes per pixel
  651. property BytesPerPixel: Single read fBytesPerPixel; //< number of bits per pixel
  652. property Precision: TglBitmapRec4ub read fPrecision; //< number of bits for each color channel
  653. property Shift: TglBitmapRec4ub read fShift; //< bit offset for each color channel
  654. property Range: TglBitmapRec4ui read fRange; //< maximal value of each color channel
  655. property Mask: TglBitmapRec4ul read fMask; //< bitmask for each color channel
  656. property RGBInverted: TglBitmapFormat read fRGBInverted; //< suitable format with inverted RGB channels
  657. property WithAlpha: TglBitmapFormat read fWithAlpha; //< suitable format with alpha channel
  658. property WithoutAlpha: TglBitmapFormat read fWithAlpha; //< suitable format without alpha channel
  659. property OpenGLFormat: TglBitmapFormat read fOpenGLFormat; //< suitable format that is supported by OpenGL
  660. property Uncompressed: TglBitmapFormat read fUncompressed; //< suitable format with uncompressed data
  661. property glFormat: GLenum read fglFormat; //< OpenGL format enum (e.g. GL_RGB)
  662. property glInternalFormat: GLenum read fglInternalFormat; //< OpenGL internal format enum (e.g. GL_RGB8)
  663. property glDataFormat: GLenum read fglDataFormat; //< OpenGL data format enum (e.g. GL_UNSIGNED_BYTE)
  664. property HasRed: Boolean read GetHasRed; //< @true if the format has a red color channel, @false otherwise
  665. property HasGreen: Boolean read GetHasGreen; //< @true if the format has a green color channel, @false otherwise
  666. property HasBlue: Boolean read GetHasBlue; //< @true if the format has a blue color channel, @false otherwise
  667. property HasAlpha: Boolean read GetHasAlpha; //< @true if the format has a alpha color channel, @false otherwise
  668. property HasColor: Boolean read GetHasColor; //< @true if the format has any color color channel, @false otherwise
  669. property IsGrayscale: Boolean read GetIsGrayscale; //< @true if the format is a grayscale format, @false otherwise
  670. { constructor }
  671. constructor Create;
  672. public
  673. { get the format descriptor by a given OpenGL internal format
  674. @param aInternalFormat OpenGL internal format to get format descriptor for
  675. @returns suitable format descriptor or tfEmpty-Descriptor }
  676. class function GetByFormat(const aInternalFormat: GLenum): TglBitmapFormatDescriptor;
  677. end;
  678. ////////////////////////////////////////////////////////////////////////////////////////////////////
  679. { structure to store pixel data in }
  680. TglBitmapPixelData = packed record
  681. Data: TglBitmapRec4ui; //< color data for each color channel
  682. Range: TglBitmapRec4ui; //< maximal color value for each channel
  683. Format: TglBitmapFormat; //< format of the pixel
  684. end;
  685. PglBitmapPixelData = ^TglBitmapPixelData;
  686. TglBitmapSizeFields = set of (ffX, ffY);
  687. TglBitmapSize = packed record
  688. Fields: TglBitmapSizeFields;
  689. X: Word;
  690. Y: Word;
  691. end;
  692. TglBitmapPixelPosition = TglBitmapSize;
  693. ////////////////////////////////////////////////////////////////////////////////////////////////////
  694. TglBitmap = class;
  695. { structure to store data for converting in }
  696. TglBitmapFunctionRec = record
  697. Sender: TglBitmap; //< texture object that stores the data to convert
  698. Size: TglBitmapSize; //< size of the texture
  699. Position: TglBitmapPixelPosition; //< position of the currently pixel
  700. Source: TglBitmapPixelData; //< pixel data of the current pixel
  701. Dest: TglBitmapPixelData; //< new data of the pixel (must be filled in)
  702. Args: Pointer; //< user defined args that was passed to the convert function
  703. end;
  704. { callback to use for converting texture data }
  705. TglBitmapFunction = procedure(var FuncRec: TglBitmapFunctionRec);
  706. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  707. { base class for all glBitmap classes. used to manage OpenGL texture objects
  708. and to load, save and manipulate texture data }
  709. TglBitmap = class
  710. private
  711. { @returns format descriptor that describes the format of the stored data }
  712. function GetFormatDesc: TglBitmapFormatDescriptor;
  713. protected
  714. fID: GLuint; //< name of the OpenGL texture object
  715. fTarget: GLuint; //< texture target (e.g. GL_TEXTURE_2D)
  716. fAnisotropic: Integer; //< anisotropic level
  717. fDeleteTextureOnFree: Boolean; //< delete OpenGL texture object when this object is destroyed
  718. fFreeDataOnDestroy: Boolean; //< free stored data when this object is destroyed
  719. fFreeDataAfterGenTexture: Boolean; //< free stored data after data was uploaded to video card
  720. fData: PByte; //< data of this texture
  721. {$IFNDEF OPENGL_ES}
  722. fIsResident: GLboolean; //< @true if OpenGL texture object has data, @false otherwise
  723. {$ENDIF}
  724. fBorderColor: array[0..3] of Single; //< color of the texture border
  725. fDimension: TglBitmapSize; //< size of this texture
  726. fMipMap: TglBitmapMipMap; //< mipmap type
  727. fFormat: TglBitmapFormat; //< format the texture data is stored in
  728. // Mapping
  729. fPixelSize: Integer; //< size of one pixel (in byte)
  730. fRowSize: Integer; //< size of one pixel row (in byte)
  731. // Filtering
  732. fFilterMin: GLenum; //< min filter to apply to the texture
  733. fFilterMag: GLenum; //< mag filter to apply to the texture
  734. // TexturWarp
  735. fWrapS: GLenum; //< texture wrapping for x axis
  736. fWrapT: GLenum; //< texture wrapping for y axis
  737. fWrapR: GLenum; //< texture wrapping for z axis
  738. {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
  739. //Swizzle
  740. fSwizzle: array[0..3] of GLenum; //< color channel swizzle
  741. {$IFEND}
  742. // CustomData
  743. fFilename: String; //< filename the texture was load from
  744. fCustomName: String; //< user defined name
  745. fCustomNameW: WideString; //< user defined name
  746. fCustomData: Pointer; //< user defined data
  747. protected
  748. { @returns the actual width of the texture }
  749. function GetWidth: Integer; virtual;
  750. { @returns the actual height of the texture }
  751. function GetHeight: Integer; virtual;
  752. { @returns the width of the texture or 1 if the width is zero }
  753. function GetFileWidth: Integer; virtual;
  754. { @returns the height of the texture or 1 if the height is zero }
  755. function GetFileHeight: Integer; virtual;
  756. protected
  757. { set a new value for fCustomData }
  758. procedure SetCustomData(const aValue: Pointer);
  759. { set a new value for fCustomName }
  760. procedure SetCustomName(const aValue: String);
  761. { set a new value for fCustomNameW }
  762. procedure SetCustomNameW(const aValue: WideString);
  763. { set new value for fFreeDataOnDestroy }
  764. procedure SetFreeDataOnDestroy(const aValue: Boolean);
  765. { set new value for fDeleteTextureOnFree }
  766. procedure SetDeleteTextureOnFree(const aValue: Boolean);
  767. { set new value for the data format. only possible if new format has the same pixel size.
  768. if you want to convert the texture data, see ConvertTo function }
  769. procedure SetFormat(const aValue: TglBitmapFormat);
  770. { set new value for fFreeDataAfterGenTexture }
  771. procedure SetFreeDataAfterGenTexture(const aValue: Boolean);
  772. { set name of OpenGL texture object }
  773. procedure SetID(const aValue: Cardinal);
  774. { set new value for fMipMap }
  775. procedure SetMipMap(const aValue: TglBitmapMipMap);
  776. { set new value for target }
  777. procedure SetTarget(const aValue: Cardinal);
  778. { set new value for fAnisotrophic }
  779. procedure SetAnisotropic(const aValue: Integer);
  780. protected
  781. { create OpenGL texture object (delete exisiting object if exists) }
  782. procedure CreateID;
  783. { setup texture parameters }
  784. procedure SetupParameters({$IFNDEF OPENGL_ES}out aBuildWithGlu: Boolean{$ENDIF});
  785. { set data pointer of texture data
  786. @param aData pointer to new texture data (be carefull, aData could be freed by this function)
  787. @param aFormat format of the data stored at aData
  788. @param aWidth width of the texture data
  789. @param aHeight height of the texture data }
  790. procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
  791. const aWidth: Integer = -1; const aHeight: Integer = -1); virtual;
  792. { generate texture (upload texture data to video card)
  793. @param aTestTextureSize test texture size before uploading and raise exception if something is wrong }
  794. procedure GenTexture(const aTestTextureSize: Boolean = true); virtual; abstract;
  795. { flip texture horizontal
  796. @returns @true in success, @false otherwise }
  797. function FlipHorz: Boolean; virtual;
  798. { flip texture vertical
  799. @returns @true in success, @false otherwise }
  800. function FlipVert: Boolean; virtual;
  801. protected
  802. property Width: Integer read GetWidth; //< the actual width of the texture
  803. property Height: Integer read GetHeight; //< the actual height of the texture
  804. property FileWidth: Integer read GetFileWidth; //< the width of the texture or 1 if the width is zero
  805. property FileHeight: Integer read GetFileHeight; //< the height of the texture or 1 if the height is zero
  806. public
  807. property ID: Cardinal read fID write SetID; //< name of the OpenGL texture object
  808. property Target: Cardinal read fTarget write SetTarget; //< texture target (e.g. GL_TEXTURE_2D)
  809. property Format: TglBitmapFormat read fFormat write SetFormat; //< format the texture data is stored in
  810. property MipMap: TglBitmapMipMap read fMipMap write SetMipMap; //< mipmap type
  811. property Anisotropic: Integer read fAnisotropic write SetAnisotropic; //< anisotropic level
  812. property FormatDesc: TglBitmapFormatDescriptor read GetFormatDesc; //< format descriptor that describes the format of the stored data
  813. property Filename: String read fFilename; //< filename the texture was load from
  814. property CustomName: String read fCustomName write SetCustomName; //< user defined name (use at will)
  815. property CustomNameW: WideString read fCustomNameW write SetCustomNameW; //< user defined name (as WideString; use at will)
  816. property CustomData: Pointer read fCustomData write SetCustomData; //< user defined data (use at will)
  817. property DeleteTextureOnFree: Boolean read fDeleteTextureOnFree write SetDeleteTextureOnFree; //< delete texture object when this object is destroyed
  818. property FreeDataOnDestroy: Boolean read fFreeDataOnDestroy write SetFreeDataOnDestroy; //< free stored data when this object is destroyed
  819. property FreeDataAfterGenTexture: Boolean read fFreeDataAfterGenTexture write SetFreeDataAfterGenTexture; //< free stored data after it is uplaoded to video card
  820. property Dimension: TglBitmapSize read fDimension; //< size of the texture
  821. property Data: PByte read fData; //< texture data (or @nil if unset)
  822. {$IFNDEF OPENGL_ES}
  823. property IsResident: GLboolean read fIsResident; //< @true if OpenGL texture object has data, @false otherwise
  824. {$ENDIF}
  825. { this method is called after the constructor and sets the default values of this object }
  826. procedure AfterConstruction; override;
  827. { this method is called before the destructor and does some cleanup }
  828. procedure BeforeDestruction; override;
  829. { splits a resource identifier into the resource and it's type
  830. @param aResource resource identifier to split and store name in
  831. @param aResType type of the resource }
  832. procedure PrepareResType(var aResource: String; var aResType: PChar);
  833. public
  834. { load a texture from a file
  835. @param aFilename file to load texuture from }
  836. procedure LoadFromFile(const aFilename: String);
  837. { load a texture from a stream
  838. @param aStream stream to load texture from }
  839. procedure LoadFromStream(const aStream: TStream); virtual;
  840. { use a function to generate texture data
  841. @param aSize size of the texture
  842. @param aFunc callback to use for generation
  843. @param aFormat format of the texture data
  844. @param aArgs user defined paramaters (use at will) }
  845. procedure LoadFromFunc(const aSize: TglBitmapSize; const aFunc: TglBitmapFunction;
  846. const aFormat: TglBitmapFormat; const aArgs: Pointer = nil);
  847. { load a texture from a resource
  848. @param aInstance resource handle
  849. @param aResource resource indentifier
  850. @param aResType resource type (if known) }
  851. procedure LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil);
  852. { load a texture from a resource id
  853. @param aInstance resource handle
  854. @param aResource resource ID
  855. @param aResType resource type }
  856. procedure LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
  857. public
  858. { save texture data to a file
  859. @param aFilename filename to store texture in
  860. @param aFileType file type to store data into }
  861. procedure SaveToFile(const aFilename: String; const aFileType: TglBitmapFileType);
  862. { save texture data to a stream
  863. @param aFilename filename to store texture in
  864. @param aFileType file type to store data into }
  865. procedure SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType); virtual;
  866. public
  867. { convert texture data using a user defined callback
  868. @param aFunc callback to use for converting
  869. @param aCreateTemp create a temporary buffer to use for converting
  870. @param aArgs user defined paramters (use at will)
  871. @returns @true if converting was successful, @false otherwise }
  872. function Convert(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer = nil): Boolean; overload;
  873. { convert texture data using a user defined callback
  874. @param aSource glBitmap to read data from
  875. @param aFunc callback to use for converting
  876. @param aCreateTemp create a temporary buffer to use for converting
  877. @param aFormat format of the new data
  878. @param aArgs user defined paramters (use at will)
  879. @returns @true if converting was successful, @false otherwise }
  880. function Convert(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
  881. const aFormat: TglBitmapFormat; const aArgs: Pointer = nil): Boolean; overload;
  882. { convert texture data using a specific format
  883. @param aFormat new format of texture data
  884. @returns @true if converting was successful, @false otherwise }
  885. function ConvertTo(const aFormat: TglBitmapFormat): Boolean; virtual;
  886. {$IFDEF GLB_SDL}
  887. public
  888. { assign texture data to SDL surface
  889. @param aSurface SDL surface to write data to
  890. @returns @true on success, @false otherwise }
  891. function AssignToSurface(out aSurface: PSDL_Surface): Boolean;
  892. { assign texture data from SDL surface
  893. @param aSurface SDL surface to read data from
  894. @returns @true on success, @false otherwise }
  895. function AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
  896. { assign alpha channel data to SDL surface
  897. @param aSurface SDL surface to write alpha channel data to
  898. @returns @true on success, @false otherwise }
  899. function AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
  900. { assign alpha channel data from SDL surface
  901. @param aSurface SDL surface to read data from
  902. @param aFunc callback to use for converting
  903. @param aArgs user defined parameters (use at will)
  904. @returns @true on success, @false otherwise }
  905. function AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  906. {$ENDIF}
  907. {$IFDEF GLB_DELPHI}
  908. public
  909. { assign texture data to TBitmap object
  910. @param aBitmap TBitmap to write data to
  911. @returns @true on success, @false otherwise }
  912. function AssignToBitmap(const aBitmap: TBitmap): Boolean;
  913. { assign texture data from TBitmap object
  914. @param aBitmap TBitmap to read data from
  915. @returns @true on success, @false otherwise }
  916. function AssignFromBitmap(const aBitmap: TBitmap): Boolean;
  917. { assign alpha channel data to TBitmap object
  918. @param aBitmap TBitmap to write data to
  919. @returns @true on success, @false otherwise }
  920. function AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
  921. { assign alpha channel data from TBitmap object
  922. @param aBitmap TBitmap to read data from
  923. @param aFunc callback to use for converting
  924. @param aArgs user defined parameters (use at will)
  925. @returns @true on success, @false otherwise }
  926. function AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  927. {$ENDIF}
  928. {$IFDEF GLB_LAZARUS}
  929. public
  930. { assign texture data to TLazIntfImage object
  931. @param aImage TLazIntfImage to write data to
  932. @returns @true on success, @false otherwise }
  933. function AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
  934. { assign texture data from TLazIntfImage object
  935. @param aImage TLazIntfImage to read data from
  936. @returns @true on success, @false otherwise }
  937. function AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
  938. { assign alpha channel data to TLazIntfImage object
  939. @param aImage TLazIntfImage to write data to
  940. @returns @true on success, @false otherwise }
  941. function AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
  942. { assign alpha channel data from TLazIntfImage object
  943. @param aImage TLazIntfImage to read data from
  944. @param aFunc callback to use for converting
  945. @param aArgs user defined parameters (use at will)
  946. @returns @true on success, @false otherwise }
  947. function AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  948. {$ENDIF}
  949. public
  950. { load alpha channel data from resource
  951. @param aInstance resource handle
  952. @param aResource resource ID
  953. @param aResType resource type
  954. @param aFunc callback to use for converting
  955. @param aArgs user defined parameters (use at will)
  956. @returns @true on success, @false otherwise }
  957. function AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  958. { load alpha channel data from resource ID
  959. @param aInstance resource handle
  960. @param aResourceID resource ID
  961. @param aResType resource type
  962. @param aFunc callback to use for converting
  963. @param aArgs user defined parameters (use at will)
  964. @returns @true on success, @false otherwise }
  965. function AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  966. { add alpha channel data from function
  967. @param aFunc callback to get data from
  968. @param aArgs user defined parameters (use at will)
  969. @returns @true on success, @false otherwise }
  970. function AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer = nil): Boolean; virtual;
  971. { add alpha channel data from file (macro for: new glBitmap, LoadFromFile, AddAlphaFromGlBitmap)
  972. @param aFilename file to load alpha channel data from
  973. @param aFunc callback to use for converting
  974. @param aArgs user defined parameters (use at will)
  975. @returns @true on success, @false otherwise }
  976. function AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  977. { add alpha channel data from stream (macro for: new glBitmap, LoadFromStream, AddAlphaFromGlBitmap)
  978. @param aStream stream to load alpha channel data from
  979. @param aFunc callback to use for converting
  980. @param aArgs user defined parameters (use at will)
  981. @returns @true on success, @false otherwise }
  982. function AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  983. { add alpha channel data from existing glBitmap object
  984. @param aBitmap TglBitmap to copy alpha channel data from
  985. @param aFunc callback to use for converting
  986. @param aArgs user defined parameters (use at will)
  987. @returns @true on success, @false otherwise }
  988. function AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  989. { add alpha to pixel if the pixels color is greter than the given color value
  990. @param aRed red threshold (0-255)
  991. @param aGreen green threshold (0-255)
  992. @param aBlue blue threshold (0-255)
  993. @param aDeviatation accepted deviatation (0-255)
  994. @returns @true on success, @false otherwise }
  995. function AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte = 0): Boolean;
  996. { add alpha to pixel if the pixels color is greter than the given color value
  997. @param aRed red threshold (0-Range.r)
  998. @param aGreen green threshold (0-Range.g)
  999. @param aBlue blue threshold (0-Range.b)
  1000. @param aDeviatation accepted deviatation (0-max(Range.rgb))
  1001. @returns @true on success, @false otherwise }
  1002. function AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal = 0): Boolean;
  1003. { add alpha to pixel if the pixels color is greter than the given color value
  1004. @param aRed red threshold (0.0-1.0)
  1005. @param aGreen green threshold (0.0-1.0)
  1006. @param aBlue blue threshold (0.0-1.0)
  1007. @param aDeviatation accepted deviatation (0.0-1.0)
  1008. @returns @true on success, @false otherwise }
  1009. function AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single = 0): Boolean;
  1010. { add a constand alpha value to all pixels
  1011. @param aAlpha alpha value to add (0-255)
  1012. @returns @true on success, @false otherwise }
  1013. function AddAlphaFromValue(const aAlpha: Byte): Boolean;
  1014. { add a constand alpha value to all pixels
  1015. @param aAlpha alpha value to add (0-max(Range.rgb))
  1016. @returns @true on success, @false otherwise }
  1017. function AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
  1018. { add a constand alpha value to all pixels
  1019. @param aAlpha alpha value to add (0.0-1.0)
  1020. @returns @true on success, @false otherwise }
  1021. function AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
  1022. { remove alpha channel
  1023. @returns @true on success, @false otherwise }
  1024. function RemoveAlpha: Boolean; virtual;
  1025. public
  1026. { create a clone of the current object
  1027. @returns clone of this object}
  1028. function Clone: TglBitmap;
  1029. { invert color data (xor)
  1030. @param aUseRGB xor each color channel
  1031. @param aUseAlpha xor alpha channel }
  1032. procedure Invert(const aUseRGB: Boolean = true; const aUseAlpha: Boolean = false);
  1033. { free texture stored data }
  1034. procedure FreeData;
  1035. {$IFNDEF OPENGL_ES}
  1036. { set the new value for texture border color
  1037. @param aRed red color for border (0.0-1.0)
  1038. @param aGreen green color for border (0.0-1.0)
  1039. @param aBlue blue color for border (0.0-1.0)
  1040. @param aAlpha alpha color for border (0.0-1.0) }
  1041. procedure SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
  1042. {$ENDIF}
  1043. public
  1044. { fill complete texture with one color
  1045. @param aRed red color for border (0-255)
  1046. @param aGreen green color for border (0-255)
  1047. @param aBlue blue color for border (0-255)
  1048. @param aAlpha alpha color for border (0-255) }
  1049. procedure FillWithColor(const aRed, aGreen, aBlue: Byte; const aAlpha: Byte = 255);
  1050. { fill complete texture with one color
  1051. @param aRed red color for border (0-Range.r)
  1052. @param aGreen green color for border (0-Range.g)
  1053. @param aBlue blue color for border (0-Range.b)
  1054. @param aAlpha alpha color for border (0-Range.a) }
  1055. procedure FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal = $FFFFFFFF);
  1056. { fill complete texture with one color
  1057. @param aRed red color for border (0.0-1.0)
  1058. @param aGreen green color for border (0.0-1.0)
  1059. @param aBlue blue color for border (0.0-1.0)
  1060. @param aAlpha alpha color for border (0.0-1.0) }
  1061. procedure FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single = 1.0);
  1062. public
  1063. { set new texture filer
  1064. @param aMin min filter
  1065. @param aMag mag filter }
  1066. procedure SetFilter(const aMin, aMag: GLenum);
  1067. { set new texture wrapping
  1068. @param S texture wrapping for x axis
  1069. @param T texture wrapping for y axis
  1070. @param R texture wrapping for z axis }
  1071. procedure SetWrap(
  1072. const S: GLenum = GL_CLAMP_TO_EDGE;
  1073. const T: GLenum = GL_CLAMP_TO_EDGE;
  1074. const R: GLenum = GL_CLAMP_TO_EDGE);
  1075. {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
  1076. { set new swizzle
  1077. @param r swizzle for red channel
  1078. @param g swizzle for green channel
  1079. @param b swizzle for blue channel
  1080. @param a swizzle for alpha channel }
  1081. procedure SetSwizzle(const r, g, b, a: GLenum);
  1082. {$IFEND}
  1083. public
  1084. { bind texture
  1085. @param aEnableTextureUnit enable texture unit for this texture (e.g. glEnable(GL_TEXTURE_2D)) }
  1086. procedure Bind(const aEnableTextureUnit: Boolean = true); virtual;
  1087. { bind texture
  1088. @param aDisableTextureUnit disable texture unit for this texture (e.g. glEnable(GL_TEXTURE_2D)) }
  1089. procedure Unbind(const aDisableTextureUnit: Boolean = true); virtual;
  1090. public
  1091. { constructor - created an empty texture }
  1092. constructor Create; overload;
  1093. { constructor - creates a texture and load it from a file
  1094. @param aFilename file to load texture from }
  1095. constructor Create(const aFileName: String); overload;
  1096. { constructor - creates a texture and load it from a stream
  1097. @param aStream stream to load texture from }
  1098. constructor Create(const aStream: TStream); overload;
  1099. { constructor - creates a texture with the given size, format and data
  1100. @param aSize size of the texture
  1101. @param aFormat format of the given data
  1102. @param aData texture data - be carefull: the data will now be managed by the glBitmap object,
  1103. you can control this by setting DeleteTextureOnFree, FreeDataOnDestroy and FreeDataAfterGenTexture }
  1104. constructor Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; aData: PByte = nil); overload;
  1105. { constructor - creates a texture with the given size and format and uses the given callback to create the data
  1106. @param aSize size of the texture
  1107. @param aFormat format of the given data
  1108. @param aFunc callback to use for generating the data
  1109. @param aArgs user defined parameters (use at will) }
  1110. constructor Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer = nil); overload;
  1111. { constructor - creates a texture and loads it from a resource
  1112. @param aInstance resource handle
  1113. @param aResource resource indentifier
  1114. @param aResType resource type (if known) }
  1115. constructor Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil); overload;
  1116. { constructor - creates a texture and loads it from a resource
  1117. @param aInstance resource handle
  1118. @param aResourceID resource ID
  1119. @param aResType resource type (if known) }
  1120. constructor Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar); overload;
  1121. private
  1122. {$IFDEF GLB_SUPPORT_PNG_READ}
  1123. { try to load a PNG from a stream
  1124. @param aStream stream to load PNG from
  1125. @returns @true on success, @false otherwise }
  1126. function LoadPNG(const aStream: TStream): Boolean; virtual;
  1127. {$ENDIF}
  1128. {$ifdef GLB_SUPPORT_PNG_WRITE}
  1129. { save texture data as PNG to stream
  1130. @param aStream stream to save data to}
  1131. procedure SavePNG(const aStream: TStream); virtual;
  1132. {$ENDIF}
  1133. {$IFDEF GLB_SUPPORT_JPEG_READ}
  1134. { try to load a JPEG from a stream
  1135. @param aStream stream to load JPEG from
  1136. @returns @true on success, @false otherwise }
  1137. function LoadJPEG(const aStream: TStream): Boolean; virtual;
  1138. {$ENDIF}
  1139. {$IFDEF GLB_SUPPORT_JPEG_WRITE}
  1140. { save texture data as JPEG to stream
  1141. @param aStream stream to save data to}
  1142. procedure SaveJPEG(const aStream: TStream); virtual;
  1143. {$ENDIF}
  1144. { try to load a RAW image from a stream
  1145. @param aStream stream to load RAW image from
  1146. @returns @true on success, @false otherwise }
  1147. function LoadRAW(const aStream: TStream): Boolean;
  1148. { save texture data as RAW image to stream
  1149. @param aStream stream to save data to}
  1150. procedure SaveRAW(const aStream: TStream);
  1151. { try to load a BMP from a stream
  1152. @param aStream stream to load BMP from
  1153. @returns @true on success, @false otherwise }
  1154. function LoadBMP(const aStream: TStream): Boolean;
  1155. { save texture data as BMP to stream
  1156. @param aStream stream to save data to}
  1157. procedure SaveBMP(const aStream: TStream);
  1158. { try to load a TGA from a stream
  1159. @param aStream stream to load TGA from
  1160. @returns @true on success, @false otherwise }
  1161. function LoadTGA(const aStream: TStream): Boolean;
  1162. { save texture data as TGA to stream
  1163. @param aStream stream to save data to}
  1164. procedure SaveTGA(const aStream: TStream);
  1165. { try to load a DDS from a stream
  1166. @param aStream stream to load DDS from
  1167. @returns @true on success, @false otherwise }
  1168. function LoadDDS(const aStream: TStream): Boolean;
  1169. { save texture data as DDS to stream
  1170. @param aStream stream to save data to}
  1171. procedure SaveDDS(const aStream: TStream);
  1172. end;
  1173. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1174. {$IF NOT DEFINED(OPENGL_ES)}
  1175. { wrapper class for 1-dimensional textures (OpenGL target = GL_TEXTURE_1D }
  1176. TglBitmap1D = class(TglBitmap)
  1177. protected
  1178. { set data pointer of texture data
  1179. @param aData pointer to new texture data (be carefull, aData could be freed by this function)
  1180. @param aFormat format of the data stored at aData
  1181. @param aWidth width of the texture data
  1182. @param aHeight height of the texture data }
  1183. procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat; const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
  1184. { upload the texture data to video card
  1185. @param aBuildWithGlu use glu functions to build mipmaps }
  1186. procedure UploadData(const aBuildWithGlu: Boolean);
  1187. public
  1188. property Width; //< actual with of the texture
  1189. { this method is called after constructor and initializes the object }
  1190. procedure AfterConstruction; override;
  1191. { flip texture horizontally
  1192. @returns @true on success, @fals otherwise }
  1193. function FlipHorz: Boolean; override;
  1194. { generate texture (create texture object if not exist, set texture parameters and upload data
  1195. @param aTestTextureSize check the size of the texture and throw exception if something is wrong }
  1196. procedure GenTexture(const aTestTextureSize: Boolean = true); override;
  1197. end;
  1198. {$IFEND}
  1199. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1200. { wrapper class for 2-dimensional textures (OpenGL target = GL_TEXTURE_2D) }
  1201. TglBitmap2D = class(TglBitmap)
  1202. protected
  1203. fLines: array of PByte; //< array to store scanline entry points in
  1204. { get a specific scanline
  1205. @param aIndex index of the scanline to return
  1206. @returns scanline at position aIndex or @nil }
  1207. function GetScanline(const aIndex: Integer): Pointer;
  1208. { set data pointer of texture data
  1209. @param aData pointer to new texture data (be carefull, aData could be freed by this function)
  1210. @param aFormat format of the data stored at aData
  1211. @param aWidth width of the texture data
  1212. @param aHeight height of the texture data }
  1213. procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
  1214. const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
  1215. { upload the texture data to video card
  1216. @param aTarget target o upload data to (e.g. GL_TEXTURE_2D)
  1217. @param aBuildWithGlu use glu functions to build mipmaps }
  1218. procedure UploadData(const aTarget: GLenum{$IFNDEF OPENGL_ES}; const aBuildWithGlu: Boolean{$ENDIF});
  1219. public
  1220. property Width; //< actual width of the texture
  1221. property Height; //< actual height of the texture
  1222. property Scanline[const aIndex: Integer]: Pointer read GetScanline; //< scanline to access texture data directly
  1223. { this method is called after constructor and initializes the object }
  1224. procedure AfterConstruction; override;
  1225. { copy a part of the frame buffer top the texture
  1226. @param aTop topmost pixel to copy
  1227. @param aLeft leftmost pixel to copy
  1228. @param aRight rightmost pixel to copy
  1229. @param aBottom bottommost pixel to copy
  1230. @param aFormat format to store data in }
  1231. procedure GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
  1232. {$IFNDEF OPENGL_ES}
  1233. { downlaod texture data from OpenGL texture object }
  1234. procedure GetDataFromTexture;
  1235. {$ENDIF}
  1236. { generate texture (create texture object if not exist, set texture parameters and upload data)
  1237. @param aTestTextureSize check the size of the texture and throw exception if something is wrong }
  1238. procedure GenTexture(const aTestTextureSize: Boolean = true); override;
  1239. { flip texture horizontally
  1240. @returns @true on success, @false otherwise }
  1241. function FlipHorz: Boolean; override;
  1242. { flip texture vertically
  1243. @returns @true on success, @false otherwise }
  1244. function FlipVert: Boolean; override;
  1245. { create normal map from texture data
  1246. @param aFunc normal map function to generate normalmap with
  1247. @param aScale scale of the normale stored in the normal map
  1248. @param aUseAlpha generate normalmap from alpha channel data (if present) }
  1249. procedure GenerateNormalMap(const aFunc: TglBitmapNormalMapFunc = nm3x3;
  1250. const aScale: Single = 2; const aUseAlpha: Boolean = false);
  1251. end;
  1252. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1253. {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
  1254. { wrapper class for cube maps (OpenGL target = GL_TEXTURE_CUBE_MAP) }
  1255. TglBitmapCubeMap = class(TglBitmap2D)
  1256. protected
  1257. {$IFNDEF OPENGL_ES}
  1258. fGenMode: Integer; //< generation mode for the cube map (e.g. GL_REFLECTION_MAP)
  1259. {$ENDIF}
  1260. { generate texture (create texture object if not exist, set texture parameters and upload data
  1261. do not call directly for cubemaps, use GenerateCubeMap instead
  1262. @param aTestTextureSize check the size of the texture and throw exception if something is wrong }
  1263. procedure GenTexture(const aTestTextureSize: Boolean = true); reintroduce;
  1264. public
  1265. { this method is called after constructor and initializes the object }
  1266. procedure AfterConstruction; override;
  1267. { generate texture (create texture object if not exist, set texture parameters and upload data
  1268. @param aCubeTarget cube map target to upload data to (e.g. GL_TEXTURE_CUBE_MAP_POSITIVE_X)
  1269. @param aTestTextureSize check the size of the texture and throw exception if something is wrong }
  1270. procedure GenerateCubeMap(const aCubeTarget: Cardinal; const aTestTextureSize: Boolean = true);
  1271. { bind texture
  1272. @param aEnableTexCoordsGen enable cube map generator
  1273. @param aEnableTextureUnit enable texture unit }
  1274. procedure Bind({$IFNDEF OPENGL_ES}const aEnableTexCoordsGen: Boolean = true;{$ENDIF} const aEnableTextureUnit: Boolean = true); reintroduce; virtual;
  1275. { unbind texture
  1276. @param aDisableTexCoordsGen disable cube map generator
  1277. @param aDisableTextureUnit disable texture unit }
  1278. procedure Unbind({$IFNDEF OPENGL_ES}const aDisableTexCoordsGen: Boolean = true;{$ENDIF} const aDisableTextureUnit: Boolean = true); reintroduce; virtual;
  1279. end;
  1280. {$IFEND}
  1281. {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
  1282. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1283. { wrapper class for cube normal maps }
  1284. TglBitmapNormalMap = class(TglBitmapCubeMap)
  1285. public
  1286. { this method is called after constructor and initializes the object }
  1287. procedure AfterConstruction; override;
  1288. { create cube normal map from texture data and upload it to video card
  1289. @param aSize size of each cube map texture
  1290. @param aTestTextureSize check texture size when uploading and throw exception if something is wrong }
  1291. procedure GenerateNormalMap(const aSize: Integer = 32; const aTestTextureSize: Boolean = true);
  1292. end;
  1293. {$IFEND}
  1294. const
  1295. NULL_SIZE: TglBitmapSize = (Fields: []; X: 0; Y: 0);
  1296. procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
  1297. procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
  1298. procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
  1299. procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
  1300. procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
  1301. procedure glBitmapSetDefaultWrap(
  1302. const S: Cardinal = GL_CLAMP_TO_EDGE;
  1303. const T: Cardinal = GL_CLAMP_TO_EDGE;
  1304. const R: Cardinal = GL_CLAMP_TO_EDGE);
  1305. {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
  1306. procedure glBitmapSetDefaultSwizzle(const r: GLenum = GL_RED; g: GLenum = GL_GREEN; b: GLenum = GL_BLUE; a: GLenum = GL_ALPHA);
  1307. {$IFEND}
  1308. function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
  1309. function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
  1310. function glBitmapGetDefaultMipmap: TglBitmapMipMap;
  1311. function glBitmapGetDefaultFormat: TglBitmapFormat;
  1312. procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
  1313. procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
  1314. {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
  1315. procedure glBitmapGetDefaultSwizzle(var r, g, b, a: GLenum);
  1316. {$IFEND}
  1317. function glBitmapSize(X: Integer = -1; Y: Integer = -1): TglBitmapSize;
  1318. function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
  1319. function glBitmapRec4ub(const r, g, b, a: Byte): TglBitmapRec4ub;
  1320. function glBitmapRec4ui(const r, g, b, a: Cardinal): TglBitmapRec4ui;
  1321. function glBitmapRec4ul(const r, g, b, a: QWord): TglBitmapRec4ul;
  1322. function glBitmapRec4ubCompare(const r1, r2: TglBitmapRec4ub): Boolean;
  1323. function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean;
  1324. function glBitmapCreateTestTexture(const aFormat: TglBitmapFormat): TglBitmap2D;
  1325. {$IFDEF GLB_DELPHI}
  1326. function CreateGrayPalette: HPALETTE;
  1327. {$ENDIF}
  1328. implementation
  1329. uses
  1330. Math, syncobjs, typinfo
  1331. {$IF DEFINED(GLB_SUPPORT_JPEG_READ) AND DEFINED(GLB_LAZ_JPEG)}, FPReadJPEG{$IFEND};
  1332. var
  1333. glBitmapDefaultDeleteTextureOnFree: Boolean;
  1334. glBitmapDefaultFreeDataAfterGenTextures: Boolean;
  1335. glBitmapDefaultFormat: TglBitmapFormat;
  1336. glBitmapDefaultMipmap: TglBitmapMipMap;
  1337. glBitmapDefaultFilterMin: Cardinal;
  1338. glBitmapDefaultFilterMag: Cardinal;
  1339. glBitmapDefaultWrapS: Cardinal;
  1340. glBitmapDefaultWrapT: Cardinal;
  1341. glBitmapDefaultWrapR: Cardinal;
  1342. glDefaultSwizzle: array[0..3] of GLenum;
  1343. ////////////////////////////////////////////////////////////////////////////////////////////////////
  1344. type
  1345. TFormatDescriptor = class(TglBitmapFormatDescriptor)
  1346. public
  1347. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); virtual; abstract;
  1348. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract;
  1349. function GetSize(const aSize: TglBitmapSize): Integer; overload; virtual;
  1350. function GetSize(const aWidth, aHeight: Integer): Integer; overload; virtual;
  1351. function CreateMappingData: Pointer; virtual;
  1352. procedure FreeMappingData(var aMappingData: Pointer); virtual;
  1353. function IsEmpty: Boolean; virtual;
  1354. function MaskMatch(const aMask: TglBitmapRec4ul): Boolean; virtual;
  1355. procedure PreparePixel(out aPixel: TglBitmapPixelData); virtual;
  1356. constructor Create; virtual;
  1357. public
  1358. class procedure Init;
  1359. class function Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
  1360. class function GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
  1361. class function GetFromMask(const aMask: TglBitmapRec4ul; const aBitCount: Integer = 0): TFormatDescriptor;
  1362. class function GetFromPrecShift(const aPrec, aShift: TglBitmapRec4ub; const aBitCount: Integer): TFormatDescriptor;
  1363. class procedure Clear;
  1364. class procedure Finalize;
  1365. end;
  1366. TFormatDescriptorClass = class of TFormatDescriptor;
  1367. TfdEmpty = class(TFormatDescriptor);
  1368. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1369. TfdAlphaUB1 = class(TFormatDescriptor) //1* unsigned byte
  1370. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1371. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1372. end;
  1373. TfdLuminanceUB1 = class(TFormatDescriptor) //1* unsigned byte
  1374. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1375. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1376. end;
  1377. TfdUniversalUB1 = class(TFormatDescriptor) //1* unsigned byte
  1378. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1379. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1380. end;
  1381. TfdLuminanceAlphaUB2 = class(TfdLuminanceUB1) //2* unsigned byte
  1382. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1383. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1384. end;
  1385. TfdRGBub3 = class(TFormatDescriptor) //3* unsigned byte
  1386. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1387. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1388. end;
  1389. TfdBGRub3 = class(TFormatDescriptor) //3* unsigned byte (inverse)
  1390. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1391. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1392. end;
  1393. TfdRGBAub4 = class(TfdRGBub3) //3* unsigned byte
  1394. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1395. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1396. end;
  1397. TfdBGRAub4 = class(TfdBGRub3) //3* unsigned byte (inverse)
  1398. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1399. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1400. end;
  1401. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1402. TfdAlphaUS1 = class(TFormatDescriptor) //1* unsigned short
  1403. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1404. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1405. end;
  1406. TfdLuminanceUS1 = class(TFormatDescriptor) //1* unsigned short
  1407. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1408. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1409. end;
  1410. TfdUniversalUS1 = class(TFormatDescriptor) //1* unsigned short
  1411. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1412. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1413. end;
  1414. TfdDepthUS1 = class(TFormatDescriptor) //1* unsigned short
  1415. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1416. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1417. end;
  1418. TfdLuminanceAlphaUS2 = class(TfdLuminanceUS1) //2* unsigned short
  1419. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1420. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1421. end;
  1422. TfdRGBus3 = class(TFormatDescriptor) //3* unsigned short
  1423. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1424. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1425. end;
  1426. TfdBGRus3 = class(TFormatDescriptor) //3* unsigned short (inverse)
  1427. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1428. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1429. end;
  1430. TfdRGBAus4 = class(TfdRGBus3) //4* unsigned short
  1431. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1432. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1433. end;
  1434. TfdARGBus4 = class(TfdRGBus3) //4* unsigned short
  1435. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1436. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1437. end;
  1438. TfdBGRAus4 = class(TfdBGRus3) //4* unsigned short (inverse)
  1439. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1440. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1441. end;
  1442. TfdABGRus4 = class(TfdBGRus3) //4* unsigned short (inverse)
  1443. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1444. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1445. end;
  1446. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1447. TfdUniversalUI1 = class(TFormatDescriptor) //1* unsigned int
  1448. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1449. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1450. end;
  1451. TfdDepthUI1 = class(TFormatDescriptor) //1* unsigned int
  1452. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1453. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1454. end;
  1455. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1456. TfdAlpha4ub1 = class(TfdAlphaUB1)
  1457. procedure SetValues; override;
  1458. end;
  1459. TfdAlpha8ub1 = class(TfdAlphaUB1)
  1460. procedure SetValues; override;
  1461. end;
  1462. TfdAlpha16us1 = class(TfdAlphaUS1)
  1463. procedure SetValues; override;
  1464. end;
  1465. TfdLuminance4ub1 = class(TfdLuminanceUB1)
  1466. procedure SetValues; override;
  1467. end;
  1468. TfdLuminance8ub1 = class(TfdLuminanceUB1)
  1469. procedure SetValues; override;
  1470. end;
  1471. TfdLuminance16us1 = class(TfdLuminanceUS1)
  1472. procedure SetValues; override;
  1473. end;
  1474. TfdLuminance4Alpha4ub2 = class(TfdLuminanceAlphaUB2)
  1475. procedure SetValues; override;
  1476. end;
  1477. TfdLuminance6Alpha2ub2 = class(TfdLuminanceAlphaUB2)
  1478. procedure SetValues; override;
  1479. end;
  1480. TfdLuminance8Alpha8ub2 = class(TfdLuminanceAlphaUB2)
  1481. procedure SetValues; override;
  1482. end;
  1483. TfdLuminance12Alpha4us2 = class(TfdLuminanceAlphaUS2)
  1484. procedure SetValues; override;
  1485. end;
  1486. TfdLuminance16Alpha16us2 = class(TfdLuminanceAlphaUS2)
  1487. procedure SetValues; override;
  1488. end;
  1489. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1490. TfdR3G3B2ub1 = class(TfdUniversalUB1)
  1491. procedure SetValues; override;
  1492. end;
  1493. TfdRGBX4us1 = class(TfdUniversalUS1)
  1494. procedure SetValues; override;
  1495. end;
  1496. TfdXRGB4us1 = class(TfdUniversalUS1)
  1497. procedure SetValues; override;
  1498. end;
  1499. TfdR5G6B5us1 = class(TfdUniversalUS1)
  1500. procedure SetValues; override;
  1501. end;
  1502. TfdRGB5X1us1 = class(TfdUniversalUS1)
  1503. procedure SetValues; override;
  1504. end;
  1505. TfdX1RGB5us1 = class(TfdUniversalUS1)
  1506. procedure SetValues; override;
  1507. end;
  1508. TfdRGB8ub3 = class(TfdRGBub3)
  1509. procedure SetValues; override;
  1510. end;
  1511. TfdRGBX8ui1 = class(TfdUniversalUI1)
  1512. procedure SetValues; override;
  1513. end;
  1514. TfdXRGB8ui1 = class(TfdUniversalUI1)
  1515. procedure SetValues; override;
  1516. end;
  1517. TfdRGB10X2ui1 = class(TfdUniversalUI1)
  1518. procedure SetValues; override;
  1519. end;
  1520. TfdX2RGB10ui1 = class(TfdUniversalUI1)
  1521. procedure SetValues; override;
  1522. end;
  1523. TfdRGB16us3 = class(TfdRGBus3)
  1524. procedure SetValues; override;
  1525. end;
  1526. TfdRGBA4us1 = class(TfdUniversalUS1)
  1527. procedure SetValues; override;
  1528. end;
  1529. TfdARGB4us1 = class(TfdUniversalUS1)
  1530. procedure SetValues; override;
  1531. end;
  1532. TfdRGB5A1us1 = class(TfdUniversalUS1)
  1533. procedure SetValues; override;
  1534. end;
  1535. TfdA1RGB5us1 = class(TfdUniversalUS1)
  1536. procedure SetValues; override;
  1537. end;
  1538. TfdRGBA8ui1 = class(TfdUniversalUI1)
  1539. procedure SetValues; override;
  1540. end;
  1541. TfdARGB8ui1 = class(TfdUniversalUI1)
  1542. procedure SetValues; override;
  1543. end;
  1544. TfdRGBA8ub4 = class(TfdRGBAub4)
  1545. procedure SetValues; override;
  1546. end;
  1547. TfdRGB10A2ui1 = class(TfdUniversalUI1)
  1548. procedure SetValues; override;
  1549. end;
  1550. TfdA2RGB10ui1 = class(TfdUniversalUI1)
  1551. procedure SetValues; override;
  1552. end;
  1553. TfdRGBA16us4 = class(TfdRGBAus4)
  1554. procedure SetValues; override;
  1555. end;
  1556. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1557. TfdBGRX4us1 = class(TfdUniversalUS1)
  1558. procedure SetValues; override;
  1559. end;
  1560. TfdXBGR4us1 = class(TfdUniversalUS1)
  1561. procedure SetValues; override;
  1562. end;
  1563. TfdB5G6R5us1 = class(TfdUniversalUS1)
  1564. procedure SetValues; override;
  1565. end;
  1566. TfdBGR5X1us1 = class(TfdUniversalUS1)
  1567. procedure SetValues; override;
  1568. end;
  1569. TfdX1BGR5us1 = class(TfdUniversalUS1)
  1570. procedure SetValues; override;
  1571. end;
  1572. TfdBGR8ub3 = class(TfdBGRub3)
  1573. procedure SetValues; override;
  1574. end;
  1575. TfdBGRX8ui1 = class(TfdUniversalUI1)
  1576. procedure SetValues; override;
  1577. end;
  1578. TfdXBGR8ui1 = class(TfdUniversalUI1)
  1579. procedure SetValues; override;
  1580. end;
  1581. TfdBGR10X2ui1 = class(TfdUniversalUI1)
  1582. procedure SetValues; override;
  1583. end;
  1584. TfdX2BGR10ui1 = class(TfdUniversalUI1)
  1585. procedure SetValues; override;
  1586. end;
  1587. TfdBGR16us3 = class(TfdBGRus3)
  1588. procedure SetValues; override;
  1589. end;
  1590. TfdBGRA4us1 = class(TfdUniversalUS1)
  1591. procedure SetValues; override;
  1592. end;
  1593. TfdABGR4us1 = class(TfdUniversalUS1)
  1594. procedure SetValues; override;
  1595. end;
  1596. TfdBGR5A1us1 = class(TfdUniversalUS1)
  1597. procedure SetValues; override;
  1598. end;
  1599. TfdA1BGR5us1 = class(TfdUniversalUS1)
  1600. procedure SetValues; override;
  1601. end;
  1602. TfdBGRA8ui1 = class(TfdUniversalUI1)
  1603. procedure SetValues; override;
  1604. end;
  1605. TfdABGR8ui1 = class(TfdUniversalUI1)
  1606. procedure SetValues; override;
  1607. end;
  1608. TfdBGRA8ub4 = class(TfdBGRAub4)
  1609. procedure SetValues; override;
  1610. end;
  1611. TfdBGR10A2ui1 = class(TfdUniversalUI1)
  1612. procedure SetValues; override;
  1613. end;
  1614. TfdA2BGR10ui1 = class(TfdUniversalUI1)
  1615. procedure SetValues; override;
  1616. end;
  1617. TfdBGRA16us4 = class(TfdBGRAus4)
  1618. procedure SetValues; override;
  1619. end;
  1620. TfdDepth16us1 = class(TfdDepthUS1)
  1621. procedure SetValues; override;
  1622. end;
  1623. TfdDepth24ui1 = class(TfdDepthUI1)
  1624. procedure SetValues; override;
  1625. end;
  1626. TfdDepth32ui1 = class(TfdDepthUI1)
  1627. procedure SetValues; override;
  1628. end;
  1629. TfdS3tcDtx1RGBA = class(TFormatDescriptor)
  1630. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1631. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1632. procedure SetValues; override;
  1633. end;
  1634. TfdS3tcDtx3RGBA = class(TFormatDescriptor)
  1635. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1636. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1637. procedure SetValues; override;
  1638. end;
  1639. TfdS3tcDtx5RGBA = class(TFormatDescriptor)
  1640. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1641. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1642. procedure SetValues; override;
  1643. end;
  1644. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1645. TbmpBitfieldFormat = class(TFormatDescriptor)
  1646. public
  1647. procedure SetCustomValues(const aBPP: Integer; aMask: TglBitmapRec4ul); overload;
  1648. procedure SetCustomValues(const aBBP: Integer; const aPrec, aShift: TglBitmapRec4ub); overload;
  1649. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1650. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1651. end;
  1652. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1653. TbmpColorTableEnty = packed record
  1654. b, g, r, a: Byte;
  1655. end;
  1656. TbmpColorTable = array of TbmpColorTableEnty;
  1657. TbmpColorTableFormat = class(TFormatDescriptor)
  1658. private
  1659. fBitsPerPixel: Integer;
  1660. fColorTable: TbmpColorTable;
  1661. protected
  1662. procedure SetValues; override;
  1663. public
  1664. property ColorTable: TbmpColorTable read fColorTable write fColorTable;
  1665. property BitsPerPixel: Integer read fBitsPerPixel write fBitsPerPixel;
  1666. procedure SetCustomValues(const aFormat: TglBitmapFormat; const aBPP: Integer; const aPrec, aShift: TglBitmapRec4ub); overload;
  1667. procedure CalcValues;
  1668. procedure CreateColorTable;
  1669. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1670. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1671. destructor Destroy; override;
  1672. end;
  1673. const
  1674. LUMINANCE_WEIGHT_R = 0.30;
  1675. LUMINANCE_WEIGHT_G = 0.59;
  1676. LUMINANCE_WEIGHT_B = 0.11;
  1677. ALPHA_WEIGHT_R = 0.30;
  1678. ALPHA_WEIGHT_G = 0.59;
  1679. ALPHA_WEIGHT_B = 0.11;
  1680. DEPTH_WEIGHT_R = 0.333333333;
  1681. DEPTH_WEIGHT_G = 0.333333333;
  1682. DEPTH_WEIGHT_B = 0.333333333;
  1683. FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
  1684. TfdEmpty,
  1685. TfdAlpha4ub1,
  1686. TfdAlpha8ub1,
  1687. TfdAlpha16us1,
  1688. TfdLuminance4ub1,
  1689. TfdLuminance8ub1,
  1690. TfdLuminance16us1,
  1691. TfdLuminance4Alpha4ub2,
  1692. TfdLuminance6Alpha2ub2,
  1693. TfdLuminance8Alpha8ub2,
  1694. TfdLuminance12Alpha4us2,
  1695. TfdLuminance16Alpha16us2,
  1696. TfdR3G3B2ub1,
  1697. TfdRGBX4us1,
  1698. TfdXRGB4us1,
  1699. TfdR5G6B5us1,
  1700. TfdRGB5X1us1,
  1701. TfdX1RGB5us1,
  1702. TfdRGB8ub3,
  1703. TfdRGBX8ui1,
  1704. TfdXRGB8ui1,
  1705. TfdRGB10X2ui1,
  1706. TfdX2RGB10ui1,
  1707. TfdRGB16us3,
  1708. TfdRGBA4us1,
  1709. TfdARGB4us1,
  1710. TfdRGB5A1us1,
  1711. TfdA1RGB5us1,
  1712. TfdRGBA8ui1,
  1713. TfdARGB8ui1,
  1714. TfdRGBA8ub4,
  1715. TfdRGB10A2ui1,
  1716. TfdA2RGB10ui1,
  1717. TfdRGBA16us4,
  1718. TfdBGRX4us1,
  1719. TfdXBGR4us1,
  1720. TfdB5G6R5us1,
  1721. TfdBGR5X1us1,
  1722. TfdX1BGR5us1,
  1723. TfdBGR8ub3,
  1724. TfdBGRX8ui1,
  1725. TfdXBGR8ui1,
  1726. TfdBGR10X2ui1,
  1727. TfdX2BGR10ui1,
  1728. TfdBGR16us3,
  1729. TfdBGRA4us1,
  1730. TfdABGR4us1,
  1731. TfdBGR5A1us1,
  1732. TfdA1BGR5us1,
  1733. TfdBGRA8ui1,
  1734. TfdABGR8ui1,
  1735. TfdBGRA8ub4,
  1736. TfdBGR10A2ui1,
  1737. TfdA2BGR10ui1,
  1738. TfdBGRA16us4,
  1739. TfdDepth16us1,
  1740. TfdDepth24ui1,
  1741. TfdDepth32ui1,
  1742. TfdS3tcDtx1RGBA,
  1743. TfdS3tcDtx3RGBA,
  1744. TfdS3tcDtx5RGBA
  1745. );
  1746. var
  1747. FormatDescriptorCS: TCriticalSection;
  1748. FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
  1749. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1750. constructor EglBitmapUnsupportedFormat.Create(const aFormat: TglBitmapFormat);
  1751. begin
  1752. inherited Create('unsupported format: ' + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
  1753. end;
  1754. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1755. constructor EglBitmapUnsupportedFormat.Create(const aMsg: String; const aFormat: TglBitmapFormat);
  1756. begin
  1757. inherited Create(aMsg + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
  1758. end;
  1759. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1760. function glBitmapSize(X: Integer; Y: Integer): TglBitmapSize;
  1761. begin
  1762. result.Fields := [];
  1763. if (X >= 0) then
  1764. result.Fields := result.Fields + [ffX];
  1765. if (Y >= 0) then
  1766. result.Fields := result.Fields + [ffY];
  1767. result.X := Max(0, X);
  1768. result.Y := Max(0, Y);
  1769. end;
  1770. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1771. function glBitmapPosition(X: Integer; Y: Integer): TglBitmapPixelPosition;
  1772. begin
  1773. result := glBitmapSize(X, Y);
  1774. end;
  1775. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1776. function glBitmapRec4ub(const r, g, b, a: Byte): TglBitmapRec4ub;
  1777. begin
  1778. result.r := r;
  1779. result.g := g;
  1780. result.b := b;
  1781. result.a := a;
  1782. end;
  1783. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1784. function glBitmapRec4ui(const r, g, b, a: Cardinal): TglBitmapRec4ui;
  1785. begin
  1786. result.r := r;
  1787. result.g := g;
  1788. result.b := b;
  1789. result.a := a;
  1790. end;
  1791. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1792. function glBitmapRec4ul(const r, g, b, a: QWord): TglBitmapRec4ul;
  1793. begin
  1794. result.r := r;
  1795. result.g := g;
  1796. result.b := b;
  1797. result.a := a;
  1798. end;
  1799. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1800. function glBitmapRec4ubCompare(const r1, r2: TglBitmapRec4ub): Boolean;
  1801. var
  1802. i: Integer;
  1803. begin
  1804. result := false;
  1805. for i := 0 to high(r1.arr) do
  1806. if (r1.arr[i] <> r2.arr[i]) then
  1807. exit;
  1808. result := true;
  1809. end;
  1810. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1811. function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean;
  1812. var
  1813. i: Integer;
  1814. begin
  1815. result := false;
  1816. for i := 0 to high(r1.arr) do
  1817. if (r1.arr[i] <> r2.arr[i]) then
  1818. exit;
  1819. result := true;
  1820. end;
  1821. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1822. function glBitmapCreateTestTexture(const aFormat: TglBitmapFormat): TglBitmap2D;
  1823. var
  1824. desc: TFormatDescriptor;
  1825. p, tmp: PByte;
  1826. x, y, i: Integer;
  1827. md: Pointer;
  1828. px: TglBitmapPixelData;
  1829. begin
  1830. result := nil;
  1831. desc := TFormatDescriptor.Get(aFormat);
  1832. if (desc.IsCompressed) or (desc.glFormat = 0) then
  1833. exit;
  1834. p := GetMemory(ceil(25 * desc.BytesPerPixel)); // 5 x 5 pixel
  1835. md := desc.CreateMappingData;
  1836. try
  1837. tmp := p;
  1838. desc.PreparePixel(px);
  1839. for y := 0 to 4 do
  1840. for x := 0 to 4 do begin
  1841. px.Data := glBitmapRec4ui(0, 0, 0, 0);
  1842. for i := 0 to 3 do begin
  1843. if ((y < 3) and (y = i)) or
  1844. ((y = 3) and (i < 3)) or
  1845. ((y = 4) and (i = 3))
  1846. then
  1847. px.Data.arr[i] := Trunc(px.Range.arr[i] / 4 * x)
  1848. else if ((y < 4) and (i = 3)) or
  1849. ((y = 4) and (i < 3))
  1850. then
  1851. px.Data.arr[i] := px.Range.arr[i]
  1852. else
  1853. px.Data.arr[i] := 0; //px.Range.arr[i];
  1854. end;
  1855. desc.Map(px, tmp, md);
  1856. end;
  1857. finally
  1858. desc.FreeMappingData(md);
  1859. end;
  1860. result := TglBitmap2D.Create(glBitmapPosition(5, 5), aFormat, p);
  1861. result.FreeDataOnDestroy := true;
  1862. result.FreeDataAfterGenTexture := false;
  1863. result.SetFilter(GL_NEAREST, GL_NEAREST);
  1864. end;
  1865. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1866. function glBitmapShiftRec(const r, g, b, a: Byte): TglBitmapRec4ub;
  1867. begin
  1868. result.r := r;
  1869. result.g := g;
  1870. result.b := b;
  1871. result.a := a;
  1872. end;
  1873. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1874. function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
  1875. begin
  1876. result := [];
  1877. if (aFormat in [
  1878. //8bpp
  1879. tfAlpha4ub1, tfAlpha8ub1,
  1880. tfLuminance4ub1, tfLuminance8ub1, tfR3G3B2ub1,
  1881. //16bpp
  1882. tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
  1883. tfRGBX4us1, tfXRGB4us1, tfRGB5X1us1, tfX1RGB5us1, tfR5G6B5us1, tfRGB5A1us1, tfA1RGB5us1, tfRGBA4us1, tfARGB4us1,
  1884. tfBGRX4us1, tfXBGR4us1, tfBGR5X1us1, tfX1BGR5us1, tfB5G6R5us1, tfBGR5A1us1, tfA1BGR5us1, tfBGRA4us1, tfABGR4us1,
  1885. //24bpp
  1886. tfBGR8ub3, tfRGB8ub3,
  1887. //32bpp
  1888. tfRGBX8ui1, tfXRGB8ui1, tfRGB10X2ui1, tfX2RGB10ui1, tfRGBA8ui1, tfARGB8ui1, tfRGBA8ub4, tfRGB10A2ui1, tfA2RGB10ui1,
  1889. tfBGRX8ui1, tfXBGR8ui1, tfBGR10X2ui1, tfX2BGR10ui1, tfBGRA8ui1, tfABGR8ui1, tfBGRA8ub4, tfBGR10A2ui1, tfA2BGR10ui1])
  1890. then
  1891. result := result + [ ftBMP ];
  1892. if (aFormat in [
  1893. //8bbp
  1894. tfAlpha4ub1, tfAlpha8ub1, tfLuminance4ub1, tfLuminance8ub1,
  1895. //16bbp
  1896. tfAlpha16us1, tfLuminance16us1,
  1897. tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
  1898. tfX1RGB5us1, tfARGB4us1, tfA1RGB5us1, tfDepth16us1,
  1899. //24bbp
  1900. tfBGR8ub3,
  1901. //32bbp
  1902. tfX2RGB10ui1, tfARGB8ui1, tfBGRA8ub4, tfA2RGB10ui1,
  1903. tfDepth24ui1, tfDepth32ui1])
  1904. then
  1905. result := result + [ftTGA];
  1906. if not (aFormat in [tfEmpty, tfRGB16us3, tfBGR16us3]) then
  1907. result := result + [ftDDS];
  1908. {$IFDEF GLB_SUPPORT_PNG_WRITE}
  1909. if aFormat in [
  1910. tfAlpha8ub1, tfLuminance8ub1, tfLuminance8Alpha8ub2,
  1911. tfRGB8ub3, tfRGBA8ui1,
  1912. tfBGR8ub3, tfBGRA8ui1] then
  1913. result := result + [ftPNG];
  1914. {$ENDIF}
  1915. {$IFDEF GLB_SUPPORT_JPEG_WRITE}
  1916. if aFormat in [tfAlpha8ub1, tfLuminance8ub1, tfRGB8ub3, tfBGR8ub3] then
  1917. result := result + [ftJPEG];
  1918. {$ENDIF}
  1919. end;
  1920. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1921. function IsPowerOfTwo(aNumber: Integer): Boolean;
  1922. begin
  1923. while (aNumber and 1) = 0 do
  1924. aNumber := aNumber shr 1;
  1925. result := aNumber = 1;
  1926. end;
  1927. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1928. function GetTopMostBit(aBitSet: QWord): Integer;
  1929. begin
  1930. result := 0;
  1931. while aBitSet > 0 do begin
  1932. inc(result);
  1933. aBitSet := aBitSet shr 1;
  1934. end;
  1935. end;
  1936. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1937. function CountSetBits(aBitSet: QWord): Integer;
  1938. begin
  1939. result := 0;
  1940. while aBitSet > 0 do begin
  1941. if (aBitSet and 1) = 1 then
  1942. inc(result);
  1943. aBitSet := aBitSet shr 1;
  1944. end;
  1945. end;
  1946. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1947. function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
  1948. begin
  1949. result := Trunc(
  1950. LUMINANCE_WEIGHT_R * aPixel.Data.r +
  1951. LUMINANCE_WEIGHT_G * aPixel.Data.g +
  1952. LUMINANCE_WEIGHT_B * aPixel.Data.b);
  1953. end;
  1954. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1955. function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
  1956. begin
  1957. result := Trunc(
  1958. DEPTH_WEIGHT_R * aPixel.Data.r +
  1959. DEPTH_WEIGHT_G * aPixel.Data.g +
  1960. DEPTH_WEIGHT_B * aPixel.Data.b);
  1961. end;
  1962. {$IFDEF GLB_NATIVE_OGL}
  1963. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1964. //OpenGLInitialization///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1965. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1966. var
  1967. GL_LibHandle: Pointer = nil;
  1968. function glbGetProcAddress(aProcName: PAnsiChar; aLibHandle: Pointer = nil; const aRaiseOnErr: Boolean = true): Pointer;
  1969. begin
  1970. if not Assigned(aLibHandle) then
  1971. aLibHandle := GL_LibHandle;
  1972. {$IF DEFINED(GLB_WIN)}
  1973. result := GetProcAddress({%H-}HMODULE(aLibHandle), aProcName);
  1974. if Assigned(result) then
  1975. exit;
  1976. if Assigned(wglGetProcAddress) then
  1977. result := wglGetProcAddress(aProcName);
  1978. {$ELSEIF DEFINED(GLB_LINUX)}
  1979. if Assigned(glXGetProcAddress) then begin
  1980. result := glXGetProcAddress(aProcName);
  1981. if Assigned(result) then
  1982. exit;
  1983. end;
  1984. if Assigned(glXGetProcAddressARB) then begin
  1985. result := glXGetProcAddressARB(aProcName);
  1986. if Assigned(result) then
  1987. exit;
  1988. end;
  1989. result := dlsym(aLibHandle, aProcName);
  1990. {$IFEND}
  1991. if not Assigned(result) and aRaiseOnErr then
  1992. raise EglBitmap.Create('unable to load procedure form library: ' + aProcName);
  1993. end;
  1994. {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
  1995. var
  1996. GLU_LibHandle: Pointer = nil;
  1997. OpenGLInitialized: Boolean;
  1998. InitOpenGLCS: TCriticalSection;
  1999. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2000. procedure glbInitOpenGL;
  2001. ////////////////////////////////////////////////////////////////////////////////
  2002. function glbLoadLibrary(const aName: PChar): Pointer;
  2003. begin
  2004. {$IF DEFINED(GLB_WIN)}
  2005. result := {%H-}Pointer(LoadLibrary(aName));
  2006. {$ELSEIF DEFINED(GLB_LINUX)}
  2007. result := dlopen(Name, RTLD_LAZY);
  2008. {$ELSE}
  2009. result := nil;
  2010. {$IFEND}
  2011. end;
  2012. ////////////////////////////////////////////////////////////////////////////////
  2013. function glbFreeLibrary(const aLibHandle: Pointer): Boolean;
  2014. begin
  2015. result := false;
  2016. if not Assigned(aLibHandle) then
  2017. exit;
  2018. {$IF DEFINED(GLB_WIN)}
  2019. Result := FreeLibrary({%H-}HINST(aLibHandle));
  2020. {$ELSEIF DEFINED(GLB_LINUX)}
  2021. Result := dlclose(aLibHandle) = 0;
  2022. {$IFEND}
  2023. end;
  2024. begin
  2025. if Assigned(GL_LibHandle) then
  2026. glbFreeLibrary(GL_LibHandle);
  2027. if Assigned(GLU_LibHandle) then
  2028. glbFreeLibrary(GLU_LibHandle);
  2029. GL_LibHandle := glbLoadLibrary(libopengl);
  2030. if not Assigned(GL_LibHandle) then
  2031. raise EglBitmap.Create('unable to load library: ' + libopengl);
  2032. GLU_LibHandle := glbLoadLibrary(libglu);
  2033. if not Assigned(GLU_LibHandle) then
  2034. raise EglBitmap.Create('unable to load library: ' + libglu);
  2035. {$IF DEFINED(GLB_WIN)}
  2036. wglGetProcAddress := glbGetProcAddress('wglGetProcAddress');
  2037. {$ELSEIF DEFINED(GLB_LINUX)}
  2038. glXGetProcAddress := glbGetProcAddress('glXGetProcAddress');
  2039. glXGetProcAddressARB := glbGetProcAddress('glXGetProcAddressARB');
  2040. {$IFEND}
  2041. glEnable := glbGetProcAddress('glEnable');
  2042. glDisable := glbGetProcAddress('glDisable');
  2043. glGetString := glbGetProcAddress('glGetString');
  2044. glGetIntegerv := glbGetProcAddress('glGetIntegerv');
  2045. glTexParameteri := glbGetProcAddress('glTexParameteri');
  2046. glTexParameteriv := glbGetProcAddress('glTexParameteriv');
  2047. glTexParameterfv := glbGetProcAddress('glTexParameterfv');
  2048. glGetTexParameteriv := glbGetProcAddress('glGetTexParameteriv');
  2049. glGetTexParameterfv := glbGetProcAddress('glGetTexParameterfv');
  2050. glGetTexLevelParameteriv := glbGetProcAddress('glGetTexLevelParameteriv');
  2051. glGetTexLevelParameterfv := glbGetProcAddress('glGetTexLevelParameterfv');
  2052. glTexGeni := glbGetProcAddress('glTexGeni');
  2053. glGenTextures := glbGetProcAddress('glGenTextures');
  2054. glBindTexture := glbGetProcAddress('glBindTexture');
  2055. glDeleteTextures := glbGetProcAddress('glDeleteTextures');
  2056. glAreTexturesResident := glbGetProcAddress('glAreTexturesResident');
  2057. glReadPixels := glbGetProcAddress('glReadPixels');
  2058. glPixelStorei := glbGetProcAddress('glPixelStorei');
  2059. glTexImage1D := glbGetProcAddress('glTexImage1D');
  2060. glTexImage2D := glbGetProcAddress('glTexImage2D');
  2061. glGetTexImage := glbGetProcAddress('glGetTexImage');
  2062. gluBuild1DMipmaps := glbGetProcAddress('gluBuild1DMipmaps', GLU_LibHandle);
  2063. gluBuild2DMipmaps := glbGetProcAddress('gluBuild2DMipmaps', GLU_LibHandle);
  2064. end;
  2065. {$ENDIF}
  2066. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2067. procedure glbReadOpenGLExtensions;
  2068. var
  2069. Buffer: AnsiString;
  2070. MajorVersion, MinorVersion: Integer;
  2071. ///////////////////////////////////////////////////////////////////////////////////////////
  2072. procedure TrimVersionString(aBuffer: AnsiString; out aMajor, aMinor: Integer);
  2073. var
  2074. Separator: Integer;
  2075. begin
  2076. aMinor := 0;
  2077. aMajor := 0;
  2078. Separator := Pos(AnsiString('.'), aBuffer);
  2079. if (Separator > 1) and (Separator < Length(aBuffer)) and
  2080. (aBuffer[Separator - 1] in ['0'..'9']) and
  2081. (aBuffer[Separator + 1] in ['0'..'9']) then begin
  2082. Dec(Separator);
  2083. while (Separator > 0) and (aBuffer[Separator] in ['0'..'9']) do
  2084. Dec(Separator);
  2085. Delete(aBuffer, 1, Separator);
  2086. Separator := Pos(AnsiString('.'), aBuffer) + 1;
  2087. while (Separator <= Length(aBuffer)) and (AnsiChar(aBuffer[Separator]) in ['0'..'9']) do
  2088. Inc(Separator);
  2089. Delete(aBuffer, Separator, 255);
  2090. Separator := Pos(AnsiString('.'), aBuffer);
  2091. aMajor := StrToInt(Copy(String(aBuffer), 1, Separator - 1));
  2092. aMinor := StrToInt(Copy(String(aBuffer), Separator + 1, 1));
  2093. end;
  2094. end;
  2095. ///////////////////////////////////////////////////////////////////////////////////////////
  2096. function CheckExtension(const Extension: AnsiString): Boolean;
  2097. var
  2098. ExtPos: Integer;
  2099. begin
  2100. ExtPos := Pos(Extension, Buffer);
  2101. result := ExtPos > 0;
  2102. if result then
  2103. result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
  2104. end;
  2105. ///////////////////////////////////////////////////////////////////////////////////////////
  2106. function CheckVersion(const aMajor, aMinor: Integer): Boolean;
  2107. begin
  2108. result := (MajorVersion > aMajor) or ((MajorVersion = aMajor) and (MinorVersion >= aMinor));
  2109. end;
  2110. begin
  2111. {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
  2112. InitOpenGLCS.Enter;
  2113. try
  2114. if not OpenGLInitialized then begin
  2115. glbInitOpenGL;
  2116. OpenGLInitialized := true;
  2117. end;
  2118. finally
  2119. InitOpenGLCS.Leave;
  2120. end;
  2121. {$ENDIF}
  2122. // Version
  2123. Buffer := glGetString(GL_VERSION);
  2124. TrimVersionString(Buffer, MajorVersion, MinorVersion);
  2125. GL_VERSION_1_2 := CheckVersion(1, 2);
  2126. GL_VERSION_1_3 := CheckVersion(1, 3);
  2127. GL_VERSION_1_4 := CheckVersion(1, 4);
  2128. GL_VERSION_2_0 := CheckVersion(2, 0);
  2129. GL_VERSION_3_3 := CheckVersion(3, 3);
  2130. // Extensions
  2131. Buffer := glGetString(GL_EXTENSIONS);
  2132. GL_ARB_texture_border_clamp := CheckExtension('GL_ARB_texture_border_clamp');
  2133. GL_ARB_texture_non_power_of_two := CheckExtension('GL_ARB_texture_non_power_of_two');
  2134. GL_ARB_texture_swizzle := CheckExtension('GL_ARB_texture_swizzle');
  2135. GL_ARB_texture_cube_map := CheckExtension('GL_ARB_texture_cube_map');
  2136. GL_ARB_texture_rectangle := CheckExtension('GL_ARB_texture_rectangle');
  2137. GL_ARB_texture_mirrored_repeat := CheckExtension('GL_ARB_texture_mirrored_repeat');
  2138. GL_EXT_texture_edge_clamp := CheckExtension('GL_EXT_texture_edge_clamp');
  2139. GL_EXT_texture_filter_anisotropic := CheckExtension('GL_EXT_texture_filter_anisotropic');
  2140. GL_EXT_texture_rectangle := CheckExtension('GL_EXT_texture_rectangle');
  2141. GL_EXT_texture_swizzle := CheckExtension('GL_EXT_texture_swizzle');
  2142. GL_EXT_texture_cube_map := CheckExtension('GL_EXT_texture_cube_map');
  2143. GL_NV_texture_rectangle := CheckExtension('GL_NV_texture_rectangle');
  2144. GL_IBM_texture_mirrored_repeat := CheckExtension('GL_IBM_texture_mirrored_repeat');
  2145. GL_SGIS_generate_mipmap := CheckExtension('GL_SGIS_generate_mipmap');
  2146. if GL_VERSION_1_3 then begin
  2147. glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1D');
  2148. glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2D');
  2149. glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImage');
  2150. end else begin
  2151. glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1DARB', nil, false);
  2152. glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2DARB', nil, false);
  2153. glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImageARB', nil, false);
  2154. end;
  2155. end;
  2156. {$ENDIF}
  2157. {$IFDEF GLB_SDL_IMAGE}
  2158. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2159. // SDL Image Helper /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2160. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2161. function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
  2162. begin
  2163. result := TStream(context^.unknown.data1).Seek(offset, whence);
  2164. end;
  2165. function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
  2166. begin
  2167. result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
  2168. end;
  2169. function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
  2170. begin
  2171. result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
  2172. end;
  2173. function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
  2174. begin
  2175. result := 0;
  2176. end;
  2177. function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
  2178. begin
  2179. result := SDL_AllocRW;
  2180. if result = nil then
  2181. raise EglBitmap.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
  2182. result^.seek := glBitmapRWseek;
  2183. result^.read := glBitmapRWread;
  2184. result^.write := glBitmapRWwrite;
  2185. result^.close := glBitmapRWclose;
  2186. result^.unknown.data1 := Stream;
  2187. end;
  2188. {$ENDIF}
  2189. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2190. procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
  2191. begin
  2192. glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
  2193. end;
  2194. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2195. procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
  2196. begin
  2197. glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
  2198. end;
  2199. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2200. procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
  2201. begin
  2202. glBitmapDefaultMipmap := aValue;
  2203. end;
  2204. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2205. procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
  2206. begin
  2207. glBitmapDefaultFormat := aFormat;
  2208. end;
  2209. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2210. procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
  2211. begin
  2212. glBitmapDefaultFilterMin := aMin;
  2213. glBitmapDefaultFilterMag := aMag;
  2214. end;
  2215. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2216. procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
  2217. begin
  2218. glBitmapDefaultWrapS := S;
  2219. glBitmapDefaultWrapT := T;
  2220. glBitmapDefaultWrapR := R;
  2221. end;
  2222. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2223. {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
  2224. procedure glBitmapSetDefaultSwizzle(const r: GLenum = GL_RED; g: GLenum = GL_GREEN; b: GLenum = GL_BLUE; a: GLenum = GL_ALPHA);
  2225. begin
  2226. glDefaultSwizzle[0] := r;
  2227. glDefaultSwizzle[1] := g;
  2228. glDefaultSwizzle[2] := b;
  2229. glDefaultSwizzle[3] := a;
  2230. end;
  2231. {$IFEND}
  2232. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2233. function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
  2234. begin
  2235. result := glBitmapDefaultDeleteTextureOnFree;
  2236. end;
  2237. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2238. function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
  2239. begin
  2240. result := glBitmapDefaultFreeDataAfterGenTextures;
  2241. end;
  2242. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2243. function glBitmapGetDefaultMipmap: TglBitmapMipMap;
  2244. begin
  2245. result := glBitmapDefaultMipmap;
  2246. end;
  2247. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2248. function glBitmapGetDefaultFormat: TglBitmapFormat;
  2249. begin
  2250. result := glBitmapDefaultFormat;
  2251. end;
  2252. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2253. procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
  2254. begin
  2255. aMin := glBitmapDefaultFilterMin;
  2256. aMag := glBitmapDefaultFilterMag;
  2257. end;
  2258. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2259. procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
  2260. begin
  2261. S := glBitmapDefaultWrapS;
  2262. T := glBitmapDefaultWrapT;
  2263. R := glBitmapDefaultWrapR;
  2264. end;
  2265. {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
  2266. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2267. procedure glBitmapGetDefaultSwizzle(var r, g, b, a: GLenum);
  2268. begin
  2269. r := glDefaultSwizzle[0];
  2270. g := glDefaultSwizzle[1];
  2271. b := glDefaultSwizzle[2];
  2272. a := glDefaultSwizzle[3];
  2273. end;
  2274. {$ENDIF}
  2275. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2276. //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2277. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2278. function TFormatDescriptor.GetSize(const aSize: TglBitmapSize): Integer;
  2279. var
  2280. w, h: Integer;
  2281. begin
  2282. if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
  2283. w := Max(1, aSize.X);
  2284. h := Max(1, aSize.Y);
  2285. result := GetSize(w, h);
  2286. end else
  2287. result := 0;
  2288. end;
  2289. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2290. function TFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer;
  2291. begin
  2292. result := 0;
  2293. if (aWidth <= 0) or (aHeight <= 0) then
  2294. exit;
  2295. result := Ceil(aWidth * aHeight * BytesPerPixel);
  2296. end;
  2297. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2298. function TFormatDescriptor.CreateMappingData: Pointer;
  2299. begin
  2300. result := nil;
  2301. end;
  2302. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2303. procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
  2304. begin
  2305. //DUMMY
  2306. end;
  2307. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2308. function TFormatDescriptor.IsEmpty: Boolean;
  2309. begin
  2310. result := (fFormat = tfEmpty);
  2311. end;
  2312. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2313. function TFormatDescriptor.MaskMatch(const aMask: TglBitmapRec4ul): Boolean;
  2314. var
  2315. i: Integer;
  2316. m: TglBitmapRec4ul;
  2317. begin
  2318. result := false;
  2319. if (aMask.r = 0) and (aMask.g = 0) and (aMask.b = 0) and (aMask.a = 0) then
  2320. raise EglBitmap.Create('FormatCheckFormat - All Masks are 0');
  2321. m := Mask;
  2322. for i := 0 to 3 do
  2323. if (aMask.arr[i] <> m.arr[i]) then
  2324. exit;
  2325. result := true;
  2326. end;
  2327. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2328. procedure TFormatDescriptor.PreparePixel(out aPixel: TglBitmapPixelData);
  2329. begin
  2330. FillChar(aPixel{%H-}, SizeOf(aPixel), 0);
  2331. aPixel.Data := Range;
  2332. aPixel.Format := fFormat;
  2333. aPixel.Range := Range;
  2334. end;
  2335. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2336. constructor TFormatDescriptor.Create;
  2337. begin
  2338. inherited Create;
  2339. end;
  2340. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2341. //TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2342. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2343. procedure TfdAlphaUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2344. begin
  2345. aData^ := aPixel.Data.a;
  2346. inc(aData);
  2347. end;
  2348. procedure TfdAlphaUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2349. begin
  2350. aPixel.Data.r := 0;
  2351. aPixel.Data.g := 0;
  2352. aPixel.Data.b := 0;
  2353. aPixel.Data.a := aData^;
  2354. inc(aData);
  2355. end;
  2356. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2357. //TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2358. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2359. procedure TfdLuminanceUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2360. begin
  2361. aData^ := LuminanceWeight(aPixel);
  2362. inc(aData);
  2363. end;
  2364. procedure TfdLuminanceUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2365. begin
  2366. aPixel.Data.r := aData^;
  2367. aPixel.Data.g := aData^;
  2368. aPixel.Data.b := aData^;
  2369. aPixel.Data.a := 0;
  2370. inc(aData);
  2371. end;
  2372. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2373. //TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2374. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2375. procedure TfdUniversalUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2376. var
  2377. i: Integer;
  2378. begin
  2379. aData^ := 0;
  2380. for i := 0 to 3 do
  2381. if (Range.arr[i] > 0) then
  2382. aData^ := aData^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
  2383. inc(aData);
  2384. end;
  2385. procedure TfdUniversalUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2386. var
  2387. i: Integer;
  2388. begin
  2389. for i := 0 to 3 do
  2390. aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and Range.arr[i];
  2391. inc(aData);
  2392. end;
  2393. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2394. //TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2395. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2396. procedure TfdLuminanceAlphaUB2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2397. begin
  2398. inherited Map(aPixel, aData, aMapData);
  2399. aData^ := aPixel.Data.a;
  2400. inc(aData);
  2401. end;
  2402. procedure TfdLuminanceAlphaUB2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2403. begin
  2404. inherited Unmap(aData, aPixel, aMapData);
  2405. aPixel.Data.a := aData^;
  2406. inc(aData);
  2407. end;
  2408. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2409. //TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2410. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2411. procedure TfdRGBub3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2412. begin
  2413. aData^ := aPixel.Data.r;
  2414. inc(aData);
  2415. aData^ := aPixel.Data.g;
  2416. inc(aData);
  2417. aData^ := aPixel.Data.b;
  2418. inc(aData);
  2419. end;
  2420. procedure TfdRGBub3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2421. begin
  2422. aPixel.Data.r := aData^;
  2423. inc(aData);
  2424. aPixel.Data.g := aData^;
  2425. inc(aData);
  2426. aPixel.Data.b := aData^;
  2427. inc(aData);
  2428. aPixel.Data.a := 0;
  2429. end;
  2430. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2431. //TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2432. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2433. procedure TfdBGRub3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2434. begin
  2435. aData^ := aPixel.Data.b;
  2436. inc(aData);
  2437. aData^ := aPixel.Data.g;
  2438. inc(aData);
  2439. aData^ := aPixel.Data.r;
  2440. inc(aData);
  2441. end;
  2442. procedure TfdBGRub3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2443. begin
  2444. aPixel.Data.b := aData^;
  2445. inc(aData);
  2446. aPixel.Data.g := aData^;
  2447. inc(aData);
  2448. aPixel.Data.r := aData^;
  2449. inc(aData);
  2450. aPixel.Data.a := 0;
  2451. end;
  2452. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2453. //TfdRGBA_UB4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2454. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2455. procedure TfdRGBAub4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2456. begin
  2457. inherited Map(aPixel, aData, aMapData);
  2458. aData^ := aPixel.Data.a;
  2459. inc(aData);
  2460. end;
  2461. procedure TfdRGBAub4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2462. begin
  2463. inherited Unmap(aData, aPixel, aMapData);
  2464. aPixel.Data.a := aData^;
  2465. inc(aData);
  2466. end;
  2467. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2468. //TfdBGRA_UB4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2469. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2470. procedure TfdBGRAub4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2471. begin
  2472. inherited Map(aPixel, aData, aMapData);
  2473. aData^ := aPixel.Data.a;
  2474. inc(aData);
  2475. end;
  2476. procedure TfdBGRAub4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2477. begin
  2478. inherited Unmap(aData, aPixel, aMapData);
  2479. aPixel.Data.a := aData^;
  2480. inc(aData);
  2481. end;
  2482. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2483. //TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2484. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2485. procedure TfdAlphaUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2486. begin
  2487. PWord(aData)^ := aPixel.Data.a;
  2488. inc(aData, 2);
  2489. end;
  2490. procedure TfdAlphaUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2491. begin
  2492. aPixel.Data.r := 0;
  2493. aPixel.Data.g := 0;
  2494. aPixel.Data.b := 0;
  2495. aPixel.Data.a := PWord(aData)^;
  2496. inc(aData, 2);
  2497. end;
  2498. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2499. //TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2500. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2501. procedure TfdLuminanceUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2502. begin
  2503. PWord(aData)^ := LuminanceWeight(aPixel);
  2504. inc(aData, 2);
  2505. end;
  2506. procedure TfdLuminanceUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2507. begin
  2508. aPixel.Data.r := PWord(aData)^;
  2509. aPixel.Data.g := PWord(aData)^;
  2510. aPixel.Data.b := PWord(aData)^;
  2511. aPixel.Data.a := 0;
  2512. inc(aData, 2);
  2513. end;
  2514. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2515. //TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2516. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2517. procedure TfdUniversalUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2518. var
  2519. i: Integer;
  2520. begin
  2521. PWord(aData)^ := 0;
  2522. for i := 0 to 3 do
  2523. if (Range.arr[i] > 0) then
  2524. PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
  2525. inc(aData, 2);
  2526. end;
  2527. procedure TfdUniversalUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2528. var
  2529. i: Integer;
  2530. begin
  2531. for i := 0 to 3 do
  2532. aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and Range.arr[i];
  2533. inc(aData, 2);
  2534. end;
  2535. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2536. //TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2537. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2538. procedure TfdDepthUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2539. begin
  2540. PWord(aData)^ := DepthWeight(aPixel);
  2541. inc(aData, 2);
  2542. end;
  2543. procedure TfdDepthUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2544. begin
  2545. aPixel.Data.r := PWord(aData)^;
  2546. aPixel.Data.g := PWord(aData)^;
  2547. aPixel.Data.b := PWord(aData)^;
  2548. aPixel.Data.a := PWord(aData)^;;
  2549. inc(aData, 2);
  2550. end;
  2551. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2552. //TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2553. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2554. procedure TfdLuminanceAlphaUS2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2555. begin
  2556. inherited Map(aPixel, aData, aMapData);
  2557. PWord(aData)^ := aPixel.Data.a;
  2558. inc(aData, 2);
  2559. end;
  2560. procedure TfdLuminanceAlphaUS2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2561. begin
  2562. inherited Unmap(aData, aPixel, aMapData);
  2563. aPixel.Data.a := PWord(aData)^;
  2564. inc(aData, 2);
  2565. end;
  2566. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2567. //TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2568. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2569. procedure TfdRGBus3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2570. begin
  2571. PWord(aData)^ := aPixel.Data.r;
  2572. inc(aData, 2);
  2573. PWord(aData)^ := aPixel.Data.g;
  2574. inc(aData, 2);
  2575. PWord(aData)^ := aPixel.Data.b;
  2576. inc(aData, 2);
  2577. end;
  2578. procedure TfdRGBus3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2579. begin
  2580. aPixel.Data.r := PWord(aData)^;
  2581. inc(aData, 2);
  2582. aPixel.Data.g := PWord(aData)^;
  2583. inc(aData, 2);
  2584. aPixel.Data.b := PWord(aData)^;
  2585. inc(aData, 2);
  2586. aPixel.Data.a := 0;
  2587. end;
  2588. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2589. //TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2590. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2591. procedure TfdBGRus3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2592. begin
  2593. PWord(aData)^ := aPixel.Data.b;
  2594. inc(aData, 2);
  2595. PWord(aData)^ := aPixel.Data.g;
  2596. inc(aData, 2);
  2597. PWord(aData)^ := aPixel.Data.r;
  2598. inc(aData, 2);
  2599. end;
  2600. procedure TfdBGRus3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2601. begin
  2602. aPixel.Data.b := PWord(aData)^;
  2603. inc(aData, 2);
  2604. aPixel.Data.g := PWord(aData)^;
  2605. inc(aData, 2);
  2606. aPixel.Data.r := PWord(aData)^;
  2607. inc(aData, 2);
  2608. aPixel.Data.a := 0;
  2609. end;
  2610. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2611. //TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2612. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2613. procedure TfdRGBAus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2614. begin
  2615. inherited Map(aPixel, aData, aMapData);
  2616. PWord(aData)^ := aPixel.Data.a;
  2617. inc(aData, 2);
  2618. end;
  2619. procedure TfdRGBAus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2620. begin
  2621. inherited Unmap(aData, aPixel, aMapData);
  2622. aPixel.Data.a := PWord(aData)^;
  2623. inc(aData, 2);
  2624. end;
  2625. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2626. //TfdARGB_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2627. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2628. procedure TfdARGBus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2629. begin
  2630. PWord(aData)^ := aPixel.Data.a;
  2631. inc(aData, 2);
  2632. inherited Map(aPixel, aData, aMapData);
  2633. end;
  2634. procedure TfdARGBus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2635. begin
  2636. aPixel.Data.a := PWord(aData)^;
  2637. inc(aData, 2);
  2638. inherited Unmap(aData, aPixel, aMapData);
  2639. end;
  2640. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2641. //TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2642. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2643. procedure TfdBGRAus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2644. begin
  2645. inherited Map(aPixel, aData, aMapData);
  2646. PWord(aData)^ := aPixel.Data.a;
  2647. inc(aData, 2);
  2648. end;
  2649. procedure TfdBGRAus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2650. begin
  2651. inherited Unmap(aData, aPixel, aMapData);
  2652. aPixel.Data.a := PWord(aData)^;
  2653. inc(aData, 2);
  2654. end;
  2655. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2656. //TfdABGR_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2657. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2658. procedure TfdABGRus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2659. begin
  2660. PWord(aData)^ := aPixel.Data.a;
  2661. inc(aData, 2);
  2662. inherited Map(aPixel, aData, aMapData);
  2663. end;
  2664. procedure TfdABGRus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2665. begin
  2666. aPixel.Data.a := PWord(aData)^;
  2667. inc(aData, 2);
  2668. inherited Unmap(aData, aPixel, aMapData);
  2669. end;
  2670. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2671. //TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2672. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2673. procedure TfdUniversalUI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2674. var
  2675. i: Integer;
  2676. begin
  2677. PCardinal(aData)^ := 0;
  2678. for i := 0 to 3 do
  2679. if (Range.arr[i] > 0) then
  2680. PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
  2681. inc(aData, 4);
  2682. end;
  2683. procedure TfdUniversalUI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2684. var
  2685. i: Integer;
  2686. begin
  2687. for i := 0 to 3 do
  2688. aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and Range.arr[i];
  2689. inc(aData, 2);
  2690. end;
  2691. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2692. //TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2693. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2694. procedure TfdDepthUI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2695. begin
  2696. PCardinal(aData)^ := DepthWeight(aPixel);
  2697. inc(aData, 4);
  2698. end;
  2699. procedure TfdDepthUI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2700. begin
  2701. aPixel.Data.r := PCardinal(aData)^;
  2702. aPixel.Data.g := PCardinal(aData)^;
  2703. aPixel.Data.b := PCardinal(aData)^;
  2704. aPixel.Data.a := PCardinal(aData)^;
  2705. inc(aData, 4);
  2706. end;
  2707. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2708. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2709. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2710. procedure TfdAlpha4ub1.SetValues;
  2711. begin
  2712. inherited SetValues;
  2713. fBitsPerPixel := 8;
  2714. fFormat := tfAlpha4ub1;
  2715. fWithAlpha := tfAlpha4ub1;
  2716. fPrecision := glBitmapRec4ub(0, 0, 0, 8);
  2717. fShift := glBitmapRec4ub(0, 0, 0, 0);
  2718. {$IFNDEF OPENGL_ES}
  2719. fOpenGLFormat := tfAlpha4ub1;
  2720. fglFormat := GL_ALPHA;
  2721. fglInternalFormat := GL_ALPHA4;
  2722. fglDataFormat := GL_UNSIGNED_BYTE;
  2723. {$ELSE}
  2724. fOpenGLFormat := tfAlpha8ub1;
  2725. {$ENDIF}
  2726. end;
  2727. procedure TfdAlpha8ub1.SetValues;
  2728. begin
  2729. inherited SetValues;
  2730. fBitsPerPixel := 8;
  2731. fFormat := tfAlpha8ub1;
  2732. fWithAlpha := tfAlpha8ub1;
  2733. fPrecision := glBitmapRec4ub(0, 0, 0, 8);
  2734. fShift := glBitmapRec4ub(0, 0, 0, 0);
  2735. fOpenGLFormat := tfAlpha8ub1;
  2736. fglFormat := GL_ALPHA;
  2737. fglInternalFormat := {$IFNDEF OPENGL_ES}GL_ALPHA8{$ELSE}GL_ALPHA{$ENDIF};
  2738. fglDataFormat := GL_UNSIGNED_BYTE;
  2739. end;
  2740. procedure TfdAlpha16us1.SetValues;
  2741. begin
  2742. inherited SetValues;
  2743. fBitsPerPixel := 16;
  2744. fFormat := tfAlpha16us1;
  2745. fWithAlpha := tfAlpha16us1;
  2746. fPrecision := glBitmapRec4ub(0, 0, 0, 16);
  2747. fShift := glBitmapRec4ub(0, 0, 0, 0);
  2748. {$IFNDEF OPENGL_ES}
  2749. fOpenGLFormat := tfAlpha16us1;
  2750. fglFormat := GL_ALPHA;
  2751. fglInternalFormat := GL_ALPHA16;
  2752. fglDataFormat := GL_UNSIGNED_SHORT;
  2753. {$ELSE}
  2754. fOpenGLFormat := tfAlpha8ub1;
  2755. {$ENDIF}
  2756. end;
  2757. procedure TfdLuminance4ub1.SetValues;
  2758. begin
  2759. inherited SetValues;
  2760. fBitsPerPixel := 8;
  2761. fFormat := tfLuminance4ub1;
  2762. fWithAlpha := tfLuminance4Alpha4ub2;
  2763. fWithoutAlpha := tfLuminance4ub1;
  2764. fPrecision := glBitmapRec4ub(8, 8, 8, 0);
  2765. fShift := glBitmapRec4ub(0, 0, 0, 0);
  2766. {$IFNDEF OPENGL_ES}
  2767. fOpenGLFormat := tfLuminance4ub1;
  2768. fglFormat := GL_LUMINANCE;
  2769. fglInternalFormat := GL_LUMINANCE4;
  2770. fglDataFormat := GL_UNSIGNED_BYTE;
  2771. {$ELSE}
  2772. fOpenGLFormat := tfLuminance8ub1;
  2773. {$ENDIF}
  2774. end;
  2775. procedure TfdLuminance8ub1.SetValues;
  2776. begin
  2777. inherited SetValues;
  2778. fBitsPerPixel := 8;
  2779. fFormat := tfLuminance8ub1;
  2780. fWithAlpha := tfLuminance8Alpha8ub2;
  2781. fWithoutAlpha := tfLuminance8ub1;
  2782. fOpenGLFormat := tfLuminance8ub1;
  2783. fPrecision := glBitmapRec4ub(8, 8, 8, 0);
  2784. fShift := glBitmapRec4ub(0, 0, 0, 0);
  2785. fglFormat := GL_LUMINANCE;
  2786. fglInternalFormat := {$IFNDEF OPENGL_ES}GL_LUMINANCE8{$ELSE}GL_LUMINANCE{$ENDIF};
  2787. fglDataFormat := GL_UNSIGNED_BYTE;
  2788. end;
  2789. procedure TfdLuminance16us1.SetValues;
  2790. begin
  2791. inherited SetValues;
  2792. fBitsPerPixel := 16;
  2793. fFormat := tfLuminance16us1;
  2794. fWithAlpha := tfLuminance16Alpha16us2;
  2795. fWithoutAlpha := tfLuminance16us1;
  2796. fPrecision := glBitmapRec4ub(16, 16, 16, 0);
  2797. fShift := glBitmapRec4ub( 0, 0, 0, 0);
  2798. {$IFNDEF OPENGL_ES}
  2799. fOpenGLFormat := tfLuminance16us1;
  2800. fglFormat := GL_LUMINANCE;
  2801. fglInternalFormat := GL_LUMINANCE16;
  2802. fglDataFormat := GL_UNSIGNED_SHORT;
  2803. {$ELSE}
  2804. fOpenGLFormat := tfLuminance8ub1;
  2805. {$ENDIF}
  2806. end;
  2807. procedure TfdLuminance4Alpha4ub2.SetValues;
  2808. begin
  2809. inherited SetValues;
  2810. fBitsPerPixel := 16;
  2811. fFormat := tfLuminance4Alpha4ub2;
  2812. fWithAlpha := tfLuminance4Alpha4ub2;
  2813. fWithoutAlpha := tfLuminance4ub1;
  2814. fPrecision := glBitmapRec4ub(8, 8, 8, 8);
  2815. fShift := glBitmapRec4ub(0, 0, 0, 8);
  2816. {$IFNDEF OPENGL_ES}
  2817. fOpenGLFormat := tfLuminance4Alpha4ub2;
  2818. fglFormat := GL_LUMINANCE_ALPHA;
  2819. fglInternalFormat := GL_LUMINANCE4_ALPHA4;
  2820. fglDataFormat := GL_UNSIGNED_BYTE;
  2821. {$ELSE}
  2822. fOpenGLFormat := tfLuminance8Alpha8ub2;
  2823. {$ENDIF}
  2824. end;
  2825. procedure TfdLuminance6Alpha2ub2.SetValues;
  2826. begin
  2827. inherited SetValues;
  2828. fBitsPerPixel := 16;
  2829. fFormat := tfLuminance6Alpha2ub2;
  2830. fWithAlpha := tfLuminance6Alpha2ub2;
  2831. fWithoutAlpha := tfLuminance8ub1;
  2832. fPrecision := glBitmapRec4ub(8, 8, 8, 8);
  2833. fShift := glBitmapRec4ub(0, 0, 0, 8);
  2834. {$IFNDEF OPENGL_ES}
  2835. fOpenGLFormat := tfLuminance6Alpha2ub2;
  2836. fglFormat := GL_LUMINANCE_ALPHA;
  2837. fglInternalFormat := GL_LUMINANCE6_ALPHA2;
  2838. fglDataFormat := GL_UNSIGNED_BYTE;
  2839. {$ELSE}
  2840. fOpenGLFormat := tfLuminance8Alpha8ub2;
  2841. {$ENDIF}
  2842. end;
  2843. procedure TfdLuminance8Alpha8ub2.SetValues;
  2844. begin
  2845. inherited SetValues;
  2846. fBitsPerPixel := 16;
  2847. fFormat := tfLuminance8Alpha8ub2;
  2848. fWithAlpha := tfLuminance8Alpha8ub2;
  2849. fWithoutAlpha := tfLuminance8ub1;
  2850. fOpenGLFormat := tfLuminance8Alpha8ub2;
  2851. fPrecision := glBitmapRec4ub(8, 8, 8, 8);
  2852. fShift := glBitmapRec4ub(0, 0, 0, 8);
  2853. fglFormat := GL_LUMINANCE_ALPHA;
  2854. fglInternalFormat := {$IFNDEF OPENGL_ES}GL_LUMINANCE8_ALPHA8{$ELSE}GL_LUMINANCE_ALPHA{$ENDIF};
  2855. fglDataFormat := GL_UNSIGNED_BYTE;
  2856. end;
  2857. procedure TfdLuminance12Alpha4us2.SetValues;
  2858. begin
  2859. inherited SetValues;
  2860. fBitsPerPixel := 32;
  2861. fFormat := tfLuminance12Alpha4us2;
  2862. fWithAlpha := tfLuminance12Alpha4us2;
  2863. fWithoutAlpha := tfLuminance16us1;
  2864. fPrecision := glBitmapRec4ub(16, 16, 16, 16);
  2865. fShift := glBitmapRec4ub( 0, 0, 0, 16);
  2866. {$IFNDEF OPENGL_ES}
  2867. fOpenGLFormat := tfLuminance12Alpha4us2;
  2868. fglFormat := GL_LUMINANCE_ALPHA;
  2869. fglInternalFormat := GL_LUMINANCE12_ALPHA4;
  2870. fglDataFormat := GL_UNSIGNED_SHORT;
  2871. {$ELSE}
  2872. fOpenGLFormat := tfLuminance8Alpha8ub2;
  2873. {$ENDIF}
  2874. end;
  2875. procedure TfdLuminance16Alpha16us2.SetValues;
  2876. begin
  2877. inherited SetValues;
  2878. fBitsPerPixel := 32;
  2879. fFormat := tfLuminance16Alpha16us2;
  2880. fWithAlpha := tfLuminance16Alpha16us2;
  2881. fWithoutAlpha := tfLuminance16us1;
  2882. fPrecision := glBitmapRec4ub(16, 16, 16, 16);
  2883. fShift := glBitmapRec4ub( 0, 0, 0, 16);
  2884. {$IFNDEF OPENGL_ES}
  2885. fOpenGLFormat := tfLuminance16Alpha16us2;
  2886. fglFormat := GL_LUMINANCE_ALPHA;
  2887. fglInternalFormat := GL_LUMINANCE16_ALPHA16;
  2888. fglDataFormat := GL_UNSIGNED_SHORT;
  2889. {$ELSE}
  2890. fOpenGLFormat := tfLuminance8Alpha8ub2;
  2891. {$ENDIF}
  2892. end;
  2893. procedure TfdR3G3B2ub1.SetValues;
  2894. begin
  2895. inherited SetValues;
  2896. fBitsPerPixel := 8;
  2897. fFormat := tfR3G3B2ub1;
  2898. fWithAlpha := tfRGBA4us1;
  2899. fWithoutAlpha := tfR3G3B2ub1;
  2900. fRGBInverted := tfEmpty;
  2901. fPrecision := glBitmapRec4ub(3, 3, 2, 0);
  2902. fShift := glBitmapRec4ub(5, 2, 0, 0);
  2903. {$IFNDEF OPENGL_ES}
  2904. fOpenGLFormat := tfR3G3B2ub1;
  2905. fglFormat := GL_RGB;
  2906. fglInternalFormat := GL_R3_G3_B2;
  2907. fglDataFormat := GL_UNSIGNED_BYTE_3_3_2;
  2908. {$ELSE}
  2909. fOpenGLFormat := tfR5G6B5us1;
  2910. {$ENDIF}
  2911. end;
  2912. procedure TfdRGBX4us1.SetValues;
  2913. begin
  2914. inherited SetValues;
  2915. fBitsPerPixel := 16;
  2916. fFormat := tfRGBX4us1;
  2917. fWithAlpha := tfRGBA4us1;
  2918. fWithoutAlpha := tfRGBX4us1;
  2919. fRGBInverted := tfBGRX4us1;
  2920. fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
  2921. fShift := glBitmapRec4ub(12, 8, 4, 0);
  2922. {$IFNDEF OPENGL_ES}
  2923. fOpenGLFormat := tfRGBX4us1;
  2924. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2925. fglInternalFormat := GL_RGB4;
  2926. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
  2927. {$ELSE}
  2928. fOpenGLFormat := tfR5G6B5us1;
  2929. {$ENDIF}
  2930. end;
  2931. procedure TfdXRGB4us1.SetValues;
  2932. begin
  2933. inherited SetValues;
  2934. fBitsPerPixel := 16;
  2935. fFormat := tfXRGB4us1;
  2936. fWithAlpha := tfARGB4us1;
  2937. fWithoutAlpha := tfXRGB4us1;
  2938. fRGBInverted := tfXBGR4us1;
  2939. fPrecision := glBitmapRec4ub(4, 4, 4, 0);
  2940. fShift := glBitmapRec4ub(8, 4, 0, 0);
  2941. {$IFNDEF OPENGL_ES}
  2942. fOpenGLFormat := tfXRGB4us1;
  2943. fglFormat := GL_BGRA;
  2944. fglInternalFormat := GL_RGB4;
  2945. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
  2946. {$ELSE}
  2947. fOpenGLFormat := tfR5G6B5us1;
  2948. {$ENDIF}
  2949. end;
  2950. procedure TfdR5G6B5us1.SetValues;
  2951. begin
  2952. inherited SetValues;
  2953. fBitsPerPixel := 16;
  2954. fFormat := tfR5G6B5us1;
  2955. fWithAlpha := tfRGB5A1us1;
  2956. fWithoutAlpha := tfR5G6B5us1;
  2957. fRGBInverted := tfB5G6R5us1;
  2958. fPrecision := glBitmapRec4ub( 5, 6, 5, 0);
  2959. fShift := glBitmapRec4ub(11, 5, 0, 0);
  2960. {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
  2961. fOpenGLFormat := tfR5G6B5us1;
  2962. fglFormat := GL_RGB;
  2963. fglInternalFormat := GL_RGB565;
  2964. fglDataFormat := GL_UNSIGNED_SHORT_5_6_5;
  2965. {$ELSE}
  2966. fOpenGLFormat := tfRGB8ub3;
  2967. {$IFEND}
  2968. end;
  2969. procedure TfdRGB5X1us1.SetValues;
  2970. begin
  2971. inherited SetValues;
  2972. fBitsPerPixel := 16;
  2973. fFormat := tfRGB5X1us1;
  2974. fWithAlpha := tfRGB5A1us1;
  2975. fWithoutAlpha := tfRGB5X1us1;
  2976. fRGBInverted := tfBGR5X1us1;
  2977. fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
  2978. fShift := glBitmapRec4ub(11, 6, 1, 0);
  2979. {$IFNDEF OPENGL_ES}
  2980. fOpenGLFormat := tfRGB5X1us1;
  2981. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2982. fglInternalFormat := GL_RGB5;
  2983. fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
  2984. {$ELSE}
  2985. fOpenGLFormat := tfR5G6B5us1;
  2986. {$ENDIF}
  2987. end;
  2988. procedure TfdX1RGB5us1.SetValues;
  2989. begin
  2990. inherited SetValues;
  2991. fBitsPerPixel := 16;
  2992. fFormat := tfX1RGB5us1;
  2993. fWithAlpha := tfA1RGB5us1;
  2994. fWithoutAlpha := tfX1RGB5us1;
  2995. fRGBInverted := tfX1BGR5us1;
  2996. fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
  2997. fShift := glBitmapRec4ub(10, 5, 0, 0);
  2998. {$IFNDEF OPENGL_ES}
  2999. fOpenGLFormat := tfX1RGB5us1;
  3000. fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  3001. fglInternalFormat := GL_RGB5;
  3002. fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
  3003. {$ELSE}
  3004. fOpenGLFormat := tfR5G6B5us1;
  3005. {$ENDIF}
  3006. end;
  3007. procedure TfdRGB8ub3.SetValues;
  3008. begin
  3009. inherited SetValues;
  3010. fBitsPerPixel := 24;
  3011. fFormat := tfRGB8ub3;
  3012. fWithAlpha := tfRGBA8ub4;
  3013. fWithoutAlpha := tfRGB8ub3;
  3014. fRGBInverted := tfBGR8ub3;
  3015. fPrecision := glBitmapRec4ub(8, 8, 8, 0);
  3016. fShift := glBitmapRec4ub(0, 8, 16, 0);
  3017. fOpenGLFormat := tfRGB8ub3;
  3018. fglFormat := GL_RGB;
  3019. fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGB8{$ELSE}GL_RGB{$IFEND};
  3020. fglDataFormat := GL_UNSIGNED_BYTE;
  3021. end;
  3022. procedure TfdRGBX8ui1.SetValues;
  3023. begin
  3024. inherited SetValues;
  3025. fBitsPerPixel := 32;
  3026. fFormat := tfRGBX8ui1;
  3027. fWithAlpha := tfRGBA8ui1;
  3028. fWithoutAlpha := tfRGBX8ui1;
  3029. fRGBInverted := tfBGRX8ui1;
  3030. fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
  3031. fShift := glBitmapRec4ub(24, 16, 8, 0);
  3032. {$IFNDEF OPENGL_ES}
  3033. fOpenGLFormat := tfRGBX8ui1;
  3034. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  3035. fglInternalFormat := GL_RGB8;
  3036. fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
  3037. {$ELSE}
  3038. fOpenGLFormat := tfRGB8ub3;
  3039. {$ENDIF}
  3040. end;
  3041. procedure TfdXRGB8ui1.SetValues;
  3042. begin
  3043. inherited SetValues;
  3044. fBitsPerPixel := 32;
  3045. fFormat := tfXRGB8ui1;
  3046. fWithAlpha := tfXRGB8ui1;
  3047. fWithoutAlpha := tfXRGB8ui1;
  3048. fOpenGLFormat := tfXRGB8ui1;
  3049. fRGBInverted := tfXBGR8ui1;
  3050. fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
  3051. fShift := glBitmapRec4ub(16, 8, 0, 0);
  3052. {$IFNDEF OPENGL_ES}
  3053. fOpenGLFormat := tfXRGB8ui1;
  3054. fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  3055. fglInternalFormat := GL_RGB8;
  3056. fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
  3057. {$ELSE}
  3058. fOpenGLFormat := tfRGB8ub3;
  3059. {$ENDIF}
  3060. end;
  3061. procedure TfdRGB10X2ui1.SetValues;
  3062. begin
  3063. inherited SetValues;
  3064. fBitsPerPixel := 32;
  3065. fFormat := tfRGB10X2ui1;
  3066. fWithAlpha := tfRGB10A2ui1;
  3067. fWithoutAlpha := tfRGB10X2ui1;
  3068. fRGBInverted := tfBGR10X2ui1;
  3069. fPrecision := glBitmapRec4ub(10, 10, 10, 0);
  3070. fShift := glBitmapRec4ub(22, 12, 2, 0);
  3071. {$IFNDEF OPENGL_ES}
  3072. fOpenGLFormat := tfRGB10X2ui1;
  3073. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  3074. fglInternalFormat := GL_RGB10;
  3075. fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
  3076. {$ELSE}
  3077. fOpenGLFormat := tfRGB16us3;
  3078. {$ENDIF}
  3079. end;
  3080. procedure TfdX2RGB10ui1.SetValues;
  3081. begin
  3082. inherited SetValues;
  3083. fBitsPerPixel := 32;
  3084. fFormat := tfX2RGB10ui1;
  3085. fWithAlpha := tfA2RGB10ui1;
  3086. fWithoutAlpha := tfX2RGB10ui1;
  3087. fRGBInverted := tfX2BGR10ui1;
  3088. fPrecision := glBitmapRec4ub(10, 10, 10, 0);
  3089. fShift := glBitmapRec4ub(20, 10, 0, 0);
  3090. {$IFNDEF OPENGL_ES}
  3091. fOpenGLFormat := tfX2RGB10ui1;
  3092. fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  3093. fglInternalFormat := GL_RGB10;
  3094. fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
  3095. {$ELSE}
  3096. fOpenGLFormat := tfRGB16us3;
  3097. {$ENDIF}
  3098. end;
  3099. procedure TfdRGB16us3.SetValues;
  3100. begin
  3101. inherited SetValues;
  3102. fBitsPerPixel := 48;
  3103. fFormat := tfRGB16us3;
  3104. fWithAlpha := tfRGBA16us4;
  3105. fWithoutAlpha := tfRGB16us3;
  3106. fRGBInverted := tfBGR16us3;
  3107. fPrecision := glBitmapRec4ub(16, 16, 16, 0);
  3108. fShift := glBitmapRec4ub( 0, 16, 32, 0);
  3109. {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
  3110. fOpenGLFormat := tfRGB16us3;
  3111. fglFormat := GL_RGB;
  3112. fglInternalFormat := {$IFNDEF OPENGL_ES}GL_RGB16{$ELSE}GL_RGB16UI{$ENDIF};
  3113. fglDataFormat := GL_UNSIGNED_SHORT;
  3114. {$ELSE}
  3115. fOpenGLFormat := tfRGB8ub3;
  3116. {$IFEND}
  3117. end;
  3118. procedure TfdRGBA4us1.SetValues;
  3119. begin
  3120. inherited SetValues;
  3121. fBitsPerPixel := 16;
  3122. fFormat := tfRGBA4us1;
  3123. fWithAlpha := tfRGBA4us1;
  3124. fWithoutAlpha := tfRGBX4us1;
  3125. fOpenGLFormat := tfRGBA4us1;
  3126. fRGBInverted := tfBGRA4us1;
  3127. fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
  3128. fShift := glBitmapRec4ub(12, 8, 4, 0);
  3129. fglFormat := GL_RGBA;
  3130. fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGBA8{$ELSE}GL_RGBA{$IFEND};
  3131. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
  3132. end;
  3133. procedure TfdARGB4us1.SetValues;
  3134. begin
  3135. inherited SetValues;
  3136. fBitsPerPixel := 16;
  3137. fFormat := tfARGB4us1;
  3138. fWithAlpha := tfARGB4us1;
  3139. fWithoutAlpha := tfXRGB4us1;
  3140. fRGBInverted := tfABGR4us1;
  3141. fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
  3142. fShift := glBitmapRec4ub( 8, 4, 0, 12);
  3143. {$IFNDEF OPENGL_ES}
  3144. fOpenGLFormat := tfARGB4us1;
  3145. fglFormat := GL_BGRA;
  3146. fglInternalFormat := GL_RGBA4;
  3147. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
  3148. {$ELSE}
  3149. fOpenGLFormat := tfRGBA4us1;
  3150. {$ENDIF}
  3151. end;
  3152. procedure TfdRGB5A1us1.SetValues;
  3153. begin
  3154. inherited SetValues;
  3155. fBitsPerPixel := 16;
  3156. fFormat := tfRGB5A1us1;
  3157. fWithAlpha := tfRGB5A1us1;
  3158. fWithoutAlpha := tfRGB5X1us1;
  3159. fOpenGLFormat := tfRGB5A1us1;
  3160. fRGBInverted := tfBGR5A1us1;
  3161. fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
  3162. fShift := glBitmapRec4ub(11, 6, 1, 0);
  3163. fglFormat := GL_RGBA;
  3164. fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}GL_RGB5_A1{$ELSE}GL_RGBA{$IFEND};
  3165. fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
  3166. end;
  3167. procedure TfdA1RGB5us1.SetValues;
  3168. begin
  3169. inherited SetValues;
  3170. fBitsPerPixel := 16;
  3171. fFormat := tfA1RGB5us1;
  3172. fWithAlpha := tfA1RGB5us1;
  3173. fWithoutAlpha := tfX1RGB5us1;
  3174. fRGBInverted := tfA1BGR5us1;
  3175. fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
  3176. fShift := glBitmapRec4ub(10, 5, 0, 15);
  3177. {$IFNDEF OPENGL_ES}
  3178. fOpenGLFormat := tfA1RGB5us1;
  3179. fglFormat := GL_BGRA;
  3180. fglInternalFormat := GL_RGB5_A1;
  3181. fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
  3182. {$ELSE}
  3183. fOpenGLFormat := tfRGB5A1us1;
  3184. {$ENDIF}
  3185. end;
  3186. procedure TfdRGBA8ui1.SetValues;
  3187. begin
  3188. inherited SetValues;
  3189. fBitsPerPixel := 32;
  3190. fFormat := tfRGBA8ui1;
  3191. fWithAlpha := tfRGBA8ui1;
  3192. fWithoutAlpha := tfRGBX8ui1;
  3193. fRGBInverted := tfBGRA8ui1;
  3194. fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
  3195. fShift := glBitmapRec4ub(24, 16, 8, 0);
  3196. {$IFNDEF OPENGL_ES}
  3197. fOpenGLFormat := tfRGBA8ui1;
  3198. fglFormat := GL_RGBA;
  3199. fglInternalFormat := GL_RGBA8;
  3200. fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
  3201. {$ELSE}
  3202. fOpenGLFormat := tfRGBA8ub4;
  3203. {$ENDIF}
  3204. end;
  3205. procedure TfdARGB8ui1.SetValues;
  3206. begin
  3207. inherited SetValues;
  3208. fBitsPerPixel := 32;
  3209. fFormat := tfARGB8ui1;
  3210. fWithAlpha := tfARGB8ui1;
  3211. fWithoutAlpha := tfXRGB8ui1;
  3212. fRGBInverted := tfABGR8ui1;
  3213. fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
  3214. fShift := glBitmapRec4ub(16, 8, 0, 24);
  3215. {$IFNDEF OPENGL_ES}
  3216. fOpenGLFormat := tfARGB8ui1;
  3217. fglFormat := GL_BGRA;
  3218. fglInternalFormat := GL_RGBA8;
  3219. fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
  3220. {$ELSE}
  3221. fOpenGLFormat := tfRGBA8ub4;
  3222. {$ENDIF}
  3223. end;
  3224. procedure TfdRGBA8ub4.SetValues;
  3225. begin
  3226. inherited SetValues;
  3227. fBitsPerPixel := 32;
  3228. fFormat := tfRGBA8ub4;
  3229. fWithAlpha := tfRGBA8ub4;
  3230. fWithoutAlpha := tfRGB8ub3;
  3231. fOpenGLFormat := tfRGBA8ub4;
  3232. fRGBInverted := tfBGRA8ub4;
  3233. fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
  3234. fShift := glBitmapRec4ub( 0, 8, 16, 24);
  3235. fglFormat := GL_RGBA;
  3236. fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGBA8{$ELSE}GL_RGBA{$IFEND};
  3237. fglDataFormat := GL_UNSIGNED_BYTE;
  3238. end;
  3239. procedure TfdRGB10A2ui1.SetValues;
  3240. begin
  3241. inherited SetValues;
  3242. fBitsPerPixel := 32;
  3243. fFormat := tfRGB10A2ui1;
  3244. fWithAlpha := tfRGB10A2ui1;
  3245. fWithoutAlpha := tfRGB10X2ui1;
  3246. fRGBInverted := tfBGR10A2ui1;
  3247. fPrecision := glBitmapRec4ub(10, 10, 10, 2);
  3248. fShift := glBitmapRec4ub(22, 12, 2, 0);
  3249. {$IFNDEF OPENGL_ES}
  3250. fOpenGLFormat := tfRGB10A2ui1;
  3251. fglFormat := GL_RGBA;
  3252. fglInternalFormat := GL_RGB10_A2;
  3253. fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
  3254. {$ELSE}
  3255. fOpenGLFormat := tfA2RGB10ui1;
  3256. {$ENDIF}
  3257. end;
  3258. procedure TfdA2RGB10ui1.SetValues;
  3259. begin
  3260. inherited SetValues;
  3261. fBitsPerPixel := 32;
  3262. fFormat := tfA2RGB10ui1;
  3263. fWithAlpha := tfA2RGB10ui1;
  3264. fWithoutAlpha := tfX2RGB10ui1;
  3265. fRGBInverted := tfA2BGR10ui1;
  3266. fPrecision := glBitmapRec4ub(10, 10, 10, 2);
  3267. fShift := glBitmapRec4ub(20, 10, 0, 30);
  3268. {$IF NOT DEFINED(OPENGL_ES)}
  3269. fOpenGLFormat := tfA2RGB10ui1;
  3270. fglFormat := GL_BGRA;
  3271. fglInternalFormat := GL_RGB10_A2;
  3272. fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
  3273. {$ELSEIF DEFINED(OPENGL_ES_3_0)}
  3274. fOpenGLFormat := tfA2RGB10ui1;
  3275. fglFormat := GL_RGBA;
  3276. fglInternalFormat := GL_RGB10_A2;
  3277. fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
  3278. {$ELSE}
  3279. fOpenGLFormat := tfRGBA8ui1;
  3280. {$IFEND}
  3281. end;
  3282. procedure TfdRGBA16us4.SetValues;
  3283. begin
  3284. inherited SetValues;
  3285. fBitsPerPixel := 64;
  3286. fFormat := tfRGBA16us4;
  3287. fWithAlpha := tfRGBA16us4;
  3288. fWithoutAlpha := tfRGB16us3;
  3289. fRGBInverted := tfBGRA16us4;
  3290. fPrecision := glBitmapRec4ub(16, 16, 16, 16);
  3291. fShift := glBitmapRec4ub( 0, 16, 32, 48);
  3292. {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
  3293. fOpenGLFormat := tfRGBA16us4;
  3294. fglFormat := GL_RGBA;
  3295. fglInternalFormat := {$IFNDEF OPENGL_ES}GL_RGBA16{$ELSE}GL_RGBA16UI{$ENDIF};
  3296. fglDataFormat := GL_UNSIGNED_SHORT;
  3297. {$ELSE}
  3298. fOpenGLFormat := tfRGBA8ub4;
  3299. {$IFEND}
  3300. end;
  3301. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3302. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3303. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3304. procedure TfdBGRX4us1.SetValues;
  3305. begin
  3306. inherited SetValues;
  3307. fBitsPerPixel := 16;
  3308. fFormat := tfBGRX4us1;
  3309. fWithAlpha := tfBGRA4us1;
  3310. fWithoutAlpha := tfBGRX4us1;
  3311. fRGBInverted := tfRGBX4us1;
  3312. fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
  3313. fShift := glBitmapRec4ub( 4, 8, 12, 0);
  3314. {$IFNDEF OPENGL_ES}
  3315. fOpenGLFormat := tfBGRX4us1;
  3316. fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  3317. fglInternalFormat := GL_RGB4;
  3318. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
  3319. {$ELSE}
  3320. fOpenGLFormat := tfR5G6B5us1;
  3321. {$ENDIF}
  3322. end;
  3323. procedure TfdXBGR4us1.SetValues;
  3324. begin
  3325. inherited SetValues;
  3326. fBitsPerPixel := 16;
  3327. fFormat := tfXBGR4us1;
  3328. fWithAlpha := tfABGR4us1;
  3329. fWithoutAlpha := tfXBGR4us1;
  3330. fRGBInverted := tfXRGB4us1;
  3331. fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
  3332. fShift := glBitmapRec4ub( 0, 4, 8, 0);
  3333. {$IFNDEF OPENGL_ES}
  3334. fOpenGLFormat := tfXBGR4us1;
  3335. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  3336. fglInternalFormat := GL_RGB4;
  3337. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
  3338. {$ELSE}
  3339. fOpenGLFormat := tfR5G6B5us1;
  3340. {$ENDIF}
  3341. end;
  3342. procedure TfdB5G6R5us1.SetValues;
  3343. begin
  3344. inherited SetValues;
  3345. fBitsPerPixel := 16;
  3346. fFormat := tfB5G6R5us1;
  3347. fWithAlpha := tfBGR5A1us1;
  3348. fWithoutAlpha := tfB5G6R5us1;
  3349. fRGBInverted := tfR5G6B5us1;
  3350. fPrecision := glBitmapRec4ub( 5, 6, 5, 0);
  3351. fShift := glBitmapRec4ub( 0, 5, 11, 0);
  3352. {$IFNDEF OPENGL_ES}
  3353. fOpenGLFormat := tfB5G6R5us1;
  3354. fglFormat := GL_RGB;
  3355. fglInternalFormat := GL_RGB565;
  3356. fglDataFormat := GL_UNSIGNED_SHORT_5_6_5_REV;
  3357. {$ELSE}
  3358. fOpenGLFormat := tfR5G6B5us1;
  3359. {$ENDIF}
  3360. end;
  3361. procedure TfdBGR5X1us1.SetValues;
  3362. begin
  3363. inherited SetValues;
  3364. fBitsPerPixel := 16;
  3365. fFormat := tfBGR5X1us1;
  3366. fWithAlpha := tfBGR5A1us1;
  3367. fWithoutAlpha := tfBGR5X1us1;
  3368. fRGBInverted := tfRGB5X1us1;
  3369. fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
  3370. fShift := glBitmapRec4ub( 1, 6, 11, 0);
  3371. {$IFNDEF OPENGL_ES}
  3372. fOpenGLFormat := tfBGR5X1us1;
  3373. fglFormat := GL_BGRA;
  3374. fglInternalFormat := GL_RGB5;
  3375. fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
  3376. {$ELSE}
  3377. fOpenGLFormat := tfR5G6B5us1;
  3378. {$ENDIF}
  3379. end;
  3380. procedure TfdX1BGR5us1.SetValues;
  3381. begin
  3382. inherited SetValues;
  3383. fBitsPerPixel := 16;
  3384. fFormat := tfX1BGR5us1;
  3385. fWithAlpha := tfA1BGR5us1;
  3386. fWithoutAlpha := tfX1BGR5us1;
  3387. fRGBInverted := tfX1RGB5us1;
  3388. fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
  3389. fShift := glBitmapRec4ub( 0, 5, 10, 0);
  3390. {$IFNDEF OPENGL_ES}
  3391. fOpenGLFormat := tfX1BGR5us1;
  3392. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  3393. fglInternalFormat := GL_RGB5;
  3394. fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
  3395. {$ELSE}
  3396. fOpenGLFormat := tfR5G6B5us1;
  3397. {$ENDIF}
  3398. end;
  3399. procedure TfdBGR8ub3.SetValues;
  3400. begin
  3401. inherited SetValues;
  3402. fBitsPerPixel := 24;
  3403. fFormat := tfBGR8ub3;
  3404. fWithAlpha := tfBGRA8ub4;
  3405. fWithoutAlpha := tfBGR8ub3;
  3406. fRGBInverted := tfRGB8ub3;
  3407. fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
  3408. fShift := glBitmapRec4ub(16, 8, 0, 0);
  3409. {$IFNDEF OPENGL_ES}
  3410. fOpenGLFormat := tfBGR8ub3;
  3411. fglFormat := GL_BGR;
  3412. fglInternalFormat := GL_RGB8;
  3413. fglDataFormat := GL_UNSIGNED_BYTE;
  3414. {$ELSE}
  3415. fOpenGLFormat := tfRGB8ub3;
  3416. {$ENDIF}
  3417. end;
  3418. procedure TfdBGRX8ui1.SetValues;
  3419. begin
  3420. inherited SetValues;
  3421. fBitsPerPixel := 32;
  3422. fFormat := tfBGRX8ui1;
  3423. fWithAlpha := tfBGRA8ui1;
  3424. fWithoutAlpha := tfBGRX8ui1;
  3425. fRGBInverted := tfRGBX8ui1;
  3426. fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
  3427. fShift := glBitmapRec4ub( 8, 16, 24, 0);
  3428. {$IFNDEF OPENGL_ES}
  3429. fOpenGLFormat := tfBGRX8ui1;
  3430. fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  3431. fglInternalFormat := GL_RGB8;
  3432. fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
  3433. {$ELSE}
  3434. fOpenGLFormat := tfRGB8ub3;
  3435. {$ENDIF}
  3436. end;
  3437. procedure TfdXBGR8ui1.SetValues;
  3438. begin
  3439. inherited SetValues;
  3440. fBitsPerPixel := 32;
  3441. fFormat := tfXBGR8ui1;
  3442. fWithAlpha := tfABGR8ui1;
  3443. fWithoutAlpha := tfXBGR8ui1;
  3444. fRGBInverted := tfXRGB8ui1;
  3445. fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
  3446. fShift := glBitmapRec4ub( 0, 8, 16, 0);
  3447. {$IFNDEF OPENGL_ES}
  3448. fOpenGLFormat := tfXBGR8ui1;
  3449. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  3450. fglInternalFormat := GL_RGB8;
  3451. fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
  3452. {$ELSE}
  3453. fOpenGLFormat := tfRGB8ub3;
  3454. {$ENDIF}
  3455. end;
  3456. procedure TfdBGR10X2ui1.SetValues;
  3457. begin
  3458. inherited SetValues;
  3459. fBitsPerPixel := 32;
  3460. fFormat := tfBGR10X2ui1;
  3461. fWithAlpha := tfBGR10A2ui1;
  3462. fWithoutAlpha := tfBGR10X2ui1;
  3463. fRGBInverted := tfRGB10X2ui1;
  3464. fPrecision := glBitmapRec4ub(10, 10, 10, 0);
  3465. fShift := glBitmapRec4ub( 2, 12, 22, 0);
  3466. {$IFNDEF OPENGL_ES}
  3467. fOpenGLFormat := tfBGR10X2ui1;
  3468. fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  3469. fglInternalFormat := GL_RGB10;
  3470. fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
  3471. {$ELSE}
  3472. fOpenGLFormat := tfRGB16us3;
  3473. {$ENDIF}
  3474. end;
  3475. procedure TfdX2BGR10ui1.SetValues;
  3476. begin
  3477. inherited SetValues;
  3478. fBitsPerPixel := 32;
  3479. fFormat := tfX2BGR10ui1;
  3480. fWithAlpha := tfA2BGR10ui1;
  3481. fWithoutAlpha := tfX2BGR10ui1;
  3482. fRGBInverted := tfX2RGB10ui1;
  3483. fPrecision := glBitmapRec4ub(10, 10, 10, 0);
  3484. fShift := glBitmapRec4ub( 0, 10, 20, 0);
  3485. {$IFNDEF OPENGL_ES}
  3486. fOpenGLFormat := tfX2BGR10ui1;
  3487. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  3488. fglInternalFormat := GL_RGB10;
  3489. fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
  3490. {$ELSE}
  3491. fOpenGLFormat := tfRGB16us3;
  3492. {$ENDIF}
  3493. end;
  3494. procedure TfdBGR16us3.SetValues;
  3495. begin
  3496. inherited SetValues;
  3497. fBitsPerPixel := 48;
  3498. fFormat := tfBGR16us3;
  3499. fWithAlpha := tfBGRA16us4;
  3500. fWithoutAlpha := tfBGR16us3;
  3501. fRGBInverted := tfRGB16us3;
  3502. fPrecision := glBitmapRec4ub(16, 16, 16, 0);
  3503. fShift := glBitmapRec4ub(32, 16, 0, 0);
  3504. {$IFNDEF OPENGL_ES}
  3505. fOpenGLFormat := tfBGR16us3;
  3506. fglFormat := GL_BGR;
  3507. fglInternalFormat := GL_RGB16;
  3508. fglDataFormat := GL_UNSIGNED_SHORT;
  3509. {$ELSE}
  3510. fOpenGLFormat := tfRGB16us3;
  3511. {$ENDIF}
  3512. end;
  3513. procedure TfdBGRA4us1.SetValues;
  3514. begin
  3515. inherited SetValues;
  3516. fBitsPerPixel := 16;
  3517. fFormat := tfBGRA4us1;
  3518. fWithAlpha := tfBGRA4us1;
  3519. fWithoutAlpha := tfBGRX4us1;
  3520. fRGBInverted := tfRGBA4us1;
  3521. fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
  3522. fShift := glBitmapRec4ub( 4, 8, 12, 0);
  3523. {$IFNDEF OPENGL_ES}
  3524. fOpenGLFormat := tfBGRA4us1;
  3525. fglFormat := GL_BGRA;
  3526. fglInternalFormat := GL_RGBA4;
  3527. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
  3528. {$ELSE}
  3529. fOpenGLFormat := tfRGBA4us1;
  3530. {$ENDIF}
  3531. end;
  3532. procedure TfdABGR4us1.SetValues;
  3533. begin
  3534. inherited SetValues;
  3535. fBitsPerPixel := 16;
  3536. fFormat := tfABGR4us1;
  3537. fWithAlpha := tfABGR4us1;
  3538. fWithoutAlpha := tfXBGR4us1;
  3539. fRGBInverted := tfARGB4us1;
  3540. fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
  3541. fShift := glBitmapRec4ub( 0, 4, 8, 12);
  3542. {$IFNDEF OPENGL_ES}
  3543. fOpenGLFormat := tfABGR4us1;
  3544. fglFormat := GL_RGBA;
  3545. fglInternalFormat := GL_RGBA4;
  3546. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
  3547. {$ELSE}
  3548. fOpenGLFormat := tfRGBA4us1;
  3549. {$ENDIF}
  3550. end;
  3551. procedure TfdBGR5A1us1.SetValues;
  3552. begin
  3553. inherited SetValues;
  3554. fBitsPerPixel := 16;
  3555. fFormat := tfBGR5A1us1;
  3556. fWithAlpha := tfBGR5A1us1;
  3557. fWithoutAlpha := tfBGR5X1us1;
  3558. fRGBInverted := tfRGB5A1us1;
  3559. fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
  3560. fShift := glBitmapRec4ub( 1, 6, 11, 0);
  3561. {$IFNDEF OPENGL_ES}
  3562. fOpenGLFormat := tfBGR5A1us1;
  3563. fglFormat := GL_BGRA;
  3564. fglInternalFormat := GL_RGB5_A1;
  3565. fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
  3566. {$ELSE}
  3567. fOpenGLFormat := tfRGB5A1us1;
  3568. {$ENDIF}
  3569. end;
  3570. procedure TfdA1BGR5us1.SetValues;
  3571. begin
  3572. inherited SetValues;
  3573. fBitsPerPixel := 16;
  3574. fFormat := tfA1BGR5us1;
  3575. fWithAlpha := tfA1BGR5us1;
  3576. fWithoutAlpha := tfX1BGR5us1;
  3577. fRGBInverted := tfA1RGB5us1;
  3578. fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
  3579. fShift := glBitmapRec4ub( 0, 5, 10, 15);
  3580. {$IFNDEF OPENGL_ES}
  3581. fOpenGLFormat := tfA1BGR5us1;
  3582. fglFormat := GL_RGBA;
  3583. fglInternalFormat := GL_RGB5_A1;
  3584. fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
  3585. {$ELSE}
  3586. fOpenGLFormat := tfRGB5A1us1;
  3587. {$ENDIF}
  3588. end;
  3589. procedure TfdBGRA8ui1.SetValues;
  3590. begin
  3591. inherited SetValues;
  3592. fBitsPerPixel := 32;
  3593. fFormat := tfBGRA8ui1;
  3594. fWithAlpha := tfBGRA8ui1;
  3595. fWithoutAlpha := tfBGRX8ui1;
  3596. fRGBInverted := tfRGBA8ui1;
  3597. fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
  3598. fShift := glBitmapRec4ub( 8, 16, 24, 0);
  3599. {$IFNDEF OPENGL_ES}
  3600. fOpenGLFormat := tfBGRA8ui1;
  3601. fglFormat := GL_BGRA;
  3602. fglInternalFormat := GL_RGBA8;
  3603. fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
  3604. {$ELSE}
  3605. fOpenGLFormat := tfRGBA8ub4;
  3606. {$ENDIF}
  3607. end;
  3608. procedure TfdABGR8ui1.SetValues;
  3609. begin
  3610. inherited SetValues;
  3611. fBitsPerPixel := 32;
  3612. fFormat := tfABGR8ui1;
  3613. fWithAlpha := tfABGR8ui1;
  3614. fWithoutAlpha := tfXBGR8ui1;
  3615. fRGBInverted := tfARGB8ui1;
  3616. fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
  3617. fShift := glBitmapRec4ub( 0, 8, 16, 24);
  3618. {$IFNDEF OPENGL_ES}
  3619. fOpenGLFormat := tfABGR8ui1;
  3620. fglFormat := GL_RGBA;
  3621. fglInternalFormat := GL_RGBA8;
  3622. fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
  3623. {$ELSE}
  3624. fOpenGLFormat := tfRGBA8ub4
  3625. {$ENDIF}
  3626. end;
  3627. procedure TfdBGRA8ub4.SetValues;
  3628. begin
  3629. inherited SetValues;
  3630. fBitsPerPixel := 32;
  3631. fFormat := tfBGRA8ub4;
  3632. fWithAlpha := tfBGRA8ub4;
  3633. fWithoutAlpha := tfBGR8ub3;
  3634. fRGBInverted := tfRGBA8ub4;
  3635. fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
  3636. fShift := glBitmapRec4ub(16, 8, 0, 24);
  3637. {$IFNDEF OPENGL_ES}
  3638. fOpenGLFormat := tfBGRA8ub4;
  3639. fglFormat := GL_BGRA;
  3640. fglInternalFormat := GL_RGBA8;
  3641. fglDataFormat := GL_UNSIGNED_BYTE;
  3642. {$ELSE}
  3643. fOpenGLFormat := tfRGBA8ub4;
  3644. {$ENDIF}
  3645. end;
  3646. procedure TfdBGR10A2ui1.SetValues;
  3647. begin
  3648. inherited SetValues;
  3649. fBitsPerPixel := 32;
  3650. fFormat := tfBGR10A2ui1;
  3651. fWithAlpha := tfBGR10A2ui1;
  3652. fWithoutAlpha := tfBGR10X2ui1;
  3653. fRGBInverted := tfRGB10A2ui1;
  3654. fPrecision := glBitmapRec4ub(10, 10, 10, 2);
  3655. fShift := glBitmapRec4ub( 2, 12, 22, 0);
  3656. {$IFNDEF OPENGL_ES}
  3657. fOpenGLFormat := tfBGR10A2ui1;
  3658. fglFormat := GL_BGRA;
  3659. fglInternalFormat := GL_RGB10_A2;
  3660. fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
  3661. {$ELSE}
  3662. fOpenGLFormat := tfA2RGB10ui1;
  3663. {$ENDIF}
  3664. end;
  3665. procedure TfdA2BGR10ui1.SetValues;
  3666. begin
  3667. inherited SetValues;
  3668. fBitsPerPixel := 32;
  3669. fFormat := tfA2BGR10ui1;
  3670. fWithAlpha := tfA2BGR10ui1;
  3671. fWithoutAlpha := tfX2BGR10ui1;
  3672. fRGBInverted := tfA2RGB10ui1;
  3673. fPrecision := glBitmapRec4ub(10, 10, 10, 2);
  3674. fShift := glBitmapRec4ub( 0, 10, 20, 30);
  3675. {$IFNDEF OPENGL_ES}
  3676. fOpenGLFormat := tfA2BGR10ui1;
  3677. fglFormat := GL_RGBA;
  3678. fglInternalFormat := GL_RGB10_A2;
  3679. fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
  3680. {$ELSE}
  3681. fOpenGLFormat := tfA2RGB10ui1;
  3682. {$ENDIF}
  3683. end;
  3684. procedure TfdBGRA16us4.SetValues;
  3685. begin
  3686. inherited SetValues;
  3687. fBitsPerPixel := 64;
  3688. fFormat := tfBGRA16us4;
  3689. fWithAlpha := tfBGRA16us4;
  3690. fWithoutAlpha := tfBGR16us3;
  3691. fRGBInverted := tfRGBA16us4;
  3692. fPrecision := glBitmapRec4ub(16, 16, 16, 16);
  3693. fShift := glBitmapRec4ub(32, 16, 0, 48);
  3694. {$IFNDEF OPENGL_ES}
  3695. fOpenGLFormat := tfBGRA16us4;
  3696. fglFormat := GL_BGRA;
  3697. fglInternalFormat := GL_RGBA16;
  3698. fglDataFormat := GL_UNSIGNED_SHORT;
  3699. {$ELSE}
  3700. fOpenGLFormat := tfRGBA16us4;
  3701. {$ENDIF}
  3702. end;
  3703. procedure TfdDepth16us1.SetValues;
  3704. begin
  3705. inherited SetValues;
  3706. fBitsPerPixel := 16;
  3707. fFormat := tfDepth16us1;
  3708. fWithoutAlpha := tfDepth16us1;
  3709. fPrecision := glBitmapRec4ub(16, 16, 16, 16);
  3710. fShift := glBitmapRec4ub( 0, 0, 0, 0);
  3711. {$IF NOT DEFINED (OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
  3712. fOpenGLFormat := tfDepth16us1;
  3713. fglFormat := GL_DEPTH_COMPONENT;
  3714. fglInternalFormat := GL_DEPTH_COMPONENT16;
  3715. fglDataFormat := GL_UNSIGNED_SHORT;
  3716. {$IFEND}
  3717. end;
  3718. procedure TfdDepth24ui1.SetValues;
  3719. begin
  3720. inherited SetValues;
  3721. fBitsPerPixel := 32;
  3722. fFormat := tfDepth24ui1;
  3723. fWithoutAlpha := tfDepth24ui1;
  3724. fOpenGLFormat := tfDepth24ui1;
  3725. fPrecision := glBitmapRec4ub(32, 32, 32, 32);
  3726. fShift := glBitmapRec4ub( 0, 0, 0, 0);
  3727. {$IF NOT DEFINED (OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
  3728. fOpenGLFormat := tfDepth24ui1;
  3729. fglFormat := GL_DEPTH_COMPONENT;
  3730. fglInternalFormat := GL_DEPTH_COMPONENT24;
  3731. fglDataFormat := GL_UNSIGNED_INT;
  3732. {$IFEND}
  3733. end;
  3734. procedure TfdDepth32ui1.SetValues;
  3735. begin
  3736. inherited SetValues;
  3737. fBitsPerPixel := 32;
  3738. fFormat := tfDepth32ui1;
  3739. fWithoutAlpha := tfDepth32ui1;
  3740. fPrecision := glBitmapRec4ub(32, 32, 32, 32);
  3741. fShift := glBitmapRec4ub( 0, 0, 0, 0);
  3742. {$IF NOT DEFINED(OPENGL_ES)}
  3743. fOpenGLFormat := tfDepth32ui1;
  3744. fglFormat := GL_DEPTH_COMPONENT;
  3745. fglInternalFormat := GL_DEPTH_COMPONENT32;
  3746. fglDataFormat := GL_UNSIGNED_INT;
  3747. {$ELSEIF DEFINED(OPENGL_ES_3_0)}
  3748. fOpenGLFormat := tfDepth24ui1;
  3749. {$ELSEIF DEFINED(OPENGL_ES_2_0)}
  3750. fOpenGLFormat := tfDepth16us1;
  3751. {$IFEND}
  3752. end;
  3753. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3754. //TfdS3tcDtx1RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3755. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3756. procedure TfdS3tcDtx1RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  3757. begin
  3758. raise EglBitmap.Create('mapping for compressed formats is not supported');
  3759. end;
  3760. procedure TfdS3tcDtx1RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  3761. begin
  3762. raise EglBitmap.Create('mapping for compressed formats is not supported');
  3763. end;
  3764. procedure TfdS3tcDtx1RGBA.SetValues;
  3765. begin
  3766. inherited SetValues;
  3767. fFormat := tfS3tcDtx1RGBA;
  3768. fWithAlpha := tfS3tcDtx1RGBA;
  3769. fUncompressed := tfRGB5A1us1;
  3770. fBitsPerPixel := 4;
  3771. fIsCompressed := true;
  3772. {$IFNDEF OPENGL_ES}
  3773. fOpenGLFormat := tfS3tcDtx1RGBA;
  3774. fglFormat := GL_COMPRESSED_RGBA;
  3775. fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
  3776. fglDataFormat := GL_UNSIGNED_BYTE;
  3777. {$ELSE}
  3778. fOpenGLFormat := fUncompressed;
  3779. {$ENDIF}
  3780. end;
  3781. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3782. //TfdS3tcDtx3RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3783. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3784. procedure TfdS3tcDtx3RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  3785. begin
  3786. raise EglBitmap.Create('mapping for compressed formats is not supported');
  3787. end;
  3788. procedure TfdS3tcDtx3RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  3789. begin
  3790. raise EglBitmap.Create('mapping for compressed formats is not supported');
  3791. end;
  3792. procedure TfdS3tcDtx3RGBA.SetValues;
  3793. begin
  3794. inherited SetValues;
  3795. fFormat := tfS3tcDtx3RGBA;
  3796. fWithAlpha := tfS3tcDtx3RGBA;
  3797. fUncompressed := tfRGBA8ub4;
  3798. fBitsPerPixel := 8;
  3799. fIsCompressed := true;
  3800. {$IFNDEF OPENGL_ES}
  3801. fOpenGLFormat := tfS3tcDtx3RGBA;
  3802. fglFormat := GL_COMPRESSED_RGBA;
  3803. fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
  3804. fglDataFormat := GL_UNSIGNED_BYTE;
  3805. {$ELSE}
  3806. fOpenGLFormat := fUncompressed;
  3807. {$ENDIF}
  3808. end;
  3809. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3810. //TfdS3tcDtx5RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3811. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3812. procedure TfdS3tcDtx5RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  3813. begin
  3814. raise EglBitmap.Create('mapping for compressed formats is not supported');
  3815. end;
  3816. procedure TfdS3tcDtx5RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  3817. begin
  3818. raise EglBitmap.Create('mapping for compressed formats is not supported');
  3819. end;
  3820. procedure TfdS3tcDtx5RGBA.SetValues;
  3821. begin
  3822. inherited SetValues;
  3823. fFormat := tfS3tcDtx3RGBA;
  3824. fWithAlpha := tfS3tcDtx3RGBA;
  3825. fUncompressed := tfRGBA8ub4;
  3826. fBitsPerPixel := 8;
  3827. fIsCompressed := true;
  3828. {$IFNDEF OPENGL_ES}
  3829. fOpenGLFormat := tfS3tcDtx3RGBA;
  3830. fglFormat := GL_COMPRESSED_RGBA;
  3831. fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  3832. fglDataFormat := GL_UNSIGNED_BYTE;
  3833. {$ELSE}
  3834. fOpenGLFormat := fUncompressed;
  3835. {$ENDIF}
  3836. end;
  3837. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3838. //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3839. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3840. function TglBitmapFormatDescriptor.GetHasRed: Boolean;
  3841. begin
  3842. result := (fPrecision.r > 0);
  3843. end;
  3844. function TglBitmapFormatDescriptor.GetHasGreen: Boolean;
  3845. begin
  3846. result := (fPrecision.g > 0);
  3847. end;
  3848. function TglBitmapFormatDescriptor.GetHasBlue: Boolean;
  3849. begin
  3850. result := (fPrecision.b > 0);
  3851. end;
  3852. function TglBitmapFormatDescriptor.GetHasAlpha: Boolean;
  3853. begin
  3854. result := (fPrecision.a > 0);
  3855. end;
  3856. function TglBitmapFormatDescriptor.GetHasColor: Boolean;
  3857. begin
  3858. result := HasRed or HasGreen or HasBlue;
  3859. end;
  3860. function TglBitmapFormatDescriptor.GetIsGrayscale: Boolean;
  3861. begin
  3862. result := (Mask.r = Mask.g) and (Mask.g = Mask.b) and (Mask.r > 0);
  3863. end;
  3864. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3865. procedure TglBitmapFormatDescriptor.SetValues;
  3866. begin
  3867. fFormat := tfEmpty;
  3868. fWithAlpha := tfEmpty;
  3869. fWithoutAlpha := tfEmpty;
  3870. fOpenGLFormat := tfEmpty;
  3871. fRGBInverted := tfEmpty;
  3872. fUncompressed := tfEmpty;
  3873. fBitsPerPixel := 0;
  3874. fIsCompressed := false;
  3875. fglFormat := 0;
  3876. fglInternalFormat := 0;
  3877. fglDataFormat := 0;
  3878. FillChar(fPrecision, 0, SizeOf(fPrecision));
  3879. FillChar(fShift, 0, SizeOf(fShift));
  3880. end;
  3881. procedure TglBitmapFormatDescriptor.CalcValues;
  3882. var
  3883. i: Integer;
  3884. begin
  3885. fBytesPerPixel := fBitsPerPixel / 8;
  3886. fChannelCount := 0;
  3887. for i := 0 to 3 do begin
  3888. if (fPrecision.arr[i] > 0) then
  3889. inc(fChannelCount);
  3890. fRange.arr[i] := (1 shl fPrecision.arr[i]) - 1;
  3891. fMask.arr[i] := fRange.arr[i] shl fShift.arr[i];
  3892. end;
  3893. end;
  3894. constructor TglBitmapFormatDescriptor.Create;
  3895. begin
  3896. inherited Create;
  3897. SetValues;
  3898. CalcValues;
  3899. end;
  3900. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3901. class function TglBitmapFormatDescriptor.GetByFormat(const aInternalFormat: GLenum): TglBitmapFormatDescriptor;
  3902. var
  3903. f: TglBitmapFormat;
  3904. begin
  3905. for f := Low(TglBitmapFormat) to High(TglBitmapFormat) do begin
  3906. result := TFormatDescriptor.Get(f);
  3907. if (result.glInternalFormat = aInternalFormat) then
  3908. exit;
  3909. end;
  3910. result := TFormatDescriptor.Get(tfEmpty);
  3911. end;
  3912. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3913. //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3914. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3915. class procedure TFormatDescriptor.Init;
  3916. begin
  3917. if not Assigned(FormatDescriptorCS) then
  3918. FormatDescriptorCS := TCriticalSection.Create;
  3919. end;
  3920. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3921. class function TFormatDescriptor.Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
  3922. begin
  3923. FormatDescriptorCS.Enter;
  3924. try
  3925. result := FormatDescriptors[aFormat];
  3926. if not Assigned(result) then begin
  3927. result := FORMAT_DESCRIPTOR_CLASSES[aFormat].Create;
  3928. FormatDescriptors[aFormat] := result;
  3929. end;
  3930. finally
  3931. FormatDescriptorCS.Leave;
  3932. end;
  3933. end;
  3934. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3935. class function TFormatDescriptor.GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
  3936. begin
  3937. result := Get(Get(aFormat).WithAlpha);
  3938. end;
  3939. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3940. class function TFormatDescriptor.GetFromMask(const aMask: TglBitmapRec4ul; const aBitCount: Integer): TFormatDescriptor;
  3941. var
  3942. ft: TglBitmapFormat;
  3943. begin
  3944. // find matching format with OpenGL support
  3945. for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
  3946. result := Get(ft);
  3947. if (result.MaskMatch(aMask)) and
  3948. (result.glFormat <> 0) and
  3949. (result.glInternalFormat <> 0) and
  3950. ((aBitCount = 0) or (aBitCount = result.BitsPerPixel))
  3951. then
  3952. exit;
  3953. end;
  3954. // find matching format without OpenGL Support
  3955. for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
  3956. result := Get(ft);
  3957. if result.MaskMatch(aMask) and ((aBitCount = 0) or (aBitCount = result.BitsPerPixel)) then
  3958. exit;
  3959. end;
  3960. result := TFormatDescriptor.Get(tfEmpty);
  3961. end;
  3962. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3963. class function TFormatDescriptor.GetFromPrecShift(const aPrec, aShift: TglBitmapRec4ub; const aBitCount: Integer): TFormatDescriptor;
  3964. var
  3965. ft: TglBitmapFormat;
  3966. begin
  3967. // find matching format with OpenGL support
  3968. for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
  3969. result := Get(ft);
  3970. if glBitmapRec4ubCompare(result.Shift, aShift) and
  3971. glBitmapRec4ubCompare(result.Precision, aPrec) and
  3972. (result.glFormat <> 0) and
  3973. (result.glInternalFormat <> 0) and
  3974. ((aBitCount = 0) or (aBitCount = result.BitsPerPixel))
  3975. then
  3976. exit;
  3977. end;
  3978. // find matching format without OpenGL Support
  3979. for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
  3980. result := Get(ft);
  3981. if glBitmapRec4ubCompare(result.Shift, aShift) and
  3982. glBitmapRec4ubCompare(result.Precision, aPrec) and
  3983. ((aBitCount = 0) or (aBitCount = result.BitsPerPixel)) then
  3984. exit;
  3985. end;
  3986. result := TFormatDescriptor.Get(tfEmpty);
  3987. end;
  3988. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3989. class procedure TFormatDescriptor.Clear;
  3990. var
  3991. f: TglBitmapFormat;
  3992. begin
  3993. FormatDescriptorCS.Enter;
  3994. try
  3995. for f := low(FormatDescriptors) to high(FormatDescriptors) do
  3996. FreeAndNil(FormatDescriptors[f]);
  3997. finally
  3998. FormatDescriptorCS.Leave;
  3999. end;
  4000. end;
  4001. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4002. class procedure TFormatDescriptor.Finalize;
  4003. begin
  4004. Clear;
  4005. FreeAndNil(FormatDescriptorCS);
  4006. end;
  4007. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4008. //TBitfieldFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4009. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4010. procedure TbmpBitfieldFormat.SetCustomValues(const aBPP: Integer; aMask: TglBitmapRec4ul);
  4011. var
  4012. i: Integer;
  4013. begin
  4014. for i := 0 to 3 do begin
  4015. fShift.arr[i] := 0;
  4016. while (aMask.arr[i] > 0) and (aMask.arr[i] and 1 > 0) do begin
  4017. aMask.arr[i] := aMask.arr[i] shr 1;
  4018. inc(fShift.arr[i]);
  4019. end;
  4020. fPrecision.arr[i] := CountSetBits(aMask.arr[i]);
  4021. end;
  4022. CalcValues;
  4023. end;
  4024. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4025. procedure TbmpBitfieldFormat.SetCustomValues(const aBBP: Integer; const aPrec, aShift: TglBitmapRec4ub);
  4026. begin
  4027. fBitsPerPixel := aBBP;
  4028. fPrecision := aPrec;
  4029. fShift := aShift;
  4030. CalcValues;
  4031. end;
  4032. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4033. procedure TbmpBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  4034. var
  4035. data: QWord;
  4036. begin
  4037. data :=
  4038. ((aPixel.Data.r and Range.r) shl Shift.r) or
  4039. ((aPixel.Data.g and Range.g) shl Shift.g) or
  4040. ((aPixel.Data.b and Range.b) shl Shift.b) or
  4041. ((aPixel.Data.a and Range.a) shl Shift.a);
  4042. case BitsPerPixel of
  4043. 8: aData^ := data;
  4044. 16: PWord(aData)^ := data;
  4045. 32: PCardinal(aData)^ := data;
  4046. 64: PQWord(aData)^ := data;
  4047. else
  4048. raise EglBitmap.CreateFmt('invalid pixel size: %d', [BitsPerPixel]);
  4049. end;
  4050. inc(aData, Round(BytesPerPixel));
  4051. end;
  4052. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4053. procedure TbmpBitfieldFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  4054. var
  4055. data: QWord;
  4056. i: Integer;
  4057. begin
  4058. case BitsPerPixel of
  4059. 8: data := aData^;
  4060. 16: data := PWord(aData)^;
  4061. 32: data := PCardinal(aData)^;
  4062. 64: data := PQWord(aData)^;
  4063. else
  4064. raise EglBitmap.CreateFmt('invalid pixel size: %d', [BitsPerPixel]);
  4065. end;
  4066. for i := 0 to 3 do
  4067. aPixel.Data.arr[i] := (data shr fShift.arr[i]) and Range.arr[i];
  4068. inc(aData, Round(BytesPerPixel));
  4069. end;
  4070. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4071. //TColorTableFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4072. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4073. procedure TbmpColorTableFormat.SetValues;
  4074. begin
  4075. inherited SetValues;
  4076. fShift := glBitmapRec4ub(8, 8, 8, 0);
  4077. end;
  4078. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4079. procedure TbmpColorTableFormat.SetCustomValues(const aFormat: TglBitmapFormat; const aBPP: Integer; const aPrec, aShift: TglBitmapRec4ub);
  4080. begin
  4081. fFormat := aFormat;
  4082. fBitsPerPixel := aBPP;
  4083. fPrecision := aPrec;
  4084. fShift := aShift;
  4085. CalcValues;
  4086. end;
  4087. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4088. procedure TbmpColorTableFormat.CalcValues;
  4089. begin
  4090. inherited CalcValues;
  4091. end;
  4092. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4093. procedure TbmpColorTableFormat.CreateColorTable;
  4094. var
  4095. i: Integer;
  4096. begin
  4097. SetLength(fColorTable, 256);
  4098. if not HasColor then begin
  4099. // alpha
  4100. for i := 0 to High(fColorTable) do begin
  4101. fColorTable[i].r := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
  4102. fColorTable[i].g := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
  4103. fColorTable[i].b := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
  4104. fColorTable[i].a := 0;
  4105. end;
  4106. end else begin
  4107. // normal
  4108. for i := 0 to High(fColorTable) do begin
  4109. fColorTable[i].r := Round(((i shr Shift.r) and Range.r) / Range.r * 255);
  4110. fColorTable[i].g := Round(((i shr Shift.g) and Range.g) / Range.g * 255);
  4111. fColorTable[i].b := Round(((i shr Shift.b) and Range.b) / Range.b * 255);
  4112. fColorTable[i].a := 0;
  4113. end;
  4114. end;
  4115. end;
  4116. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4117. procedure TbmpColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  4118. begin
  4119. if (BitsPerPixel <> 8) then
  4120. raise EglBitmapUnsupportedFormat.Create('color table are only supported for 8bit formats');
  4121. if not HasColor then
  4122. // alpha
  4123. aData^ := aPixel.Data.a
  4124. else
  4125. // normal
  4126. aData^ := Round(
  4127. ((aPixel.Data.r and Range.r) shl Shift.r) or
  4128. ((aPixel.Data.g and Range.g) shl Shift.g) or
  4129. ((aPixel.Data.b and Range.b) shl Shift.b));
  4130. inc(aData);
  4131. end;
  4132. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4133. procedure TbmpColorTableFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  4134. begin
  4135. if (BitsPerPixel <> 8) then
  4136. raise EglBitmapUnsupportedFormat.Create('color table are only supported for 8bit formats');
  4137. with fColorTable[aData^] do begin
  4138. aPixel.Data.r := r;
  4139. aPixel.Data.g := g;
  4140. aPixel.Data.b := b;
  4141. aPixel.Data.a := a;
  4142. end;
  4143. inc(aData, 1);
  4144. end;
  4145. destructor TbmpColorTableFormat.Destroy;
  4146. begin
  4147. SetLength(fColorTable, 0);
  4148. inherited Destroy;
  4149. end;
  4150. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4151. //TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4152. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4153. procedure glBitmapConvertPixel(var aPixel: TglBitmapPixelData; const aSourceFD, aDestFD: TFormatDescriptor);
  4154. var
  4155. i: Integer;
  4156. begin
  4157. for i := 0 to 3 do begin
  4158. if (aSourceFD.Range.arr[i] <> aDestFD.Range.arr[i]) then begin
  4159. if (aSourceFD.Range.arr[i] > 0) then
  4160. aPixel.Data.arr[i] := Round(aPixel.Data.arr[i] / aSourceFD.Range.arr[i] * aDestFD.Range.arr[i])
  4161. else
  4162. aPixel.Data.arr[i] := 0;
  4163. end;
  4164. end;
  4165. end;
  4166. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4167. procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
  4168. begin
  4169. with aFuncRec do begin
  4170. if (Source.Range.r > 0) then
  4171. Dest.Data.r := Source.Data.r;
  4172. if (Source.Range.g > 0) then
  4173. Dest.Data.g := Source.Data.g;
  4174. if (Source.Range.b > 0) then
  4175. Dest.Data.b := Source.Data.b;
  4176. if (Source.Range.a > 0) then
  4177. Dest.Data.a := Source.Data.a;
  4178. end;
  4179. end;
  4180. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4181. procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
  4182. var
  4183. i: Integer;
  4184. begin
  4185. with aFuncRec do begin
  4186. for i := 0 to 3 do
  4187. if (Source.Range.arr[i] > 0) then
  4188. Dest.Data.arr[i] := Round(Dest.Range.arr[i] * Source.Data.arr[i] / Source.Range.arr[i]);
  4189. end;
  4190. end;
  4191. type
  4192. TShiftData = packed record
  4193. case Integer of
  4194. 0: (r, g, b, a: SmallInt);
  4195. 1: (arr: array[0..3] of SmallInt);
  4196. end;
  4197. PShiftData = ^TShiftData;
  4198. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4199. procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
  4200. var
  4201. i: Integer;
  4202. begin
  4203. with aFuncRec do
  4204. for i := 0 to 3 do
  4205. if (Source.Range.arr[i] > 0) then
  4206. Dest.Data.arr[i] := Source.Data.arr[i] shr PShiftData(Args)^.arr[i];
  4207. end;
  4208. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4209. procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
  4210. begin
  4211. with aFuncRec do begin
  4212. Dest.Data := Source.Data;
  4213. if ({%H-}PtrUInt(Args) and $1 > 0) then begin
  4214. Dest.Data.r := Dest.Data.r xor Dest.Range.r;
  4215. Dest.Data.g := Dest.Data.g xor Dest.Range.g;
  4216. Dest.Data.b := Dest.Data.b xor Dest.Range.b;
  4217. end;
  4218. if ({%H-}PtrUInt(Args) and $2 > 0) then begin
  4219. Dest.Data.a := Dest.Data.a xor Dest.Range.a;
  4220. end;
  4221. end;
  4222. end;
  4223. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4224. procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
  4225. var
  4226. i: Integer;
  4227. begin
  4228. with aFuncRec do begin
  4229. for i := 0 to 3 do
  4230. Dest.Data.arr[i] := PglBitmapPixelData(Args)^.Data.arr[i];
  4231. end;
  4232. end;
  4233. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4234. procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
  4235. var
  4236. Temp: Single;
  4237. begin
  4238. with FuncRec do begin
  4239. if (FuncRec.Args = nil) then begin //source has no alpha
  4240. Temp :=
  4241. Source.Data.r / Source.Range.r * ALPHA_WEIGHT_R +
  4242. Source.Data.g / Source.Range.g * ALPHA_WEIGHT_G +
  4243. Source.Data.b / Source.Range.b * ALPHA_WEIGHT_B;
  4244. Dest.Data.a := Round(Dest.Range.a * Temp);
  4245. end else
  4246. Dest.Data.a := Round(Source.Data.a / Source.Range.a * Dest.Range.a);
  4247. end;
  4248. end;
  4249. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4250. procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
  4251. type
  4252. PglBitmapPixelData = ^TglBitmapPixelData;
  4253. begin
  4254. with FuncRec do begin
  4255. Dest.Data.r := Source.Data.r;
  4256. Dest.Data.g := Source.Data.g;
  4257. Dest.Data.b := Source.Data.b;
  4258. with PglBitmapPixelData(Args)^ do
  4259. if ((Dest.Data.r <= Data.r) and (Dest.Data.r >= Range.r) and
  4260. (Dest.Data.g <= Data.g) and (Dest.Data.g >= Range.g) and
  4261. (Dest.Data.b <= Data.b) and (Dest.Data.b >= Range.b)) then
  4262. Dest.Data.a := 0
  4263. else
  4264. Dest.Data.a := Dest.Range.a;
  4265. end;
  4266. end;
  4267. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4268. procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
  4269. begin
  4270. with FuncRec do begin
  4271. Dest.Data.r := Source.Data.r;
  4272. Dest.Data.g := Source.Data.g;
  4273. Dest.Data.b := Source.Data.b;
  4274. Dest.Data.a := PCardinal(Args)^;
  4275. end;
  4276. end;
  4277. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4278. procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
  4279. type
  4280. PRGBPix = ^TRGBPix;
  4281. TRGBPix = array [0..2] of byte;
  4282. var
  4283. Temp: Byte;
  4284. begin
  4285. while aWidth > 0 do begin
  4286. Temp := PRGBPix(aData)^[0];
  4287. PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
  4288. PRGBPix(aData)^[2] := Temp;
  4289. if aHasAlpha then
  4290. Inc(aData, 4)
  4291. else
  4292. Inc(aData, 3);
  4293. dec(aWidth);
  4294. end;
  4295. end;
  4296. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4297. //TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4298. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4299. function TglBitmap.GetFormatDesc: TglBitmapFormatDescriptor;
  4300. begin
  4301. result := TFormatDescriptor.Get(Format);
  4302. end;
  4303. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4304. function TglBitmap.GetWidth: Integer;
  4305. begin
  4306. if (ffX in fDimension.Fields) then
  4307. result := fDimension.X
  4308. else
  4309. result := -1;
  4310. end;
  4311. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4312. function TglBitmap.GetHeight: Integer;
  4313. begin
  4314. if (ffY in fDimension.Fields) then
  4315. result := fDimension.Y
  4316. else
  4317. result := -1;
  4318. end;
  4319. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4320. function TglBitmap.GetFileWidth: Integer;
  4321. begin
  4322. result := Max(1, Width);
  4323. end;
  4324. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4325. function TglBitmap.GetFileHeight: Integer;
  4326. begin
  4327. result := Max(1, Height);
  4328. end;
  4329. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4330. procedure TglBitmap.SetCustomData(const aValue: Pointer);
  4331. begin
  4332. if fCustomData = aValue then
  4333. exit;
  4334. fCustomData := aValue;
  4335. end;
  4336. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4337. procedure TglBitmap.SetCustomName(const aValue: String);
  4338. begin
  4339. if fCustomName = aValue then
  4340. exit;
  4341. fCustomName := aValue;
  4342. end;
  4343. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4344. procedure TglBitmap.SetCustomNameW(const aValue: WideString);
  4345. begin
  4346. if fCustomNameW = aValue then
  4347. exit;
  4348. fCustomNameW := aValue;
  4349. end;
  4350. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4351. procedure TglBitmap.SetFreeDataOnDestroy(const aValue: Boolean);
  4352. begin
  4353. if fFreeDataOnDestroy = aValue then
  4354. exit;
  4355. fFreeDataOnDestroy := aValue;
  4356. end;
  4357. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4358. procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
  4359. begin
  4360. if fDeleteTextureOnFree = aValue then
  4361. exit;
  4362. fDeleteTextureOnFree := aValue;
  4363. end;
  4364. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4365. procedure TglBitmap.SetFormat(const aValue: TglBitmapFormat);
  4366. begin
  4367. if fFormat = aValue then
  4368. exit;
  4369. if TFormatDescriptor.Get(Format).BitsPerPixel <> TFormatDescriptor.Get(aValue).BitsPerPixel then
  4370. raise EglBitmapUnsupportedFormat.Create(Format);
  4371. SetDataPointer(fData, aValue, Width, Height); //be careful, Data could be freed by this method
  4372. end;
  4373. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4374. procedure TglBitmap.SetFreeDataAfterGenTexture(const aValue: Boolean);
  4375. begin
  4376. if fFreeDataAfterGenTexture = aValue then
  4377. exit;
  4378. fFreeDataAfterGenTexture := aValue;
  4379. end;
  4380. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4381. procedure TglBitmap.SetID(const aValue: Cardinal);
  4382. begin
  4383. if fID = aValue then
  4384. exit;
  4385. fID := aValue;
  4386. end;
  4387. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4388. procedure TglBitmap.SetMipMap(const aValue: TglBitmapMipMap);
  4389. begin
  4390. if fMipMap = aValue then
  4391. exit;
  4392. fMipMap := aValue;
  4393. end;
  4394. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4395. procedure TglBitmap.SetTarget(const aValue: Cardinal);
  4396. begin
  4397. if fTarget = aValue then
  4398. exit;
  4399. fTarget := aValue;
  4400. end;
  4401. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4402. procedure TglBitmap.SetAnisotropic(const aValue: Integer);
  4403. {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_EXT)}
  4404. var
  4405. MaxAnisotropic: Integer;
  4406. {$IFEND}
  4407. begin
  4408. fAnisotropic := aValue;
  4409. if (ID > 0) then begin
  4410. {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_EXT)}
  4411. if GL_EXT_texture_filter_anisotropic then begin
  4412. if fAnisotropic > 0 then begin
  4413. Bind(false);
  4414. glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
  4415. if aValue > MaxAnisotropic then
  4416. fAnisotropic := MaxAnisotropic;
  4417. glTexParameteri(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, fAnisotropic);
  4418. end;
  4419. end else begin
  4420. fAnisotropic := 0;
  4421. end;
  4422. {$ELSE}
  4423. fAnisotropic := 0;
  4424. {$IFEND}
  4425. end;
  4426. end;
  4427. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4428. procedure TglBitmap.CreateID;
  4429. begin
  4430. if (ID <> 0) then
  4431. glDeleteTextures(1, @fID);
  4432. glGenTextures(1, @fID);
  4433. Bind(false);
  4434. end;
  4435. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4436. procedure TglBitmap.SetupParameters({$IFNDEF OPENGL_ES}out aBuildWithGlu: Boolean{$ENDIF});
  4437. begin
  4438. // Set Up Parameters
  4439. SetWrap(fWrapS, fWrapT, fWrapR);
  4440. SetFilter(fFilterMin, fFilterMag);
  4441. SetAnisotropic(fAnisotropic);
  4442. {$IFNDEF OPENGL_ES}
  4443. SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
  4444. if (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
  4445. SetSwizzle(fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
  4446. {$ENDIF}
  4447. {$IFNDEF OPENGL_ES}
  4448. // Mip Maps Generation Mode
  4449. aBuildWithGlu := false;
  4450. if (MipMap = mmMipmap) then begin
  4451. if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
  4452. glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
  4453. else
  4454. aBuildWithGlu := true;
  4455. end else if (MipMap = mmMipmapGlu) then
  4456. aBuildWithGlu := true;
  4457. {$ELSE}
  4458. if (MipMap = mmMipmap) then
  4459. glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE);
  4460. {$ENDIF}
  4461. end;
  4462. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4463. procedure TglBitmap.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
  4464. const aWidth: Integer; const aHeight: Integer);
  4465. var
  4466. s: Single;
  4467. begin
  4468. if (Data <> aData) then begin
  4469. if (Assigned(Data)) then
  4470. FreeMem(Data);
  4471. fData := aData;
  4472. end;
  4473. if not Assigned(fData) then begin
  4474. fPixelSize := 0;
  4475. fRowSize := 0;
  4476. end else begin
  4477. FillChar(fDimension, SizeOf(fDimension), 0);
  4478. if aWidth <> -1 then begin
  4479. fDimension.Fields := fDimension.Fields + [ffX];
  4480. fDimension.X := aWidth;
  4481. end;
  4482. if aHeight <> -1 then begin
  4483. fDimension.Fields := fDimension.Fields + [ffY];
  4484. fDimension.Y := aHeight;
  4485. end;
  4486. s := TFormatDescriptor.Get(aFormat).BytesPerPixel;
  4487. fFormat := aFormat;
  4488. fPixelSize := Ceil(s);
  4489. fRowSize := Ceil(s * aWidth);
  4490. end;
  4491. end;
  4492. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4493. function TglBitmap.FlipHorz: Boolean;
  4494. begin
  4495. result := false;
  4496. end;
  4497. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4498. function TglBitmap.FlipVert: Boolean;
  4499. begin
  4500. result := false;
  4501. end;
  4502. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4503. //TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4504. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4505. procedure TglBitmap.AfterConstruction;
  4506. begin
  4507. inherited AfterConstruction;
  4508. fID := 0;
  4509. fTarget := 0;
  4510. {$IFNDEF OPENGL_ES}
  4511. fIsResident := false;
  4512. {$ENDIF}
  4513. fMipMap := glBitmapDefaultMipmap;
  4514. fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
  4515. fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
  4516. glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
  4517. glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
  4518. {$IFNDEF OPENGL_ES}
  4519. glBitmapGetDefaultSwizzle (fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
  4520. {$ENDIF}
  4521. end;
  4522. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4523. procedure TglBitmap.BeforeDestruction;
  4524. var
  4525. NewData: PByte;
  4526. begin
  4527. if fFreeDataOnDestroy then begin
  4528. NewData := nil;
  4529. SetDataPointer(NewData, tfEmpty); //be careful, Data could be freed by this method
  4530. end;
  4531. if (fID > 0) and fDeleteTextureOnFree then
  4532. glDeleteTextures(1, @fID);
  4533. inherited BeforeDestruction;
  4534. end;
  4535. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4536. procedure TglBitmap.PrepareResType(var aResource: String; var aResType: PChar);
  4537. var
  4538. TempPos: Integer;
  4539. begin
  4540. if not Assigned(aResType) then begin
  4541. TempPos := Pos('.', aResource);
  4542. aResType := PChar(UpperCase(Copy(aResource, TempPos + 1, Length(aResource) - TempPos)));
  4543. aResource := UpperCase(Copy(aResource, 0, TempPos -1));
  4544. end;
  4545. end;
  4546. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4547. procedure TglBitmap.LoadFromFile(const aFilename: String);
  4548. var
  4549. fs: TFileStream;
  4550. begin
  4551. if not FileExists(aFilename) then
  4552. raise EglBitmap.Create('file does not exist: ' + aFilename);
  4553. fFilename := aFilename;
  4554. fs := TFileStream.Create(fFilename, fmOpenRead);
  4555. try
  4556. fs.Position := 0;
  4557. LoadFromStream(fs);
  4558. finally
  4559. fs.Free;
  4560. end;
  4561. end;
  4562. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4563. procedure TglBitmap.LoadFromStream(const aStream: TStream);
  4564. begin
  4565. {$IFDEF GLB_SUPPORT_PNG_READ}
  4566. if not LoadPNG(aStream) then
  4567. {$ENDIF}
  4568. {$IFDEF GLB_SUPPORT_JPEG_READ}
  4569. if not LoadJPEG(aStream) then
  4570. {$ENDIF}
  4571. if not LoadDDS(aStream) then
  4572. if not LoadTGA(aStream) then
  4573. if not LoadBMP(aStream) then
  4574. if not LoadRAW(aStream) then
  4575. raise EglBitmap.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
  4576. end;
  4577. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4578. procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapSize; const aFunc: TglBitmapFunction;
  4579. const aFormat: TglBitmapFormat; const aArgs: Pointer);
  4580. var
  4581. tmpData: PByte;
  4582. size: Integer;
  4583. begin
  4584. size := TFormatDescriptor.Get(aFormat).GetSize(aSize);
  4585. GetMem(tmpData, size);
  4586. try
  4587. FillChar(tmpData^, size, #$FF);
  4588. SetDataPointer(tmpData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
  4589. except
  4590. if Assigned(tmpData) then
  4591. FreeMem(tmpData);
  4592. raise;
  4593. end;
  4594. Convert(Self, aFunc, false, aFormat, aArgs);
  4595. end;
  4596. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4597. procedure TglBitmap.LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar);
  4598. var
  4599. rs: TResourceStream;
  4600. begin
  4601. PrepareResType(aResource, aResType);
  4602. rs := TResourceStream.Create(aInstance, aResource, aResType);
  4603. try
  4604. LoadFromStream(rs);
  4605. finally
  4606. rs.Free;
  4607. end;
  4608. end;
  4609. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4610. procedure TglBitmap.LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
  4611. var
  4612. rs: TResourceStream;
  4613. begin
  4614. rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
  4615. try
  4616. LoadFromStream(rs);
  4617. finally
  4618. rs.Free;
  4619. end;
  4620. end;
  4621. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4622. procedure TglBitmap.SaveToFile(const aFilename: String; const aFileType: TglBitmapFileType);
  4623. var
  4624. fs: TFileStream;
  4625. begin
  4626. fs := TFileStream.Create(aFileName, fmCreate);
  4627. try
  4628. fs.Position := 0;
  4629. SaveToStream(fs, aFileType);
  4630. finally
  4631. fs.Free;
  4632. end;
  4633. end;
  4634. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4635. procedure TglBitmap.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
  4636. begin
  4637. case aFileType of
  4638. {$IFDEF GLB_SUPPORT_PNG_WRITE}
  4639. ftPNG: SavePNG(aStream);
  4640. {$ENDIF}
  4641. {$IFDEF GLB_SUPPORT_JPEG_WRITE}
  4642. ftJPEG: SaveJPEG(aStream);
  4643. {$ENDIF}
  4644. ftDDS: SaveDDS(aStream);
  4645. ftTGA: SaveTGA(aStream);
  4646. ftBMP: SaveBMP(aStream);
  4647. ftRAW: SaveRAW(aStream);
  4648. end;
  4649. end;
  4650. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4651. function TglBitmap.Convert(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer): Boolean;
  4652. begin
  4653. result := Convert(Self, aFunc, aCreateTemp, Format, aArgs);
  4654. end;
  4655. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4656. function TglBitmap.Convert(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
  4657. const aFormat: TglBitmapFormat; const aArgs: Pointer): Boolean;
  4658. var
  4659. DestData, TmpData, SourceData: pByte;
  4660. TempHeight, TempWidth: Integer;
  4661. SourceFD, DestFD: TFormatDescriptor;
  4662. SourceMD, DestMD: Pointer;
  4663. FuncRec: TglBitmapFunctionRec;
  4664. begin
  4665. Assert(Assigned(Data));
  4666. Assert(Assigned(aSource));
  4667. Assert(Assigned(aSource.Data));
  4668. result := false;
  4669. if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
  4670. SourceFD := TFormatDescriptor.Get(aSource.Format);
  4671. DestFD := TFormatDescriptor.Get(aFormat);
  4672. if (SourceFD.IsCompressed) then
  4673. raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', SourceFD.Format);
  4674. if (DestFD.IsCompressed) then
  4675. raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', DestFD.Format);
  4676. // inkompatible Formats so CreateTemp
  4677. if (SourceFD.BitsPerPixel <> DestFD.BitsPerPixel) then
  4678. aCreateTemp := true;
  4679. // Values
  4680. TempHeight := Max(1, aSource.Height);
  4681. TempWidth := Max(1, aSource.Width);
  4682. FuncRec.Sender := Self;
  4683. FuncRec.Args := aArgs;
  4684. TmpData := nil;
  4685. if aCreateTemp then begin
  4686. GetMem(TmpData, DestFD.GetSize(TempWidth, TempHeight));
  4687. DestData := TmpData;
  4688. end else
  4689. DestData := Data;
  4690. try
  4691. SourceFD.PreparePixel(FuncRec.Source);
  4692. DestFD.PreparePixel (FuncRec.Dest);
  4693. SourceMD := SourceFD.CreateMappingData;
  4694. DestMD := DestFD.CreateMappingData;
  4695. FuncRec.Size := aSource.Dimension;
  4696. FuncRec.Position.Fields := FuncRec.Size.Fields;
  4697. try
  4698. SourceData := aSource.Data;
  4699. FuncRec.Position.Y := 0;
  4700. while FuncRec.Position.Y < TempHeight do begin
  4701. FuncRec.Position.X := 0;
  4702. while FuncRec.Position.X < TempWidth do begin
  4703. SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
  4704. aFunc(FuncRec);
  4705. DestFD.Map(FuncRec.Dest, DestData, DestMD);
  4706. inc(FuncRec.Position.X);
  4707. end;
  4708. inc(FuncRec.Position.Y);
  4709. end;
  4710. // Updating Image or InternalFormat
  4711. if aCreateTemp then
  4712. SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height) //be careful, Data could be freed by this method
  4713. else if (aFormat <> fFormat) then
  4714. Format := aFormat;
  4715. result := true;
  4716. finally
  4717. SourceFD.FreeMappingData(SourceMD);
  4718. DestFD.FreeMappingData(DestMD);
  4719. end;
  4720. except
  4721. if aCreateTemp and Assigned(TmpData) then
  4722. FreeMem(TmpData);
  4723. raise;
  4724. end;
  4725. end;
  4726. end;
  4727. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4728. function TglBitmap.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
  4729. var
  4730. SourceFD, DestFD: TFormatDescriptor;
  4731. SourcePD, DestPD: TglBitmapPixelData;
  4732. ShiftData: TShiftData;
  4733. function DataIsIdentical: Boolean;
  4734. begin
  4735. result := SourceFD.MaskMatch(DestFD.Mask);
  4736. end;
  4737. function CanCopyDirect: Boolean;
  4738. begin
  4739. result :=
  4740. ((SourcePD.Range.r = DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
  4741. ((SourcePD.Range.g = DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
  4742. ((SourcePD.Range.b = DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
  4743. ((SourcePD.Range.a = DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
  4744. end;
  4745. function CanShift: Boolean;
  4746. begin
  4747. result :=
  4748. ((SourcePD.Range.r >= DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
  4749. ((SourcePD.Range.g >= DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
  4750. ((SourcePD.Range.b >= DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
  4751. ((SourcePD.Range.a >= DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
  4752. end;
  4753. function GetShift(aSource, aDest: Cardinal) : ShortInt;
  4754. begin
  4755. result := 0;
  4756. while (aSource > aDest) and (aSource > 0) do begin
  4757. inc(result);
  4758. aSource := aSource shr 1;
  4759. end;
  4760. end;
  4761. begin
  4762. if (aFormat <> fFormat) and (aFormat <> tfEmpty) then begin
  4763. SourceFD := TFormatDescriptor.Get(Format);
  4764. DestFD := TFormatDescriptor.Get(aFormat);
  4765. if DataIsIdentical then begin
  4766. result := true;
  4767. Format := aFormat;
  4768. exit;
  4769. end;
  4770. SourceFD.PreparePixel(SourcePD);
  4771. DestFD.PreparePixel (DestPD);
  4772. if CanCopyDirect then
  4773. result := Convert(Self, glBitmapConvertCopyFunc, false, aFormat)
  4774. else if CanShift then begin
  4775. ShiftData.r := GetShift(SourcePD.Range.r, DestPD.Range.r);
  4776. ShiftData.g := GetShift(SourcePD.Range.g, DestPD.Range.g);
  4777. ShiftData.b := GetShift(SourcePD.Range.b, DestPD.Range.b);
  4778. ShiftData.a := GetShift(SourcePD.Range.a, DestPD.Range.a);
  4779. result := Convert(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, @ShiftData);
  4780. end else
  4781. result := Convert(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
  4782. end else
  4783. result := true;
  4784. end;
  4785. {$IFDEF GLB_SDL}
  4786. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4787. function TglBitmap.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
  4788. var
  4789. Row, RowSize: Integer;
  4790. SourceData, TmpData: PByte;
  4791. TempDepth: Integer;
  4792. FormatDesc: TFormatDescriptor;
  4793. function GetRowPointer(Row: Integer): pByte;
  4794. begin
  4795. result := aSurface.pixels;
  4796. Inc(result, Row * RowSize);
  4797. end;
  4798. begin
  4799. result := false;
  4800. FormatDesc := TFormatDescriptor.Get(Format);
  4801. if FormatDesc.IsCompressed then
  4802. raise EglBitmapUnsupportedFormat.Create(Format);
  4803. if Assigned(Data) then begin
  4804. case Trunc(FormatDesc.PixelSize) of
  4805. 1: TempDepth := 8;
  4806. 2: TempDepth := 16;
  4807. 3: TempDepth := 24;
  4808. 4: TempDepth := 32;
  4809. else
  4810. raise EglBitmapUnsupportedFormat.Create(Format);
  4811. end;
  4812. aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
  4813. FormatDesc.RedMask, FormatDesc.GreenMask, FormatDesc.BlueMask, FormatDesc.AlphaMask);
  4814. SourceData := Data;
  4815. RowSize := FormatDesc.GetSize(FileWidth, 1);
  4816. for Row := 0 to FileHeight-1 do begin
  4817. TmpData := GetRowPointer(Row);
  4818. if Assigned(TmpData) then begin
  4819. Move(SourceData^, TmpData^, RowSize);
  4820. inc(SourceData, RowSize);
  4821. end;
  4822. end;
  4823. result := true;
  4824. end;
  4825. end;
  4826. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4827. function TglBitmap.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
  4828. var
  4829. pSource, pData, pTempData: PByte;
  4830. Row, RowSize, TempWidth, TempHeight: Integer;
  4831. IntFormat: TglBitmapFormat;
  4832. fd: TFormatDescriptor;
  4833. Mask: TglBitmapMask;
  4834. function GetRowPointer(Row: Integer): pByte;
  4835. begin
  4836. result := aSurface^.pixels;
  4837. Inc(result, Row * RowSize);
  4838. end;
  4839. begin
  4840. result := false;
  4841. if (Assigned(aSurface)) then begin
  4842. with aSurface^.format^ do begin
  4843. Mask.r := RMask;
  4844. Mask.g := GMask;
  4845. Mask.b := BMask;
  4846. Mask.a := AMask;
  4847. IntFormat := TFormatDescriptor.GetFromMask(Mask).Format;
  4848. if (IntFormat = tfEmpty) then
  4849. raise EglBitmap.Create('AssignFromSurface - Invalid Pixelformat.');
  4850. end;
  4851. fd := TFormatDescriptor.Get(IntFormat);
  4852. TempWidth := aSurface^.w;
  4853. TempHeight := aSurface^.h;
  4854. RowSize := fd.GetSize(TempWidth, 1);
  4855. GetMem(pData, TempHeight * RowSize);
  4856. try
  4857. pTempData := pData;
  4858. for Row := 0 to TempHeight -1 do begin
  4859. pSource := GetRowPointer(Row);
  4860. if (Assigned(pSource)) then begin
  4861. Move(pSource^, pTempData^, RowSize);
  4862. Inc(pTempData, RowSize);
  4863. end;
  4864. end;
  4865. SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
  4866. result := true;
  4867. except
  4868. if Assigned(pData) then
  4869. FreeMem(pData);
  4870. raise;
  4871. end;
  4872. end;
  4873. end;
  4874. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4875. function TglBitmap.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
  4876. var
  4877. Row, Col, AlphaInterleave: Integer;
  4878. pSource, pDest: PByte;
  4879. function GetRowPointer(Row: Integer): pByte;
  4880. begin
  4881. result := aSurface.pixels;
  4882. Inc(result, Row * Width);
  4883. end;
  4884. begin
  4885. result := false;
  4886. if Assigned(Data) then begin
  4887. if Format in [tfAlpha8ub1, tfLuminance8Alpha8ub2, tfBGRA8ub4, tfRGBA8ub4] then begin
  4888. aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
  4889. AlphaInterleave := 0;
  4890. case Format of
  4891. tfLuminance8Alpha8ub2:
  4892. AlphaInterleave := 1;
  4893. tfBGRA8ub4, tfRGBA8ub4:
  4894. AlphaInterleave := 3;
  4895. end;
  4896. pSource := Data;
  4897. for Row := 0 to Height -1 do begin
  4898. pDest := GetRowPointer(Row);
  4899. if Assigned(pDest) then begin
  4900. for Col := 0 to Width -1 do begin
  4901. Inc(pSource, AlphaInterleave);
  4902. pDest^ := pSource^;
  4903. Inc(pDest);
  4904. Inc(pSource);
  4905. end;
  4906. end;
  4907. end;
  4908. result := true;
  4909. end;
  4910. end;
  4911. end;
  4912. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4913. function TglBitmap.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  4914. var
  4915. bmp: TglBitmap2D;
  4916. begin
  4917. bmp := TglBitmap2D.Create;
  4918. try
  4919. bmp.AssignFromSurface(aSurface);
  4920. result := AddAlphaFromGlBitmap(bmp, aFunc, aArgs);
  4921. finally
  4922. bmp.Free;
  4923. end;
  4924. end;
  4925. {$ENDIF}
  4926. {$IFDEF GLB_DELPHI}
  4927. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4928. function CreateGrayPalette: HPALETTE;
  4929. var
  4930. Idx: Integer;
  4931. Pal: PLogPalette;
  4932. begin
  4933. GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
  4934. Pal.palVersion := $300;
  4935. Pal.palNumEntries := 256;
  4936. for Idx := 0 to Pal.palNumEntries - 1 do begin
  4937. Pal.palPalEntry[Idx].peRed := Idx;
  4938. Pal.palPalEntry[Idx].peGreen := Idx;
  4939. Pal.palPalEntry[Idx].peBlue := Idx;
  4940. Pal.palPalEntry[Idx].peFlags := 0;
  4941. end;
  4942. Result := CreatePalette(Pal^);
  4943. FreeMem(Pal);
  4944. end;
  4945. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4946. function TglBitmap.AssignToBitmap(const aBitmap: TBitmap): Boolean;
  4947. var
  4948. Row: Integer;
  4949. pSource, pData: PByte;
  4950. begin
  4951. result := false;
  4952. if Assigned(Data) then begin
  4953. if Assigned(aBitmap) then begin
  4954. aBitmap.Width := Width;
  4955. aBitmap.Height := Height;
  4956. case Format of
  4957. tfAlpha8ub1, tfLuminance8ub1: begin
  4958. aBitmap.PixelFormat := pf8bit;
  4959. aBitmap.Palette := CreateGrayPalette;
  4960. end;
  4961. tfRGB5A1us1:
  4962. aBitmap.PixelFormat := pf15bit;
  4963. tfR5G6B5us1:
  4964. aBitmap.PixelFormat := pf16bit;
  4965. tfRGB8ub3, tfBGR8ub3:
  4966. aBitmap.PixelFormat := pf24bit;
  4967. tfRGBA8ub4, tfBGRA8ub4:
  4968. aBitmap.PixelFormat := pf32bit;
  4969. else
  4970. raise EglBitmap.Create('AssignToBitmap - Invalid Pixelformat.');
  4971. end;
  4972. pSource := Data;
  4973. for Row := 0 to FileHeight -1 do begin
  4974. pData := aBitmap.Scanline[Row];
  4975. Move(pSource^, pData^, fRowSize);
  4976. Inc(pSource, fRowSize);
  4977. if (Format in [tfRGB8ub3, tfRGBA8ub4]) then // swap RGB(A) to BGR(A)
  4978. SwapRGB(pData, FileWidth, Format = tfRGBA8ub4);
  4979. end;
  4980. result := true;
  4981. end;
  4982. end;
  4983. end;
  4984. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4985. function TglBitmap.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
  4986. var
  4987. pSource, pData, pTempData: PByte;
  4988. Row, RowSize, TempWidth, TempHeight: Integer;
  4989. IntFormat: TglBitmapFormat;
  4990. begin
  4991. result := false;
  4992. if (Assigned(aBitmap)) then begin
  4993. case aBitmap.PixelFormat of
  4994. pf8bit:
  4995. IntFormat := tfLuminance8ub1;
  4996. pf15bit:
  4997. IntFormat := tfRGB5A1us1;
  4998. pf16bit:
  4999. IntFormat := tfR5G6B5us1;
  5000. pf24bit:
  5001. IntFormat := tfBGR8ub3;
  5002. pf32bit:
  5003. IntFormat := tfBGRA8ub4;
  5004. else
  5005. raise EglBitmap.Create('AssignFromBitmap - Invalid Pixelformat.');
  5006. end;
  5007. TempWidth := aBitmap.Width;
  5008. TempHeight := aBitmap.Height;
  5009. RowSize := TFormatDescriptor.Get(IntFormat).GetSize(TempWidth, 1);
  5010. GetMem(pData, TempHeight * RowSize);
  5011. try
  5012. pTempData := pData;
  5013. for Row := 0 to TempHeight -1 do begin
  5014. pSource := aBitmap.Scanline[Row];
  5015. if (Assigned(pSource)) then begin
  5016. Move(pSource^, pTempData^, RowSize);
  5017. Inc(pTempData, RowSize);
  5018. end;
  5019. end;
  5020. SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
  5021. result := true;
  5022. except
  5023. if Assigned(pData) then
  5024. FreeMem(pData);
  5025. raise;
  5026. end;
  5027. end;
  5028. end;
  5029. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5030. function TglBitmap.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
  5031. var
  5032. Row, Col, AlphaInterleave: Integer;
  5033. pSource, pDest: PByte;
  5034. begin
  5035. result := false;
  5036. if Assigned(Data) then begin
  5037. if (Format in [tfAlpha8ub1, tfLuminance8Alpha8ub2, tfRGBA8ub4, tfBGRA8ub4]) then begin
  5038. if Assigned(aBitmap) then begin
  5039. aBitmap.PixelFormat := pf8bit;
  5040. aBitmap.Palette := CreateGrayPalette;
  5041. aBitmap.Width := Width;
  5042. aBitmap.Height := Height;
  5043. case Format of
  5044. tfLuminance8Alpha8ub2:
  5045. AlphaInterleave := 1;
  5046. tfRGBA8ub4, tfBGRA8ub4:
  5047. AlphaInterleave := 3;
  5048. else
  5049. AlphaInterleave := 0;
  5050. end;
  5051. // Copy Data
  5052. pSource := Data;
  5053. for Row := 0 to Height -1 do begin
  5054. pDest := aBitmap.Scanline[Row];
  5055. if Assigned(pDest) then begin
  5056. for Col := 0 to Width -1 do begin
  5057. Inc(pSource, AlphaInterleave);
  5058. pDest^ := pSource^;
  5059. Inc(pDest);
  5060. Inc(pSource);
  5061. end;
  5062. end;
  5063. end;
  5064. result := true;
  5065. end;
  5066. end;
  5067. end;
  5068. end;
  5069. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5070. function TglBitmap.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  5071. var
  5072. tex: TglBitmap2D;
  5073. begin
  5074. tex := TglBitmap2D.Create;
  5075. try
  5076. tex.AssignFromBitmap(ABitmap);
  5077. result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
  5078. finally
  5079. tex.Free;
  5080. end;
  5081. end;
  5082. {$ENDIF}
  5083. {$IFDEF GLB_LAZARUS}
  5084. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5085. function TglBitmap.AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
  5086. var
  5087. rid: TRawImageDescription;
  5088. FormatDesc: TFormatDescriptor;
  5089. begin
  5090. if not Assigned(Data) then
  5091. raise EglBitmap.Create('no pixel data assigned. load data before save');
  5092. result := false;
  5093. if not Assigned(aImage) or (Format = tfEmpty) then
  5094. exit;
  5095. FormatDesc := TFormatDescriptor.Get(Format);
  5096. if FormatDesc.IsCompressed then
  5097. exit;
  5098. FillChar(rid{%H-}, SizeOf(rid), 0);
  5099. if FormatDesc.IsGrayscale then
  5100. rid.Format := ricfGray
  5101. else
  5102. rid.Format := ricfRGBA;
  5103. rid.Width := Width;
  5104. rid.Height := Height;
  5105. rid.Depth := FormatDesc.BitsPerPixel;
  5106. rid.BitOrder := riboBitsInOrder;
  5107. rid.ByteOrder := riboLSBFirst;
  5108. rid.LineOrder := riloTopToBottom;
  5109. rid.LineEnd := rileTight;
  5110. rid.BitsPerPixel := FormatDesc.BitsPerPixel;
  5111. rid.RedPrec := CountSetBits(FormatDesc.Range.r);
  5112. rid.GreenPrec := CountSetBits(FormatDesc.Range.g);
  5113. rid.BluePrec := CountSetBits(FormatDesc.Range.b);
  5114. rid.AlphaPrec := CountSetBits(FormatDesc.Range.a);
  5115. rid.RedShift := FormatDesc.Shift.r;
  5116. rid.GreenShift := FormatDesc.Shift.g;
  5117. rid.BlueShift := FormatDesc.Shift.b;
  5118. rid.AlphaShift := FormatDesc.Shift.a;
  5119. rid.MaskBitsPerPixel := 0;
  5120. rid.PaletteColorCount := 0;
  5121. aImage.DataDescription := rid;
  5122. aImage.CreateData;
  5123. if not Assigned(aImage.PixelData) then
  5124. raise EglBitmap.Create('error while creating LazIntfImage');
  5125. Move(Data^, aImage.PixelData^, FormatDesc.GetSize(Dimension));
  5126. result := true;
  5127. end;
  5128. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5129. function TglBitmap.AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
  5130. var
  5131. f: TglBitmapFormat;
  5132. FormatDesc: TFormatDescriptor;
  5133. ImageData: PByte;
  5134. ImageSize: Integer;
  5135. CanCopy: Boolean;
  5136. Mask: TglBitmapRec4ul;
  5137. procedure CopyConvert;
  5138. var
  5139. bfFormat: TbmpBitfieldFormat;
  5140. pSourceLine, pDestLine: PByte;
  5141. pSourceMD, pDestMD: Pointer;
  5142. Shift, Prec: TglBitmapRec4ub;
  5143. x, y: Integer;
  5144. pixel: TglBitmapPixelData;
  5145. begin
  5146. bfFormat := TbmpBitfieldFormat.Create;
  5147. with aImage.DataDescription do begin
  5148. Prec.r := RedPrec;
  5149. Prec.g := GreenPrec;
  5150. Prec.b := BluePrec;
  5151. Prec.a := AlphaPrec;
  5152. Shift.r := RedShift;
  5153. Shift.g := GreenShift;
  5154. Shift.b := BlueShift;
  5155. Shift.a := AlphaShift;
  5156. bfFormat.SetCustomValues(BitsPerPixel, Prec, Shift);
  5157. end;
  5158. pSourceMD := bfFormat.CreateMappingData;
  5159. pDestMD := FormatDesc.CreateMappingData;
  5160. try
  5161. for y := 0 to aImage.Height-1 do begin
  5162. pSourceLine := aImage.PixelData + y {%H-}* aImage.DataDescription.BytesPerLine;
  5163. pDestLine := ImageData + y * Round(FormatDesc.BytesPerPixel * aImage.Width);
  5164. for x := 0 to aImage.Width-1 do begin
  5165. bfFormat.Unmap(pSourceLine, pixel, pSourceMD);
  5166. FormatDesc.Map(pixel, pDestLine, pDestMD);
  5167. end;
  5168. end;
  5169. finally
  5170. FormatDesc.FreeMappingData(pDestMD);
  5171. bfFormat.FreeMappingData(pSourceMD);
  5172. bfFormat.Free;
  5173. end;
  5174. end;
  5175. begin
  5176. result := false;
  5177. if not Assigned(aImage) then
  5178. exit;
  5179. with aImage.DataDescription do begin
  5180. Mask.r := (QWord(1 shl RedPrec )-1) shl RedShift;
  5181. Mask.g := (QWord(1 shl GreenPrec)-1) shl GreenShift;
  5182. Mask.b := (QWord(1 shl BluePrec )-1) shl BlueShift;
  5183. Mask.a := (QWord(1 shl AlphaPrec)-1) shl AlphaShift;
  5184. end;
  5185. FormatDesc := TFormatDescriptor.GetFromMask(Mask);
  5186. f := FormatDesc.Format;
  5187. if (f = tfEmpty) then
  5188. exit;
  5189. CanCopy :=
  5190. (FormatDesc.BitsPerPixel = aImage.DataDescription.Depth) and
  5191. (aImage.DataDescription.BitsPerPixel = aImage.DataDescription.Depth);
  5192. ImageSize := FormatDesc.GetSize(aImage.Width, aImage.Height);
  5193. ImageData := GetMem(ImageSize);
  5194. try
  5195. if CanCopy then
  5196. Move(aImage.PixelData^, ImageData^, ImageSize)
  5197. else
  5198. CopyConvert;
  5199. SetDataPointer(ImageData, f, aImage.Width, aImage.Height); //be careful, Data could be freed by this method
  5200. except
  5201. if Assigned(ImageData) then
  5202. FreeMem(ImageData);
  5203. raise;
  5204. end;
  5205. result := true;
  5206. end;
  5207. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5208. function TglBitmap.AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
  5209. var
  5210. rid: TRawImageDescription;
  5211. FormatDesc: TFormatDescriptor;
  5212. Pixel: TglBitmapPixelData;
  5213. x, y: Integer;
  5214. srcMD: Pointer;
  5215. src, dst: PByte;
  5216. begin
  5217. result := false;
  5218. if not Assigned(aImage) or (Format = tfEmpty) then
  5219. exit;
  5220. FormatDesc := TFormatDescriptor.Get(Format);
  5221. if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
  5222. exit;
  5223. FillChar(rid{%H-}, SizeOf(rid), 0);
  5224. rid.Format := ricfGray;
  5225. rid.Width := Width;
  5226. rid.Height := Height;
  5227. rid.Depth := CountSetBits(FormatDesc.Range.a);
  5228. rid.BitOrder := riboBitsInOrder;
  5229. rid.ByteOrder := riboLSBFirst;
  5230. rid.LineOrder := riloTopToBottom;
  5231. rid.LineEnd := rileTight;
  5232. rid.BitsPerPixel := 8 * Ceil(rid.Depth / 8);
  5233. rid.RedPrec := CountSetBits(FormatDesc.Range.a);
  5234. rid.GreenPrec := 0;
  5235. rid.BluePrec := 0;
  5236. rid.AlphaPrec := 0;
  5237. rid.RedShift := 0;
  5238. rid.GreenShift := 0;
  5239. rid.BlueShift := 0;
  5240. rid.AlphaShift := 0;
  5241. rid.MaskBitsPerPixel := 0;
  5242. rid.PaletteColorCount := 0;
  5243. aImage.DataDescription := rid;
  5244. aImage.CreateData;
  5245. srcMD := FormatDesc.CreateMappingData;
  5246. try
  5247. FormatDesc.PreparePixel(Pixel);
  5248. src := Data;
  5249. dst := aImage.PixelData;
  5250. for y := 0 to Height-1 do
  5251. for x := 0 to Width-1 do begin
  5252. FormatDesc.Unmap(src, Pixel, srcMD);
  5253. case rid.BitsPerPixel of
  5254. 8: begin
  5255. dst^ := Pixel.Data.a;
  5256. inc(dst);
  5257. end;
  5258. 16: begin
  5259. PWord(dst)^ := Pixel.Data.a;
  5260. inc(dst, 2);
  5261. end;
  5262. 24: begin
  5263. PByteArray(dst)^[0] := PByteArray(@Pixel.Data.a)^[0];
  5264. PByteArray(dst)^[1] := PByteArray(@Pixel.Data.a)^[1];
  5265. PByteArray(dst)^[2] := PByteArray(@Pixel.Data.a)^[2];
  5266. inc(dst, 3);
  5267. end;
  5268. 32: begin
  5269. PCardinal(dst)^ := Pixel.Data.a;
  5270. inc(dst, 4);
  5271. end;
  5272. else
  5273. raise EglBitmapUnsupportedFormat.Create(Format);
  5274. end;
  5275. end;
  5276. finally
  5277. FormatDesc.FreeMappingData(srcMD);
  5278. end;
  5279. result := true;
  5280. end;
  5281. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5282. function TglBitmap.AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  5283. var
  5284. tex: TglBitmap2D;
  5285. begin
  5286. tex := TglBitmap2D.Create;
  5287. try
  5288. tex.AssignFromLazIntfImage(aImage);
  5289. result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
  5290. finally
  5291. tex.Free;
  5292. end;
  5293. end;
  5294. {$ENDIF}
  5295. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5296. function TglBitmap.AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar;
  5297. const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  5298. var
  5299. rs: TResourceStream;
  5300. begin
  5301. PrepareResType(aResource, aResType);
  5302. rs := TResourceStream.Create(aInstance, aResource, aResType);
  5303. try
  5304. result := AddAlphaFromStream(rs, aFunc, aArgs);
  5305. finally
  5306. rs.Free;
  5307. end;
  5308. end;
  5309. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5310. function TglBitmap.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
  5311. const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  5312. var
  5313. rs: TResourceStream;
  5314. begin
  5315. rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
  5316. try
  5317. result := AddAlphaFromStream(rs, aFunc, aArgs);
  5318. finally
  5319. rs.Free;
  5320. end;
  5321. end;
  5322. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5323. function TglBitmap.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  5324. begin
  5325. if TFormatDescriptor.Get(Format).IsCompressed then
  5326. raise EglBitmapUnsupportedFormat.Create(Format);
  5327. result := Convert(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs);
  5328. end;
  5329. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5330. function TglBitmap.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  5331. var
  5332. FS: TFileStream;
  5333. begin
  5334. FS := TFileStream.Create(aFileName, fmOpenRead);
  5335. try
  5336. result := AddAlphaFromStream(FS, aFunc, aArgs);
  5337. finally
  5338. FS.Free;
  5339. end;
  5340. end;
  5341. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5342. function TglBitmap.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  5343. var
  5344. tex: TglBitmap2D;
  5345. begin
  5346. tex := TglBitmap2D.Create(aStream);
  5347. try
  5348. result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
  5349. finally
  5350. tex.Free;
  5351. end;
  5352. end;
  5353. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5354. function TglBitmap.AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  5355. var
  5356. DestData, DestData2, SourceData: pByte;
  5357. TempHeight, TempWidth: Integer;
  5358. SourceFD, DestFD: TFormatDescriptor;
  5359. SourceMD, DestMD, DestMD2: Pointer;
  5360. FuncRec: TglBitmapFunctionRec;
  5361. begin
  5362. result := false;
  5363. Assert(Assigned(Data));
  5364. Assert(Assigned(aBitmap));
  5365. Assert(Assigned(aBitmap.Data));
  5366. if ((aBitmap.Width = Width) and (aBitmap.Height = Height)) then begin
  5367. result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
  5368. SourceFD := TFormatDescriptor.Get(aBitmap.Format);
  5369. DestFD := TFormatDescriptor.Get(Format);
  5370. if not Assigned(aFunc) then begin
  5371. aFunc := glBitmapAlphaFunc;
  5372. FuncRec.Args := {%H-}Pointer(SourceFD.HasAlpha);
  5373. end else
  5374. FuncRec.Args := aArgs;
  5375. // Values
  5376. TempHeight := aBitmap.FileHeight;
  5377. TempWidth := aBitmap.FileWidth;
  5378. FuncRec.Sender := Self;
  5379. FuncRec.Size := Dimension;
  5380. FuncRec.Position.Fields := FuncRec.Size.Fields;
  5381. DestData := Data;
  5382. DestData2 := Data;
  5383. SourceData := aBitmap.Data;
  5384. // Mapping
  5385. SourceFD.PreparePixel(FuncRec.Source);
  5386. DestFD.PreparePixel (FuncRec.Dest);
  5387. SourceMD := SourceFD.CreateMappingData;
  5388. DestMD := DestFD.CreateMappingData;
  5389. DestMD2 := DestFD.CreateMappingData;
  5390. try
  5391. FuncRec.Position.Y := 0;
  5392. while FuncRec.Position.Y < TempHeight do begin
  5393. FuncRec.Position.X := 0;
  5394. while FuncRec.Position.X < TempWidth do begin
  5395. SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
  5396. DestFD.Unmap (DestData, FuncRec.Dest, DestMD);
  5397. aFunc(FuncRec);
  5398. DestFD.Map(FuncRec.Dest, DestData2, DestMD2);
  5399. inc(FuncRec.Position.X);
  5400. end;
  5401. inc(FuncRec.Position.Y);
  5402. end;
  5403. finally
  5404. SourceFD.FreeMappingData(SourceMD);
  5405. DestFD.FreeMappingData(DestMD);
  5406. DestFD.FreeMappingData(DestMD2);
  5407. end;
  5408. end;
  5409. end;
  5410. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5411. function TglBitmap.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
  5412. begin
  5413. result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
  5414. end;
  5415. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5416. function TglBitmap.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
  5417. var
  5418. PixelData: TglBitmapPixelData;
  5419. begin
  5420. TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
  5421. result := AddAlphaFromColorKeyFloat(
  5422. aRed / PixelData.Range.r,
  5423. aGreen / PixelData.Range.g,
  5424. aBlue / PixelData.Range.b,
  5425. aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b)));
  5426. end;
  5427. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5428. function TglBitmap.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
  5429. var
  5430. values: array[0..2] of Single;
  5431. tmp: Cardinal;
  5432. i: Integer;
  5433. PixelData: TglBitmapPixelData;
  5434. begin
  5435. TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
  5436. with PixelData do begin
  5437. values[0] := aRed;
  5438. values[1] := aGreen;
  5439. values[2] := aBlue;
  5440. for i := 0 to 2 do begin
  5441. tmp := Trunc(Range.arr[i] * aDeviation);
  5442. Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp));
  5443. Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp));
  5444. end;
  5445. Data.a := 0;
  5446. Range.a := 0;
  5447. end;
  5448. result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, @PixelData);
  5449. end;
  5450. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5451. function TglBitmap.AddAlphaFromValue(const aAlpha: Byte): Boolean;
  5452. begin
  5453. result := AddAlphaFromValueFloat(aAlpha / $FF);
  5454. end;
  5455. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5456. function TglBitmap.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
  5457. var
  5458. PixelData: TglBitmapPixelData;
  5459. begin
  5460. TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
  5461. result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
  5462. end;
  5463. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5464. function TglBitmap.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
  5465. var
  5466. PixelData: TglBitmapPixelData;
  5467. begin
  5468. TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
  5469. with PixelData do
  5470. Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
  5471. result := AddAlphaFromFunc(glBitmapValueAlphaFunc, @PixelData.Data.a);
  5472. end;
  5473. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5474. function TglBitmap.RemoveAlpha: Boolean;
  5475. var
  5476. FormatDesc: TFormatDescriptor;
  5477. begin
  5478. result := false;
  5479. FormatDesc := TFormatDescriptor.Get(Format);
  5480. if Assigned(Data) then begin
  5481. if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
  5482. raise EglBitmapUnsupportedFormat.Create(Format);
  5483. result := ConvertTo(FormatDesc.WithoutAlpha);
  5484. end;
  5485. end;
  5486. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5487. function TglBitmap.Clone: TglBitmap;
  5488. var
  5489. Temp: TglBitmap;
  5490. TempPtr: PByte;
  5491. Size: Integer;
  5492. begin
  5493. result := nil;
  5494. Temp := (ClassType.Create as TglBitmap);
  5495. try
  5496. // copy texture data if assigned
  5497. if Assigned(Data) then begin
  5498. Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
  5499. GetMem(TempPtr, Size);
  5500. try
  5501. Move(Data^, TempPtr^, Size);
  5502. Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
  5503. except
  5504. if Assigned(TempPtr) then
  5505. FreeMem(TempPtr);
  5506. raise;
  5507. end;
  5508. end else begin
  5509. TempPtr := nil;
  5510. Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
  5511. end;
  5512. // copy properties
  5513. Temp.fID := ID;
  5514. Temp.fTarget := Target;
  5515. Temp.fFormat := Format;
  5516. Temp.fMipMap := MipMap;
  5517. Temp.fAnisotropic := Anisotropic;
  5518. Temp.fBorderColor := fBorderColor;
  5519. Temp.fDeleteTextureOnFree := DeleteTextureOnFree;
  5520. Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
  5521. Temp.fFilterMin := fFilterMin;
  5522. Temp.fFilterMag := fFilterMag;
  5523. Temp.fWrapS := fWrapS;
  5524. Temp.fWrapT := fWrapT;
  5525. Temp.fWrapR := fWrapR;
  5526. Temp.fFilename := fFilename;
  5527. Temp.fCustomName := fCustomName;
  5528. Temp.fCustomNameW := fCustomNameW;
  5529. Temp.fCustomData := fCustomData;
  5530. result := Temp;
  5531. except
  5532. FreeAndNil(Temp);
  5533. raise;
  5534. end;
  5535. end;
  5536. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5537. procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
  5538. begin
  5539. if aUseRGB or aUseAlpha then
  5540. Convert(glBitmapInvertFunc, false, {%H-}Pointer(
  5541. ((Byte(aUseAlpha) and 1) shl 1) or
  5542. (Byte(aUseRGB) and 1) ));
  5543. end;
  5544. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5545. procedure TglBitmap.FreeData;
  5546. var
  5547. TempPtr: PByte;
  5548. begin
  5549. TempPtr := nil;
  5550. SetDataPointer(TempPtr, tfEmpty); //be careful, Data could be freed by this method
  5551. end;
  5552. {$IFNDEF OPENGL_ES}
  5553. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5554. procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
  5555. begin
  5556. fBorderColor[0] := aRed;
  5557. fBorderColor[1] := aGreen;
  5558. fBorderColor[2] := aBlue;
  5559. fBorderColor[3] := aAlpha;
  5560. if (ID > 0) then begin
  5561. Bind(false);
  5562. glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
  5563. end;
  5564. end;
  5565. {$ENDIF}
  5566. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5567. procedure TglBitmap.FillWithColor(const aRed, aGreen, aBlue: Byte;
  5568. const aAlpha: Byte);
  5569. begin
  5570. FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
  5571. end;
  5572. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5573. procedure TglBitmap.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
  5574. var
  5575. PixelData: TglBitmapPixelData;
  5576. begin
  5577. TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
  5578. FillWithColorFloat(
  5579. aRed / PixelData.Range.r,
  5580. aGreen / PixelData.Range.g,
  5581. aBlue / PixelData.Range.b,
  5582. aAlpha / PixelData.Range.a);
  5583. end;
  5584. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5585. procedure TglBitmap.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
  5586. var
  5587. PixelData: TglBitmapPixelData;
  5588. begin
  5589. TFormatDescriptor.Get(Format).PreparePixel(PixelData);
  5590. with PixelData do begin
  5591. Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed)));
  5592. Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen)));
  5593. Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue)));
  5594. Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha)));
  5595. end;
  5596. Convert(glBitmapFillWithColorFunc, false, @PixelData);
  5597. end;
  5598. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5599. procedure TglBitmap.SetFilter(const aMin, aMag: GLenum);
  5600. begin
  5601. //check MIN filter
  5602. case aMin of
  5603. GL_NEAREST:
  5604. fFilterMin := GL_NEAREST;
  5605. GL_LINEAR:
  5606. fFilterMin := GL_LINEAR;
  5607. GL_NEAREST_MIPMAP_NEAREST:
  5608. fFilterMin := GL_NEAREST_MIPMAP_NEAREST;
  5609. GL_LINEAR_MIPMAP_NEAREST:
  5610. fFilterMin := GL_LINEAR_MIPMAP_NEAREST;
  5611. GL_NEAREST_MIPMAP_LINEAR:
  5612. fFilterMin := GL_NEAREST_MIPMAP_LINEAR;
  5613. GL_LINEAR_MIPMAP_LINEAR:
  5614. fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
  5615. else
  5616. raise EglBitmap.Create('SetFilter - Unknow MIN filter.');
  5617. end;
  5618. //check MAG filter
  5619. case aMag of
  5620. GL_NEAREST:
  5621. fFilterMag := GL_NEAREST;
  5622. GL_LINEAR:
  5623. fFilterMag := GL_LINEAR;
  5624. else
  5625. raise EglBitmap.Create('SetFilter - Unknow MAG filter.');
  5626. end;
  5627. //apply filter
  5628. if (ID > 0) then begin
  5629. Bind(false);
  5630. glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
  5631. if (MipMap = mmNone) {$IFNDEF OPENGL_ES}or (Target = GL_TEXTURE_RECTANGLE){$ENDIF} then begin
  5632. case fFilterMin of
  5633. GL_NEAREST, GL_LINEAR:
  5634. glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
  5635. GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR:
  5636. glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  5637. GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR:
  5638. glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  5639. end;
  5640. end else
  5641. glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
  5642. end;
  5643. end;
  5644. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5645. procedure TglBitmap.SetWrap(const S: GLenum; const T: GLenum; const R: GLenum);
  5646. procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
  5647. begin
  5648. case aValue of
  5649. {$IFNDEF OPENGL_ES}
  5650. GL_CLAMP:
  5651. aTarget := GL_CLAMP;
  5652. {$ENDIF}
  5653. GL_REPEAT:
  5654. aTarget := GL_REPEAT;
  5655. GL_CLAMP_TO_EDGE: begin
  5656. {$IFNDEF OPENGL_ES}
  5657. if not GL_VERSION_1_2 and not GL_EXT_texture_edge_clamp then
  5658. aTarget := GL_CLAMP
  5659. else
  5660. {$ENDIF}
  5661. aTarget := GL_CLAMP_TO_EDGE;
  5662. end;
  5663. {$IFNDEF OPENGL_ES}
  5664. GL_CLAMP_TO_BORDER: begin
  5665. if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
  5666. aTarget := GL_CLAMP_TO_BORDER
  5667. else
  5668. aTarget := GL_CLAMP;
  5669. end;
  5670. {$ENDIF}
  5671. {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
  5672. GL_MIRRORED_REPEAT: begin
  5673. {$IFNDEF OPENGL_ES}
  5674. if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
  5675. {$ELSE}
  5676. if GL_VERSION_2_0 then
  5677. {$ENDIF}
  5678. aTarget := GL_MIRRORED_REPEAT
  5679. else
  5680. raise EglBitmap.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
  5681. end;
  5682. {$IFEND}
  5683. else
  5684. raise EglBitmap.Create('SetWrap - Unknow Texturewrap');
  5685. end;
  5686. end;
  5687. begin
  5688. CheckAndSetWrap(S, fWrapS);
  5689. CheckAndSetWrap(T, fWrapT);
  5690. CheckAndSetWrap(R, fWrapR);
  5691. if (ID > 0) then begin
  5692. Bind(false);
  5693. glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
  5694. glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
  5695. {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
  5696. {$IFDEF OPENGL_ES} if GL_VERSION_3_0 then{$ENDIF}
  5697. glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
  5698. {$IFEND}
  5699. end;
  5700. end;
  5701. {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
  5702. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5703. procedure TglBitmap.SetSwizzle(const r, g, b, a: GLenum);
  5704. procedure CheckAndSetValue(const aValue: GLenum; const aIndex: Integer);
  5705. begin
  5706. if (aValue = GL_ZERO) or (aValue = GL_ONE) or (aValue = GL_ALPHA) or
  5707. (aValue = GL_RED) or (aValue = GL_GREEN) or (aValue = GL_BLUE) then
  5708. fSwizzle[aIndex] := aValue
  5709. else
  5710. raise EglBitmap.Create('SetSwizzle - Unknow Swizle Value');
  5711. end;
  5712. begin
  5713. {$IFNDEF OPENGL_ES}
  5714. if not (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
  5715. raise EglBitmapNotSupported.Create('texture swizzle is not supported');
  5716. {$ELSE}
  5717. if not GL_VERSION_3_0 then
  5718. raise EglBitmapNotSupported.Create('texture swizzle is not supported');
  5719. {$ENDIF}
  5720. CheckAndSetValue(r, 0);
  5721. CheckAndSetValue(g, 1);
  5722. CheckAndSetValue(b, 2);
  5723. CheckAndSetValue(a, 3);
  5724. if (ID > 0) then begin
  5725. Bind(false);
  5726. {$IFNDEF OPENGL_ES}
  5727. glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_RGBA, PGLint(@fSwizzle[0]));
  5728. {$ELSE}
  5729. glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_R, PGLint(@fSwizzle[0]));
  5730. glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_G, PGLint(@fSwizzle[1]));
  5731. glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_B, PGLint(@fSwizzle[2]));
  5732. glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_A, PGLint(@fSwizzle[3]));
  5733. {$ENDIF}
  5734. end;
  5735. end;
  5736. {$IFEND}
  5737. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5738. procedure TglBitmap.Bind(const aEnableTextureUnit: Boolean);
  5739. begin
  5740. if aEnableTextureUnit then
  5741. glEnable(Target);
  5742. if (ID > 0) then
  5743. glBindTexture(Target, ID);
  5744. end;
  5745. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5746. procedure TglBitmap.Unbind(const aDisableTextureUnit: Boolean);
  5747. begin
  5748. if aDisableTextureUnit then
  5749. glDisable(Target);
  5750. glBindTexture(Target, 0);
  5751. end;
  5752. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5753. constructor TglBitmap.Create;
  5754. begin
  5755. if (ClassType = TglBitmap) then
  5756. raise EglBitmap.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
  5757. {$IFDEF GLB_NATIVE_OGL}
  5758. glbReadOpenGLExtensions;
  5759. {$ENDIF}
  5760. inherited Create;
  5761. fFormat := glBitmapGetDefaultFormat;
  5762. fFreeDataOnDestroy := true;
  5763. end;
  5764. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5765. constructor TglBitmap.Create(const aFileName: String);
  5766. begin
  5767. Create;
  5768. LoadFromFile(aFileName);
  5769. end;
  5770. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5771. constructor TglBitmap.Create(const aStream: TStream);
  5772. begin
  5773. Create;
  5774. LoadFromStream(aStream);
  5775. end;
  5776. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5777. constructor TglBitmap.Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; aData: PByte);
  5778. var
  5779. ImageSize: Integer;
  5780. begin
  5781. Create;
  5782. if not Assigned(aData) then begin
  5783. ImageSize := TFormatDescriptor.Get(aFormat).GetSize(aSize);
  5784. GetMem(aData, ImageSize);
  5785. try
  5786. FillChar(aData^, ImageSize, #$FF);
  5787. SetDataPointer(aData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
  5788. except
  5789. if Assigned(aData) then
  5790. FreeMem(aData);
  5791. raise;
  5792. end;
  5793. end else begin
  5794. SetDataPointer(aData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
  5795. end;
  5796. end;
  5797. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5798. constructor TglBitmap.Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer);
  5799. begin
  5800. Create;
  5801. LoadFromFunc(aSize, aFunc, aFormat, aArgs);
  5802. end;
  5803. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5804. constructor TglBitmap.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
  5805. begin
  5806. Create;
  5807. LoadFromResource(aInstance, aResource, aResType);
  5808. end;
  5809. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5810. constructor TglBitmap.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
  5811. begin
  5812. Create;
  5813. LoadFromResourceID(aInstance, aResourceID, aResType);
  5814. end;
  5815. {$IFDEF GLB_SUPPORT_PNG_READ}
  5816. {$IF DEFINED(GLB_LAZ_PNG)}
  5817. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5818. //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5819. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5820. function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
  5821. const
  5822. MAGIC_LEN = 8;
  5823. PNG_MAGIC: String[MAGIC_LEN] = #$89#$50#$4E#$47#$0D#$0A#$1A#$0A;
  5824. var
  5825. reader: TLazReaderPNG;
  5826. intf: TLazIntfImage;
  5827. StreamPos: Int64;
  5828. magic: String[MAGIC_LEN];
  5829. begin
  5830. result := true;
  5831. StreamPos := aStream.Position;
  5832. SetLength(magic, MAGIC_LEN);
  5833. aStream.Read(magic[1], MAGIC_LEN);
  5834. aStream.Position := StreamPos;
  5835. if (magic <> PNG_MAGIC) then begin
  5836. result := false;
  5837. exit;
  5838. end;
  5839. intf := TLazIntfImage.Create(0, 0);
  5840. reader := TLazReaderPNG.Create;
  5841. try try
  5842. reader.UpdateDescription := true;
  5843. reader.ImageRead(aStream, intf);
  5844. AssignFromLazIntfImage(intf);
  5845. except
  5846. result := false;
  5847. aStream.Position := StreamPos;
  5848. exit;
  5849. end;
  5850. finally
  5851. reader.Free;
  5852. intf.Free;
  5853. end;
  5854. end;
  5855. {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
  5856. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5857. function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
  5858. var
  5859. Surface: PSDL_Surface;
  5860. RWops: PSDL_RWops;
  5861. begin
  5862. result := false;
  5863. RWops := glBitmapCreateRWops(aStream);
  5864. try
  5865. if IMG_isPNG(RWops) > 0 then begin
  5866. Surface := IMG_LoadPNG_RW(RWops);
  5867. try
  5868. AssignFromSurface(Surface);
  5869. result := true;
  5870. finally
  5871. SDL_FreeSurface(Surface);
  5872. end;
  5873. end;
  5874. finally
  5875. SDL_FreeRW(RWops);
  5876. end;
  5877. end;
  5878. {$ELSEIF DEFINED(GLB_LIB_PNG)}
  5879. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5880. procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
  5881. begin
  5882. TStream(png_get_io_ptr(png)).Read(buffer^, size);
  5883. end;
  5884. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5885. function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
  5886. var
  5887. StreamPos: Int64;
  5888. signature: array [0..7] of byte;
  5889. png: png_structp;
  5890. png_info: png_infop;
  5891. TempHeight, TempWidth: Integer;
  5892. Format: TglBitmapFormat;
  5893. png_data: pByte;
  5894. png_rows: array of pByte;
  5895. Row, LineSize: Integer;
  5896. begin
  5897. result := false;
  5898. if not init_libPNG then
  5899. raise Exception.Create('LoadPNG - unable to initialize libPNG.');
  5900. try
  5901. // signature
  5902. StreamPos := aStream.Position;
  5903. aStream.Read(signature{%H-}, 8);
  5904. aStream.Position := StreamPos;
  5905. if png_check_sig(@signature, 8) <> 0 then begin
  5906. // png read struct
  5907. png := png_create_read_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
  5908. if png = nil then
  5909. raise EglBitmapException.Create('LoadPng - couldn''t create read struct.');
  5910. // png info
  5911. png_info := png_create_info_struct(png);
  5912. if png_info = nil then begin
  5913. png_destroy_read_struct(@png, nil, nil);
  5914. raise EglBitmapException.Create('LoadPng - couldn''t create info struct.');
  5915. end;
  5916. // set read callback
  5917. png_set_read_fn(png, aStream, glBitmap_libPNG_read_func);
  5918. // read informations
  5919. png_read_info(png, png_info);
  5920. // size
  5921. TempHeight := png_get_image_height(png, png_info);
  5922. TempWidth := png_get_image_width(png, png_info);
  5923. // format
  5924. case png_get_color_type(png, png_info) of
  5925. PNG_COLOR_TYPE_GRAY:
  5926. Format := tfLuminance8ub1;
  5927. PNG_COLOR_TYPE_GRAY_ALPHA:
  5928. Format := tfLuminance8Alpha8us1;
  5929. PNG_COLOR_TYPE_RGB:
  5930. Format := tfRGB8ub3;
  5931. PNG_COLOR_TYPE_RGB_ALPHA:
  5932. Format := tfRGBA8ub4;
  5933. else
  5934. raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
  5935. end;
  5936. // cut upper 8 bit from 16 bit formats
  5937. if png_get_bit_depth(png, png_info) > 8 then
  5938. png_set_strip_16(png);
  5939. // expand bitdepth smaller than 8
  5940. if png_get_bit_depth(png, png_info) < 8 then
  5941. png_set_expand(png);
  5942. // allocating mem for scanlines
  5943. LineSize := png_get_rowbytes(png, png_info);
  5944. GetMem(png_data, TempHeight * LineSize);
  5945. try
  5946. SetLength(png_rows, TempHeight);
  5947. for Row := Low(png_rows) to High(png_rows) do begin
  5948. png_rows[Row] := png_data;
  5949. Inc(png_rows[Row], Row * LineSize);
  5950. end;
  5951. // read complete image into scanlines
  5952. png_read_image(png, @png_rows[0]);
  5953. // read end
  5954. png_read_end(png, png_info);
  5955. // destroy read struct
  5956. png_destroy_read_struct(@png, @png_info, nil);
  5957. SetLength(png_rows, 0);
  5958. // set new data
  5959. SetDataPointer(png_data, Format, TempWidth, TempHeight); //be careful, Data could be freed by this method
  5960. result := true;
  5961. except
  5962. if Assigned(png_data) then
  5963. FreeMem(png_data);
  5964. raise;
  5965. end;
  5966. end;
  5967. finally
  5968. quit_libPNG;
  5969. end;
  5970. end;
  5971. {$ELSEIF DEFINED(GLB_PNGIMAGE)}
  5972. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5973. function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
  5974. var
  5975. StreamPos: Int64;
  5976. Png: TPNGObject;
  5977. Header: String[8];
  5978. Row, Col, PixSize, LineSize: Integer;
  5979. NewImage, pSource, pDest, pAlpha: pByte;
  5980. PngFormat: TglBitmapFormat;
  5981. FormatDesc: TFormatDescriptor;
  5982. const
  5983. PngHeader: String[8] = #137#80#78#71#13#10#26#10;
  5984. begin
  5985. result := false;
  5986. StreamPos := aStream.Position;
  5987. aStream.Read(Header[0], SizeOf(Header));
  5988. aStream.Position := StreamPos;
  5989. {Test if the header matches}
  5990. if Header = PngHeader then begin
  5991. Png := TPNGObject.Create;
  5992. try
  5993. Png.LoadFromStream(aStream);
  5994. case Png.Header.ColorType of
  5995. COLOR_GRAYSCALE:
  5996. PngFormat := tfLuminance8ub1;
  5997. COLOR_GRAYSCALEALPHA:
  5998. PngFormat := tfLuminance8Alpha8us1;
  5999. COLOR_RGB:
  6000. PngFormat := tfBGR8ub3;
  6001. COLOR_RGBALPHA:
  6002. PngFormat := tfBGRA8ub4;
  6003. else
  6004. raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
  6005. end;
  6006. FormatDesc := TFormatDescriptor.Get(PngFormat);
  6007. PixSize := Round(FormatDesc.PixelSize);
  6008. LineSize := FormatDesc.GetSize(Png.Header.Width, 1);
  6009. GetMem(NewImage, LineSize * Integer(Png.Header.Height));
  6010. try
  6011. pDest := NewImage;
  6012. case Png.Header.ColorType of
  6013. COLOR_RGB, COLOR_GRAYSCALE:
  6014. begin
  6015. for Row := 0 to Png.Height -1 do begin
  6016. Move (Png.Scanline[Row]^, pDest^, LineSize);
  6017. Inc(pDest, LineSize);
  6018. end;
  6019. end;
  6020. COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA:
  6021. begin
  6022. PixSize := PixSize -1;
  6023. for Row := 0 to Png.Height -1 do begin
  6024. pSource := Png.Scanline[Row];
  6025. pAlpha := pByte(Png.AlphaScanline[Row]);
  6026. for Col := 0 to Png.Width -1 do begin
  6027. Move (pSource^, pDest^, PixSize);
  6028. Inc(pSource, PixSize);
  6029. Inc(pDest, PixSize);
  6030. pDest^ := pAlpha^;
  6031. inc(pAlpha);
  6032. Inc(pDest);
  6033. end;
  6034. end;
  6035. end;
  6036. else
  6037. raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
  6038. end;
  6039. SetDataPointer(NewImage, PngFormat, Png.Header.Width, Png.Header.Height); //be careful, Data could be freed by this method
  6040. result := true;
  6041. except
  6042. if Assigned(NewImage) then
  6043. FreeMem(NewImage);
  6044. raise;
  6045. end;
  6046. finally
  6047. Png.Free;
  6048. end;
  6049. end;
  6050. end;
  6051. {$IFEND}
  6052. {$ENDIF}
  6053. {$IFDEF GLB_SUPPORT_PNG_WRITE}
  6054. {$IFDEF GLB_LIB_PNG}
  6055. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6056. procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
  6057. begin
  6058. TStream(png_get_io_ptr(png)).Write(buffer^, size);
  6059. end;
  6060. {$ENDIF}
  6061. {$IF DEFINED(GLB_LAZ_PNG)}
  6062. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6063. procedure TglBitmap.SavePNG(const aStream: TStream);
  6064. var
  6065. png: TPortableNetworkGraphic;
  6066. intf: TLazIntfImage;
  6067. raw: TRawImage;
  6068. begin
  6069. png := TPortableNetworkGraphic.Create;
  6070. intf := TLazIntfImage.Create(0, 0);
  6071. try
  6072. if not AssignToLazIntfImage(intf) then
  6073. raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
  6074. intf.GetRawImage(raw);
  6075. png.LoadFromRawImage(raw, false);
  6076. png.SaveToStream(aStream);
  6077. finally
  6078. png.Free;
  6079. intf.Free;
  6080. end;
  6081. end;
  6082. {$ELSEIF DEFINED(GLB_LIB_PNG)}
  6083. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6084. procedure TglBitmap.SavePNG(const aStream: TStream);
  6085. var
  6086. png: png_structp;
  6087. png_info: png_infop;
  6088. png_rows: array of pByte;
  6089. LineSize: Integer;
  6090. ColorType: Integer;
  6091. Row: Integer;
  6092. FormatDesc: TFormatDescriptor;
  6093. begin
  6094. if not (ftPNG in FormatGetSupportedFiles(Format)) then
  6095. raise EglBitmapUnsupportedFormat.Create(Format);
  6096. if not init_libPNG then
  6097. raise Exception.Create('unable to initialize libPNG.');
  6098. try
  6099. case Format of
  6100. tfAlpha8ub1, tfLuminance8ub1:
  6101. ColorType := PNG_COLOR_TYPE_GRAY;
  6102. tfLuminance8Alpha8us1:
  6103. ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
  6104. tfBGR8ub3, tfRGB8ub3:
  6105. ColorType := PNG_COLOR_TYPE_RGB;
  6106. tfBGRA8ub4, tfRGBA8ub4:
  6107. ColorType := PNG_COLOR_TYPE_RGBA;
  6108. else
  6109. raise EglBitmapUnsupportedFormat.Create(Format);
  6110. end;
  6111. FormatDesc := TFormatDescriptor.Get(Format);
  6112. LineSize := FormatDesc.GetSize(Width, 1);
  6113. // creating array for scanline
  6114. SetLength(png_rows, Height);
  6115. try
  6116. for Row := 0 to Height - 1 do begin
  6117. png_rows[Row] := Data;
  6118. Inc(png_rows[Row], Row * LineSize)
  6119. end;
  6120. // write struct
  6121. png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
  6122. if png = nil then
  6123. raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
  6124. // create png info
  6125. png_info := png_create_info_struct(png);
  6126. if png_info = nil then begin
  6127. png_destroy_write_struct(@png, nil);
  6128. raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
  6129. end;
  6130. // set read callback
  6131. png_set_write_fn(png, aStream, glBitmap_libPNG_write_func, nil);
  6132. // set compression
  6133. png_set_compression_level(png, 6);
  6134. if Format in [tfBGR8ub3, tfBGRA8ub4] then
  6135. png_set_bgr(png);
  6136. png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
  6137. png_write_info(png, png_info);
  6138. png_write_image(png, @png_rows[0]);
  6139. png_write_end(png, png_info);
  6140. png_destroy_write_struct(@png, @png_info);
  6141. finally
  6142. SetLength(png_rows, 0);
  6143. end;
  6144. finally
  6145. quit_libPNG;
  6146. end;
  6147. end;
  6148. {$ELSEIF DEFINED(GLB_PNGIMAGE)}
  6149. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6150. procedure TglBitmap.SavePNG(const aStream: TStream);
  6151. var
  6152. Png: TPNGObject;
  6153. pSource, pDest: pByte;
  6154. X, Y, PixSize: Integer;
  6155. ColorType: Cardinal;
  6156. Alpha: Boolean;
  6157. pTemp: pByte;
  6158. Temp: Byte;
  6159. begin
  6160. if not (ftPNG in FormatGetSupportedFiles (Format)) then
  6161. raise EglBitmapUnsupportedFormat.Create(Format);
  6162. case Format of
  6163. tfAlpha8ub1, tfLuminance8ub1: begin
  6164. ColorType := COLOR_GRAYSCALE;
  6165. PixSize := 1;
  6166. Alpha := false;
  6167. end;
  6168. tfLuminance8Alpha8us1: begin
  6169. ColorType := COLOR_GRAYSCALEALPHA;
  6170. PixSize := 1;
  6171. Alpha := true;
  6172. end;
  6173. tfBGR8ub3, tfRGB8ub3: begin
  6174. ColorType := COLOR_RGB;
  6175. PixSize := 3;
  6176. Alpha := false;
  6177. end;
  6178. tfBGRA8ub4, tfRGBA8ub4: begin
  6179. ColorType := COLOR_RGBALPHA;
  6180. PixSize := 3;
  6181. Alpha := true
  6182. end;
  6183. else
  6184. raise EglBitmapUnsupportedFormat.Create(Format);
  6185. end;
  6186. Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
  6187. try
  6188. // Copy ImageData
  6189. pSource := Data;
  6190. for Y := 0 to Height -1 do begin
  6191. pDest := png.ScanLine[Y];
  6192. for X := 0 to Width -1 do begin
  6193. Move(pSource^, pDest^, PixSize);
  6194. Inc(pDest, PixSize);
  6195. Inc(pSource, PixSize);
  6196. if Alpha then begin
  6197. png.AlphaScanline[Y]^[X] := pSource^;
  6198. Inc(pSource);
  6199. end;
  6200. end;
  6201. // convert RGB line to BGR
  6202. if Format in [tfRGB8ub3, tfRGBA8ub4] then begin
  6203. pTemp := png.ScanLine[Y];
  6204. for X := 0 to Width -1 do begin
  6205. Temp := pByteArray(pTemp)^[0];
  6206. pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
  6207. pByteArray(pTemp)^[2] := Temp;
  6208. Inc(pTemp, 3);
  6209. end;
  6210. end;
  6211. end;
  6212. // Save to Stream
  6213. Png.CompressionLevel := 6;
  6214. Png.SaveToStream(aStream);
  6215. finally
  6216. FreeAndNil(Png);
  6217. end;
  6218. end;
  6219. {$IFEND}
  6220. {$ENDIF}
  6221. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6222. //JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6223. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6224. {$IFDEF GLB_LIB_JPEG}
  6225. type
  6226. glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
  6227. glBitmap_libJPEG_source_mgr = record
  6228. pub: jpeg_source_mgr;
  6229. SrcStream: TStream;
  6230. SrcBuffer: array [1..4096] of byte;
  6231. end;
  6232. glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
  6233. glBitmap_libJPEG_dest_mgr = record
  6234. pub: jpeg_destination_mgr;
  6235. DestStream: TStream;
  6236. DestBuffer: array [1..4096] of byte;
  6237. end;
  6238. procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
  6239. begin
  6240. //DUMMY
  6241. end;
  6242. procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
  6243. begin
  6244. //DUMMY
  6245. end;
  6246. procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
  6247. begin
  6248. //DUMMY
  6249. end;
  6250. procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
  6251. begin
  6252. //DUMMY
  6253. end;
  6254. procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
  6255. begin
  6256. //DUMMY
  6257. end;
  6258. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6259. function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
  6260. var
  6261. src: glBitmap_libJPEG_source_mgr_ptr;
  6262. bytes: integer;
  6263. begin
  6264. src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
  6265. bytes := src^.SrcStream.Read(src^.SrcBuffer[1], 4096);
  6266. if (bytes <= 0) then begin
  6267. src^.SrcBuffer[1] := $FF;
  6268. src^.SrcBuffer[2] := JPEG_EOI;
  6269. bytes := 2;
  6270. end;
  6271. src^.pub.next_input_byte := @(src^.SrcBuffer[1]);
  6272. src^.pub.bytes_in_buffer := bytes;
  6273. result := true;
  6274. end;
  6275. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6276. procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
  6277. var
  6278. src: glBitmap_libJPEG_source_mgr_ptr;
  6279. begin
  6280. src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
  6281. if num_bytes > 0 then begin
  6282. // wanted byte isn't in buffer so set stream position and read buffer
  6283. if num_bytes > src^.pub.bytes_in_buffer then begin
  6284. src^.SrcStream.Position := src^.SrcStream.Position + num_bytes - src^.pub.bytes_in_buffer;
  6285. src^.pub.fill_input_buffer(cinfo);
  6286. end else begin
  6287. // wanted byte is in buffer so only skip
  6288. inc(src^.pub.next_input_byte, num_bytes);
  6289. dec(src^.pub.bytes_in_buffer, num_bytes);
  6290. end;
  6291. end;
  6292. end;
  6293. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6294. function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
  6295. var
  6296. dest: glBitmap_libJPEG_dest_mgr_ptr;
  6297. begin
  6298. dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
  6299. if dest^.pub.free_in_buffer < Cardinal(Length(dest^.DestBuffer)) then begin
  6300. // write complete buffer
  6301. dest^.DestStream.Write(dest^.DestBuffer[1], SizeOf(dest^.DestBuffer));
  6302. // reset buffer
  6303. dest^.pub.next_output_byte := @dest^.DestBuffer[1];
  6304. dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
  6305. end;
  6306. result := true;
  6307. end;
  6308. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6309. procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
  6310. var
  6311. Idx: Integer;
  6312. dest: glBitmap_libJPEG_dest_mgr_ptr;
  6313. begin
  6314. dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
  6315. for Idx := Low(dest^.DestBuffer) to High(dest^.DestBuffer) do begin
  6316. // check for endblock
  6317. if (Idx < High(dest^.DestBuffer)) and (dest^.DestBuffer[Idx] = $FF) and (dest^.DestBuffer[Idx +1] = JPEG_EOI) then begin
  6318. // write endblock
  6319. dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
  6320. // leave
  6321. break;
  6322. end else
  6323. dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
  6324. end;
  6325. end;
  6326. {$ENDIF}
  6327. {$IFDEF GLB_SUPPORT_JPEG_READ}
  6328. {$IF DEFINED(GLB_LAZ_JPEG)}
  6329. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6330. function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
  6331. const
  6332. MAGIC_LEN = 2;
  6333. JPEG_MAGIC: String[MAGIC_LEN] = #$FF#$D8;
  6334. var
  6335. intf: TLazIntfImage;
  6336. reader: TFPReaderJPEG;
  6337. StreamPos: Int64;
  6338. magic: String[MAGIC_LEN];
  6339. begin
  6340. result := true;
  6341. StreamPos := aStream.Position;
  6342. SetLength(magic, MAGIC_LEN);
  6343. aStream.Read(magic[1], MAGIC_LEN);
  6344. aStream.Position := StreamPos;
  6345. if (magic <> JPEG_MAGIC) then begin
  6346. result := false;
  6347. exit;
  6348. end;
  6349. reader := TFPReaderJPEG.Create;
  6350. intf := TLazIntfImage.Create(0, 0);
  6351. try try
  6352. intf.DataDescription := GetDescriptionFromDevice(0, 0, 0);
  6353. reader.ImageRead(aStream, intf);
  6354. AssignFromLazIntfImage(intf);
  6355. except
  6356. result := false;
  6357. aStream.Position := StreamPos;
  6358. exit;
  6359. end;
  6360. finally
  6361. reader.Free;
  6362. intf.Free;
  6363. end;
  6364. end;
  6365. {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
  6366. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6367. function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
  6368. var
  6369. Surface: PSDL_Surface;
  6370. RWops: PSDL_RWops;
  6371. begin
  6372. result := false;
  6373. RWops := glBitmapCreateRWops(aStream);
  6374. try
  6375. if IMG_isJPG(RWops) > 0 then begin
  6376. Surface := IMG_LoadJPG_RW(RWops);
  6377. try
  6378. AssignFromSurface(Surface);
  6379. result := true;
  6380. finally
  6381. SDL_FreeSurface(Surface);
  6382. end;
  6383. end;
  6384. finally
  6385. SDL_FreeRW(RWops);
  6386. end;
  6387. end;
  6388. {$ELSEIF DEFINED(GLB_LIB_JPEG)}
  6389. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6390. function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
  6391. var
  6392. StreamPos: Int64;
  6393. Temp: array[0..1]of Byte;
  6394. jpeg: jpeg_decompress_struct;
  6395. jpeg_err: jpeg_error_mgr;
  6396. IntFormat: TglBitmapFormat;
  6397. pImage: pByte;
  6398. TempHeight, TempWidth: Integer;
  6399. pTemp: pByte;
  6400. Row: Integer;
  6401. FormatDesc: TFormatDescriptor;
  6402. begin
  6403. result := false;
  6404. if not init_libJPEG then
  6405. raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
  6406. try
  6407. // reading first two bytes to test file and set cursor back to begin
  6408. StreamPos := aStream.Position;
  6409. aStream.Read({%H-}Temp[0], 2);
  6410. aStream.Position := StreamPos;
  6411. // if Bitmap then read file.
  6412. if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
  6413. FillChar(jpeg{%H-}, SizeOf(jpeg_decompress_struct), $00);
  6414. FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
  6415. // error managment
  6416. jpeg.err := jpeg_std_error(@jpeg_err);
  6417. jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
  6418. jpeg_err.output_message := glBitmap_libJPEG_output_message;
  6419. // decompression struct
  6420. jpeg_create_decompress(@jpeg);
  6421. // allocation space for streaming methods
  6422. jpeg.src := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_source_mgr));
  6423. // seeting up custom functions
  6424. with glBitmap_libJPEG_source_mgr_ptr(jpeg.src)^ do begin
  6425. pub.init_source := glBitmap_libJPEG_init_source;
  6426. pub.fill_input_buffer := glBitmap_libJPEG_fill_input_buffer;
  6427. pub.skip_input_data := glBitmap_libJPEG_skip_input_data;
  6428. pub.resync_to_restart := jpeg_resync_to_restart; // use default method
  6429. pub.term_source := glBitmap_libJPEG_term_source;
  6430. pub.bytes_in_buffer := 0; // forces fill_input_buffer on first read
  6431. pub.next_input_byte := nil; // until buffer loaded
  6432. SrcStream := aStream;
  6433. end;
  6434. // set global decoding state
  6435. jpeg.global_state := DSTATE_START;
  6436. // read header of jpeg
  6437. jpeg_read_header(@jpeg, false);
  6438. // setting output parameter
  6439. case jpeg.jpeg_color_space of
  6440. JCS_GRAYSCALE:
  6441. begin
  6442. jpeg.out_color_space := JCS_GRAYSCALE;
  6443. IntFormat := tfLuminance8ub1;
  6444. end;
  6445. else
  6446. jpeg.out_color_space := JCS_RGB;
  6447. IntFormat := tfRGB8ub3;
  6448. end;
  6449. // reading image
  6450. jpeg_start_decompress(@jpeg);
  6451. TempHeight := jpeg.output_height;
  6452. TempWidth := jpeg.output_width;
  6453. FormatDesc := TFormatDescriptor.Get(IntFormat);
  6454. // creating new image
  6455. GetMem(pImage, FormatDesc.GetSize(TempWidth, TempHeight));
  6456. try
  6457. pTemp := pImage;
  6458. for Row := 0 to TempHeight -1 do begin
  6459. jpeg_read_scanlines(@jpeg, @pTemp, 1);
  6460. Inc(pTemp, FormatDesc.GetSize(TempWidth, 1));
  6461. end;
  6462. // finish decompression
  6463. jpeg_finish_decompress(@jpeg);
  6464. // destroy decompression
  6465. jpeg_destroy_decompress(@jpeg);
  6466. SetDataPointer(pImage, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
  6467. result := true;
  6468. except
  6469. if Assigned(pImage) then
  6470. FreeMem(pImage);
  6471. raise;
  6472. end;
  6473. end;
  6474. finally
  6475. quit_libJPEG;
  6476. end;
  6477. end;
  6478. {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
  6479. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6480. function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
  6481. var
  6482. bmp: TBitmap;
  6483. jpg: TJPEGImage;
  6484. StreamPos: Int64;
  6485. Temp: array[0..1]of Byte;
  6486. begin
  6487. result := false;
  6488. // reading first two bytes to test file and set cursor back to begin
  6489. StreamPos := aStream.Position;
  6490. aStream.Read(Temp[0], 2);
  6491. aStream.Position := StreamPos;
  6492. // if Bitmap then read file.
  6493. if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
  6494. bmp := TBitmap.Create;
  6495. try
  6496. jpg := TJPEGImage.Create;
  6497. try
  6498. jpg.LoadFromStream(aStream);
  6499. bmp.Assign(jpg);
  6500. result := AssignFromBitmap(bmp);
  6501. finally
  6502. jpg.Free;
  6503. end;
  6504. finally
  6505. bmp.Free;
  6506. end;
  6507. end;
  6508. end;
  6509. {$IFEND}
  6510. {$ENDIF}
  6511. {$IFDEF GLB_SUPPORT_JPEG_WRITE}
  6512. {$IF DEFINED(GLB_LAZ_JPEG)}
  6513. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6514. procedure TglBitmap.SaveJPEG(const aStream: TStream);
  6515. var
  6516. jpeg: TJPEGImage;
  6517. intf: TLazIntfImage;
  6518. raw: TRawImage;
  6519. begin
  6520. jpeg := TJPEGImage.Create;
  6521. intf := TLazIntfImage.Create(0, 0);
  6522. try
  6523. if not AssignToLazIntfImage(intf) then
  6524. raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
  6525. intf.GetRawImage(raw);
  6526. jpeg.LoadFromRawImage(raw, false);
  6527. jpeg.SaveToStream(aStream);
  6528. finally
  6529. intf.Free;
  6530. jpeg.Free;
  6531. end;
  6532. end;
  6533. {$ELSEIF DEFINED(GLB_LIB_JPEG)}
  6534. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6535. procedure TglBitmap.SaveJPEG(const aStream: TStream);
  6536. var
  6537. jpeg: jpeg_compress_struct;
  6538. jpeg_err: jpeg_error_mgr;
  6539. Row: Integer;
  6540. pTemp, pTemp2: pByte;
  6541. procedure CopyRow(pDest, pSource: pByte);
  6542. var
  6543. X: Integer;
  6544. begin
  6545. for X := 0 to Width - 1 do begin
  6546. pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
  6547. pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
  6548. pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
  6549. Inc(pDest, 3);
  6550. Inc(pSource, 3);
  6551. end;
  6552. end;
  6553. begin
  6554. if not (ftJPEG in FormatGetSupportedFiles(Format)) then
  6555. raise EglBitmapUnsupportedFormat.Create(Format);
  6556. if not init_libJPEG then
  6557. raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
  6558. try
  6559. FillChar(jpeg{%H-}, SizeOf(jpeg_compress_struct), $00);
  6560. FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
  6561. // error managment
  6562. jpeg.err := jpeg_std_error(@jpeg_err);
  6563. jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
  6564. jpeg_err.output_message := glBitmap_libJPEG_output_message;
  6565. // compression struct
  6566. jpeg_create_compress(@jpeg);
  6567. // allocation space for streaming methods
  6568. jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
  6569. // seeting up custom functions
  6570. with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
  6571. pub.init_destination := glBitmap_libJPEG_init_destination;
  6572. pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
  6573. pub.term_destination := glBitmap_libJPEG_term_destination;
  6574. pub.next_output_byte := @DestBuffer[1];
  6575. pub.free_in_buffer := Length(DestBuffer);
  6576. DestStream := aStream;
  6577. end;
  6578. // very important state
  6579. jpeg.global_state := CSTATE_START;
  6580. jpeg.image_width := Width;
  6581. jpeg.image_height := Height;
  6582. case Format of
  6583. tfAlpha8ub1, tfLuminance8ub1: begin
  6584. jpeg.input_components := 1;
  6585. jpeg.in_color_space := JCS_GRAYSCALE;
  6586. end;
  6587. tfRGB8ub3, tfBGR8ub3: begin
  6588. jpeg.input_components := 3;
  6589. jpeg.in_color_space := JCS_RGB;
  6590. end;
  6591. end;
  6592. jpeg_set_defaults(@jpeg);
  6593. jpeg_set_quality(@jpeg, 95, true);
  6594. jpeg_start_compress(@jpeg, true);
  6595. pTemp := Data;
  6596. if Format = tfBGR8ub3 then
  6597. GetMem(pTemp2, fRowSize)
  6598. else
  6599. pTemp2 := pTemp;
  6600. try
  6601. for Row := 0 to jpeg.image_height -1 do begin
  6602. // prepare row
  6603. if Format = tfBGR8ub3 then
  6604. CopyRow(pTemp2, pTemp)
  6605. else
  6606. pTemp2 := pTemp;
  6607. // write row
  6608. jpeg_write_scanlines(@jpeg, @pTemp2, 1);
  6609. inc(pTemp, fRowSize);
  6610. end;
  6611. finally
  6612. // free memory
  6613. if Format = tfBGR8ub3 then
  6614. FreeMem(pTemp2);
  6615. end;
  6616. jpeg_finish_compress(@jpeg);
  6617. jpeg_destroy_compress(@jpeg);
  6618. finally
  6619. quit_libJPEG;
  6620. end;
  6621. end;
  6622. {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
  6623. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6624. procedure TglBitmap.SaveJPEG(const aStream: TStream);
  6625. var
  6626. Bmp: TBitmap;
  6627. Jpg: TJPEGImage;
  6628. begin
  6629. if not (ftJPEG in FormatGetSupportedFiles(Format)) then
  6630. raise EglBitmapUnsupportedFormat.Create(Format);
  6631. Bmp := TBitmap.Create;
  6632. try
  6633. Jpg := TJPEGImage.Create;
  6634. try
  6635. AssignToBitmap(Bmp);
  6636. if (Format in [tfAlpha8ub1, tfLuminance8ub1]) then begin
  6637. Jpg.Grayscale := true;
  6638. Jpg.PixelFormat := jf8Bit;
  6639. end;
  6640. Jpg.Assign(Bmp);
  6641. Jpg.SaveToStream(aStream);
  6642. finally
  6643. FreeAndNil(Jpg);
  6644. end;
  6645. finally
  6646. FreeAndNil(Bmp);
  6647. end;
  6648. end;
  6649. {$IFEND}
  6650. {$ENDIF}
  6651. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6652. //RAW/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6653. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6654. type
  6655. RawHeader = packed record
  6656. Magic: String[5];
  6657. Version: Byte;
  6658. Width: Integer;
  6659. Height: Integer;
  6660. DataSize: Integer;
  6661. BitsPerPixel: Integer;
  6662. Precision: TglBitmapRec4ub;
  6663. Shift: TglBitmapRec4ub;
  6664. end;
  6665. function TglBitmap.LoadRAW(const aStream: TStream): Boolean;
  6666. var
  6667. header: RawHeader;
  6668. StartPos: Int64;
  6669. fd: TFormatDescriptor;
  6670. buf: PByte;
  6671. begin
  6672. result := false;
  6673. StartPos := aStream.Position;
  6674. aStream.Read(header{%H-}, SizeOf(header));
  6675. if (header.Magic <> 'glBMP') then begin
  6676. aStream.Position := StartPos;
  6677. exit;
  6678. end;
  6679. fd := TFormatDescriptor.GetFromPrecShift(header.Precision, header.Shift, header.BitsPerPixel);
  6680. if (fd.Format = tfEmpty) then
  6681. raise EglBitmapUnsupportedFormat.Create('no supported format found');
  6682. buf := GetMemory(header.DataSize);
  6683. aStream.Read(buf^, header.DataSize);
  6684. SetDataPointer(buf, fd.Format, header.Width, header.Height);
  6685. result := true;
  6686. end;
  6687. procedure TglBitmap.SaveRAW(const aStream: TStream);
  6688. var
  6689. header: RawHeader;
  6690. fd: TFormatDescriptor;
  6691. begin
  6692. fd := TFormatDescriptor.Get(Format);
  6693. header.Magic := 'glBMP';
  6694. header.Version := 1;
  6695. header.Width := Width;
  6696. header.Height := Height;
  6697. header.DataSize := fd.GetSize(fDimension);
  6698. header.BitsPerPixel := fd.BitsPerPixel;
  6699. header.Precision := fd.Precision;
  6700. header.Shift := fd.Shift;
  6701. aStream.Write(header, SizeOf(header));
  6702. aStream.Write(Data^, header.DataSize);
  6703. end;
  6704. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6705. //BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6706. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6707. const
  6708. BMP_MAGIC = $4D42;
  6709. BMP_COMP_RGB = 0;
  6710. BMP_COMP_RLE8 = 1;
  6711. BMP_COMP_RLE4 = 2;
  6712. BMP_COMP_BITFIELDS = 3;
  6713. type
  6714. TBMPHeader = packed record
  6715. bfType: Word;
  6716. bfSize: Cardinal;
  6717. bfReserved1: Word;
  6718. bfReserved2: Word;
  6719. bfOffBits: Cardinal;
  6720. end;
  6721. TBMPInfo = packed record
  6722. biSize: Cardinal;
  6723. biWidth: Longint;
  6724. biHeight: Longint;
  6725. biPlanes: Word;
  6726. biBitCount: Word;
  6727. biCompression: Cardinal;
  6728. biSizeImage: Cardinal;
  6729. biXPelsPerMeter: Longint;
  6730. biYPelsPerMeter: Longint;
  6731. biClrUsed: Cardinal;
  6732. biClrImportant: Cardinal;
  6733. end;
  6734. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6735. function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
  6736. //////////////////////////////////////////////////////////////////////////////////////////////////
  6737. function ReadInfo(out aInfo: TBMPInfo; out aMask: TglBitmapRec4ul): TglBitmapFormat;
  6738. begin
  6739. result := tfEmpty;
  6740. aStream.Read(aInfo{%H-}, SizeOf(aInfo));
  6741. FillChar(aMask{%H-}, SizeOf(aMask), 0);
  6742. //Read Compression
  6743. case aInfo.biCompression of
  6744. BMP_COMP_RLE4,
  6745. BMP_COMP_RLE8: begin
  6746. raise EglBitmap.Create('RLE compression is not supported');
  6747. end;
  6748. BMP_COMP_BITFIELDS: begin
  6749. if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
  6750. aStream.Read(aMask.r, SizeOf(aMask.r));
  6751. aStream.Read(aMask.g, SizeOf(aMask.g));
  6752. aStream.Read(aMask.b, SizeOf(aMask.b));
  6753. aStream.Read(aMask.a, SizeOf(aMask.a));
  6754. end else
  6755. raise EglBitmap.Create('Bitfields are only supported for 16bit and 32bit formats');
  6756. end;
  6757. end;
  6758. //get suitable format
  6759. case aInfo.biBitCount of
  6760. 8: result := tfLuminance8ub1;
  6761. 16: result := tfX1RGB5us1;
  6762. 24: result := tfBGR8ub3;
  6763. 32: result := tfXRGB8ui1;
  6764. end;
  6765. end;
  6766. function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TbmpColorTableFormat;
  6767. var
  6768. i, c: Integer;
  6769. ColorTable: TbmpColorTable;
  6770. begin
  6771. result := nil;
  6772. if (aInfo.biBitCount >= 16) then
  6773. exit;
  6774. aFormat := tfLuminance8ub1;
  6775. c := aInfo.biClrUsed;
  6776. if (c = 0) then
  6777. c := 1 shl aInfo.biBitCount;
  6778. SetLength(ColorTable, c);
  6779. for i := 0 to c-1 do begin
  6780. aStream.Read(ColorTable[i], SizeOf(TbmpColorTableEnty));
  6781. if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then
  6782. aFormat := tfRGB8ub3;
  6783. end;
  6784. result := TbmpColorTableFormat.Create;
  6785. result.BitsPerPixel := aInfo.biBitCount;
  6786. result.ColorTable := ColorTable;
  6787. result.CalcValues;
  6788. end;
  6789. //////////////////////////////////////////////////////////////////////////////////////////////////
  6790. function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapRec4ul; const aInfo: TBMPInfo): TbmpBitfieldFormat;
  6791. var
  6792. FormatDesc: TFormatDescriptor;
  6793. begin
  6794. result := nil;
  6795. if (aMask.r <> 0) or (aMask.g <> 0) or (aMask.b <> 0) or (aMask.a <> 0) then begin
  6796. FormatDesc := TFormatDescriptor.GetFromMask(aMask);
  6797. if (FormatDesc.Format = tfEmpty) then
  6798. exit;
  6799. aFormat := FormatDesc.Format;
  6800. if (aMask.a = 0) and TFormatDescriptor.Get(aFormat).HasAlpha then
  6801. aFormat := TFormatDescriptor.Get(aFormat).WithoutAlpha;
  6802. if (aMask.a <> 0) and not TFormatDescriptor.Get(aFormat).HasAlpha then
  6803. aFormat := TFormatDescriptor.Get(aFormat).WithAlpha;
  6804. result := TbmpBitfieldFormat.Create;
  6805. result.SetCustomValues(aInfo.biBitCount, aMask);
  6806. end;
  6807. end;
  6808. var
  6809. //simple types
  6810. StartPos: Int64;
  6811. ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
  6812. PaddingBuff: Cardinal;
  6813. LineBuf, ImageData, TmpData: PByte;
  6814. SourceMD, DestMD: Pointer;
  6815. BmpFormat: TglBitmapFormat;
  6816. //records
  6817. Mask: TglBitmapRec4ul;
  6818. Header: TBMPHeader;
  6819. Info: TBMPInfo;
  6820. //classes
  6821. SpecialFormat: TFormatDescriptor;
  6822. FormatDesc: TFormatDescriptor;
  6823. //////////////////////////////////////////////////////////////////////////////////////////////////
  6824. procedure SpecialFormatReadLine(aData: PByte; aLineBuf: PByte);
  6825. var
  6826. i: Integer;
  6827. Pixel: TglBitmapPixelData;
  6828. begin
  6829. aStream.Read(aLineBuf^, rbLineSize);
  6830. SpecialFormat.PreparePixel(Pixel);
  6831. for i := 0 to Info.biWidth-1 do begin
  6832. SpecialFormat.Unmap(aLineBuf, Pixel, SourceMD);
  6833. glBitmapConvertPixel(Pixel, SpecialFormat, FormatDesc);
  6834. FormatDesc.Map(Pixel, aData, DestMD);
  6835. end;
  6836. end;
  6837. begin
  6838. result := false;
  6839. BmpFormat := tfEmpty;
  6840. SpecialFormat := nil;
  6841. LineBuf := nil;
  6842. SourceMD := nil;
  6843. DestMD := nil;
  6844. // Header
  6845. StartPos := aStream.Position;
  6846. aStream.Read(Header{%H-}, SizeOf(Header));
  6847. if Header.bfType = BMP_MAGIC then begin
  6848. try try
  6849. BmpFormat := ReadInfo(Info, Mask);
  6850. SpecialFormat := ReadColorTable(BmpFormat, Info);
  6851. if not Assigned(SpecialFormat) then
  6852. SpecialFormat := CheckBitfields(BmpFormat, Mask, Info);
  6853. aStream.Position := StartPos + Header.bfOffBits;
  6854. if (BmpFormat <> tfEmpty) then begin
  6855. FormatDesc := TFormatDescriptor.Get(BmpFormat);
  6856. rbLineSize := Round(Info.biWidth * Info.biBitCount / 8); //ReadBuffer LineSize
  6857. wbLineSize := Trunc(Info.biWidth * FormatDesc.BytesPerPixel);
  6858. Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
  6859. //get Memory
  6860. DestMD := FormatDesc.CreateMappingData;
  6861. ImageSize := FormatDesc.GetSize(Info.biWidth, abs(Info.biHeight));
  6862. GetMem(ImageData, ImageSize);
  6863. if Assigned(SpecialFormat) then begin
  6864. GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
  6865. SourceMD := SpecialFormat.CreateMappingData;
  6866. end;
  6867. //read Data
  6868. try try
  6869. FillChar(ImageData^, ImageSize, $FF);
  6870. TmpData := ImageData;
  6871. if (Info.biHeight > 0) then
  6872. Inc(TmpData, wbLineSize * (Info.biHeight-1));
  6873. for i := 0 to Abs(Info.biHeight)-1 do begin
  6874. if Assigned(SpecialFormat) then
  6875. SpecialFormatReadLine(TmpData, LineBuf) //if is special format read and convert data
  6876. else
  6877. aStream.Read(TmpData^, wbLineSize); //else only read data
  6878. if (Info.biHeight > 0) then
  6879. dec(TmpData, wbLineSize)
  6880. else
  6881. inc(TmpData, wbLineSize);
  6882. aStream.Read(PaddingBuff{%H-}, Padding);
  6883. end;
  6884. SetDataPointer(ImageData, BmpFormat, Info.biWidth, abs(Info.biHeight)); //be careful, Data could be freed by this method
  6885. result := true;
  6886. finally
  6887. if Assigned(LineBuf) then
  6888. FreeMem(LineBuf);
  6889. if Assigned(SourceMD) then
  6890. SpecialFormat.FreeMappingData(SourceMD);
  6891. FormatDesc.FreeMappingData(DestMD);
  6892. end;
  6893. except
  6894. if Assigned(ImageData) then
  6895. FreeMem(ImageData);
  6896. raise;
  6897. end;
  6898. end else
  6899. raise EglBitmap.Create('LoadBMP - No suitable format found');
  6900. except
  6901. aStream.Position := StartPos;
  6902. raise;
  6903. end;
  6904. finally
  6905. FreeAndNil(SpecialFormat);
  6906. end;
  6907. end
  6908. else aStream.Position := StartPos;
  6909. end;
  6910. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6911. procedure TglBitmap.SaveBMP(const aStream: TStream);
  6912. var
  6913. Header: TBMPHeader;
  6914. Info: TBMPInfo;
  6915. Converter: TFormatDescriptor;
  6916. FormatDesc: TFormatDescriptor;
  6917. SourceFD, DestFD: Pointer;
  6918. pData, srcData, dstData, ConvertBuffer: pByte;
  6919. Pixel: TglBitmapPixelData;
  6920. ImageSize, wbLineSize, rbLineSize, Padding, LineIdx, PixelIdx: Integer;
  6921. RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
  6922. PaddingBuff: Cardinal;
  6923. function GetLineWidth : Integer;
  6924. begin
  6925. result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
  6926. end;
  6927. begin
  6928. if not (ftBMP in FormatGetSupportedFiles(Format)) then
  6929. raise EglBitmapUnsupportedFormat.Create(Format);
  6930. Converter := nil;
  6931. FormatDesc := TFormatDescriptor.Get(Format);
  6932. ImageSize := FormatDesc.GetSize(Dimension);
  6933. FillChar(Header{%H-}, SizeOf(Header), 0);
  6934. Header.bfType := BMP_MAGIC;
  6935. Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
  6936. Header.bfReserved1 := 0;
  6937. Header.bfReserved2 := 0;
  6938. Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
  6939. FillChar(Info{%H-}, SizeOf(Info), 0);
  6940. Info.biSize := SizeOf(Info);
  6941. Info.biWidth := Width;
  6942. Info.biHeight := Height;
  6943. Info.biPlanes := 1;
  6944. Info.biCompression := BMP_COMP_RGB;
  6945. Info.biSizeImage := ImageSize;
  6946. try
  6947. case Format of
  6948. tfAlpha4ub1, tfAlpha8ub1, tfLuminance4ub1, tfLuminance8ub1, tfR3G3B2ub1:
  6949. begin
  6950. Info.biBitCount := 8;
  6951. Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
  6952. Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal); //256 ColorTable entries
  6953. Converter := TbmpColorTableFormat.Create;
  6954. with (Converter as TbmpColorTableFormat) do begin
  6955. SetCustomValues(fFormat, 1, FormatDesc.Precision, FormatDesc.Shift);
  6956. CreateColorTable;
  6957. end;
  6958. end;
  6959. tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
  6960. tfRGBX4us1, tfXRGB4us1, tfRGB5X1us1, tfX1RGB5us1, tfR5G6B5us1, tfRGB5A1us1, tfA1RGB5us1, tfRGBA4us1, tfARGB4us1,
  6961. tfBGRX4us1, tfXBGR4us1, tfBGR5X1us1, tfX1BGR5us1, tfB5G6R5us1, tfBGR5A1us1, tfA1BGR5us1, tfBGRA4us1, tfABGR4us1:
  6962. begin
  6963. Info.biBitCount := 16;
  6964. Info.biCompression := BMP_COMP_BITFIELDS;
  6965. end;
  6966. tfBGR8ub3, tfRGB8ub3:
  6967. begin
  6968. Info.biBitCount := 24;
  6969. if (Format = tfRGB8ub3) then
  6970. Converter := TfdBGR8ub3.Create; //use BGR8 Format Descriptor to Swap RGB Values
  6971. end;
  6972. tfRGBX8ui1, tfXRGB8ui1, tfRGB10X2ui1, tfX2RGB10ui1, tfRGBA8ui1, tfARGB8ui1, tfRGBA8ub4, tfRGB10A2ui1, tfA2RGB10ui1,
  6973. tfBGRX8ui1, tfXBGR8ui1, tfBGR10X2ui1, tfX2BGR10ui1, tfBGRA8ui1, tfABGR8ui1, tfBGRA8ub4, tfBGR10A2ui1, tfA2BGR10ui1:
  6974. begin
  6975. Info.biBitCount := 32;
  6976. Info.biCompression := BMP_COMP_BITFIELDS;
  6977. end;
  6978. else
  6979. raise EglBitmapUnsupportedFormat.Create(Format);
  6980. end;
  6981. Info.biXPelsPerMeter := 2835;
  6982. Info.biYPelsPerMeter := 2835;
  6983. // prepare bitmasks
  6984. if Info.biCompression = BMP_COMP_BITFIELDS then begin
  6985. Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
  6986. Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
  6987. RedMask := FormatDesc.Mask.r;
  6988. GreenMask := FormatDesc.Mask.g;
  6989. BlueMask := FormatDesc.Mask.b;
  6990. AlphaMask := FormatDesc.Mask.a;
  6991. end;
  6992. // headers
  6993. aStream.Write(Header, SizeOf(Header));
  6994. aStream.Write(Info, SizeOf(Info));
  6995. // colortable
  6996. if Assigned(Converter) and (Converter is TbmpColorTableFormat) then
  6997. with (Converter as TbmpColorTableFormat) do
  6998. aStream.Write(ColorTable[0].b,
  6999. SizeOf(TbmpColorTableEnty) * Length(ColorTable));
  7000. // bitmasks
  7001. if Info.biCompression = BMP_COMP_BITFIELDS then begin
  7002. aStream.Write(RedMask, SizeOf(Cardinal));
  7003. aStream.Write(GreenMask, SizeOf(Cardinal));
  7004. aStream.Write(BlueMask, SizeOf(Cardinal));
  7005. aStream.Write(AlphaMask, SizeOf(Cardinal));
  7006. end;
  7007. // image data
  7008. rbLineSize := Round(Info.biWidth * FormatDesc.BytesPerPixel);
  7009. wbLineSize := Round(Info.biWidth * Info.biBitCount / 8);
  7010. Padding := GetLineWidth - wbLineSize;
  7011. PaddingBuff := 0;
  7012. pData := Data;
  7013. inc(pData, (Height-1) * rbLineSize);
  7014. // prepare row buffer. But only for RGB because RGBA supports color masks
  7015. // so it's possible to change color within the image.
  7016. if Assigned(Converter) then begin
  7017. FormatDesc.PreparePixel(Pixel);
  7018. GetMem(ConvertBuffer, wbLineSize);
  7019. SourceFD := FormatDesc.CreateMappingData;
  7020. DestFD := Converter.CreateMappingData;
  7021. end else
  7022. ConvertBuffer := nil;
  7023. try
  7024. for LineIdx := 0 to Height - 1 do begin
  7025. // preparing row
  7026. if Assigned(Converter) then begin
  7027. srcData := pData;
  7028. dstData := ConvertBuffer;
  7029. for PixelIdx := 0 to Info.biWidth-1 do begin
  7030. FormatDesc.Unmap(srcData, Pixel, SourceFD);
  7031. glBitmapConvertPixel(Pixel, FormatDesc, Converter);
  7032. Converter.Map(Pixel, dstData, DestFD);
  7033. end;
  7034. aStream.Write(ConvertBuffer^, wbLineSize);
  7035. end else begin
  7036. aStream.Write(pData^, rbLineSize);
  7037. end;
  7038. dec(pData, rbLineSize);
  7039. if (Padding > 0) then
  7040. aStream.Write(PaddingBuff, Padding);
  7041. end;
  7042. finally
  7043. // destroy row buffer
  7044. if Assigned(ConvertBuffer) then begin
  7045. FormatDesc.FreeMappingData(SourceFD);
  7046. Converter.FreeMappingData(DestFD);
  7047. FreeMem(ConvertBuffer);
  7048. end;
  7049. end;
  7050. finally
  7051. if Assigned(Converter) then
  7052. Converter.Free;
  7053. end;
  7054. end;
  7055. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7056. //TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7057. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7058. type
  7059. TTGAHeader = packed record
  7060. ImageID: Byte;
  7061. ColorMapType: Byte;
  7062. ImageType: Byte;
  7063. //ColorMapSpec: Array[0..4] of Byte;
  7064. ColorMapStart: Word;
  7065. ColorMapLength: Word;
  7066. ColorMapEntrySize: Byte;
  7067. OrigX: Word;
  7068. OrigY: Word;
  7069. Width: Word;
  7070. Height: Word;
  7071. Bpp: Byte;
  7072. ImageDesc: Byte;
  7073. end;
  7074. const
  7075. TGA_UNCOMPRESSED_RGB = 2;
  7076. TGA_UNCOMPRESSED_GRAY = 3;
  7077. TGA_COMPRESSED_RGB = 10;
  7078. TGA_COMPRESSED_GRAY = 11;
  7079. TGA_NONE_COLOR_TABLE = 0;
  7080. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7081. function TglBitmap.LoadTGA(const aStream: TStream): Boolean;
  7082. var
  7083. Header: TTGAHeader;
  7084. ImageData: System.PByte;
  7085. StartPosition: Int64;
  7086. PixelSize, LineSize: Integer;
  7087. tgaFormat: TglBitmapFormat;
  7088. FormatDesc: TFormatDescriptor;
  7089. Counter: packed record
  7090. X, Y: packed record
  7091. low, high, dir: Integer;
  7092. end;
  7093. end;
  7094. const
  7095. CACHE_SIZE = $4000;
  7096. ////////////////////////////////////////////////////////////////////////////////////////
  7097. procedure ReadUncompressed;
  7098. var
  7099. i, j: Integer;
  7100. buf, tmp1, tmp2: System.PByte;
  7101. begin
  7102. buf := nil;
  7103. if (Counter.X.dir < 0) then
  7104. GetMem(buf, LineSize);
  7105. try
  7106. while (Counter.Y.low <> Counter.Y.high + counter.Y.dir) do begin
  7107. tmp1 := ImageData;
  7108. inc(tmp1, (Counter.Y.low * LineSize)); //pointer to LineStart
  7109. if (Counter.X.dir < 0) then begin //flip X
  7110. aStream.Read(buf^, LineSize);
  7111. tmp2 := buf;
  7112. inc(tmp2, LineSize - PixelSize); //pointer to last pixel in line
  7113. for i := 0 to Header.Width-1 do begin //for all pixels in line
  7114. for j := 0 to PixelSize-1 do begin //for all bytes in pixel
  7115. tmp1^ := tmp2^;
  7116. inc(tmp1);
  7117. inc(tmp2);
  7118. end;
  7119. dec(tmp2, 2*PixelSize); //move 2 backwards, because j-loop moved 1 forward
  7120. end;
  7121. end else
  7122. aStream.Read(tmp1^, LineSize);
  7123. inc(Counter.Y.low, Counter.Y.dir); //move to next line index
  7124. end;
  7125. finally
  7126. if Assigned(buf) then
  7127. FreeMem(buf);
  7128. end;
  7129. end;
  7130. ////////////////////////////////////////////////////////////////////////////////////////
  7131. procedure ReadCompressed;
  7132. /////////////////////////////////////////////////////////////////
  7133. var
  7134. TmpData: System.PByte;
  7135. LinePixelsRead: Integer;
  7136. procedure CheckLine;
  7137. begin
  7138. if (LinePixelsRead >= Header.Width) then begin
  7139. LinePixelsRead := 0;
  7140. inc(Counter.Y.low, Counter.Y.dir); //next line index
  7141. TmpData := ImageData;
  7142. inc(TmpData, Counter.Y.low * LineSize); //set line
  7143. if (Counter.X.dir < 0) then //if x flipped then
  7144. inc(TmpData, LineSize - PixelSize); //set last pixel
  7145. end;
  7146. end;
  7147. /////////////////////////////////////////////////////////////////
  7148. var
  7149. Cache: PByte;
  7150. CacheSize, CachePos: Integer;
  7151. procedure CachedRead(out Buffer; Count: Integer);
  7152. var
  7153. BytesRead: Integer;
  7154. begin
  7155. if (CachePos + Count > CacheSize) then begin
  7156. //if buffer overflow save non read bytes
  7157. BytesRead := 0;
  7158. if (CacheSize - CachePos > 0) then begin
  7159. BytesRead := CacheSize - CachePos;
  7160. Move(PByteArray(Cache)^[CachePos], Buffer{%H-}, BytesRead);
  7161. inc(CachePos, BytesRead);
  7162. end;
  7163. //load cache from file
  7164. CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
  7165. aStream.Read(Cache^, CacheSize);
  7166. CachePos := 0;
  7167. //read rest of requested bytes
  7168. if (Count - BytesRead > 0) then begin
  7169. Move(PByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
  7170. inc(CachePos, Count - BytesRead);
  7171. end;
  7172. end else begin
  7173. //if no buffer overflow just read the data
  7174. Move(PByteArray(Cache)^[CachePos], Buffer, Count);
  7175. inc(CachePos, Count);
  7176. end;
  7177. end;
  7178. procedure PixelToBuffer(const aData: PByte; var aBuffer: PByte);
  7179. begin
  7180. case PixelSize of
  7181. 1: begin
  7182. aBuffer^ := aData^;
  7183. inc(aBuffer, Counter.X.dir);
  7184. end;
  7185. 2: begin
  7186. PWord(aBuffer)^ := PWord(aData)^;
  7187. inc(aBuffer, 2 * Counter.X.dir);
  7188. end;
  7189. 3: begin
  7190. PByteArray(aBuffer)^[0] := PByteArray(aData)^[0];
  7191. PByteArray(aBuffer)^[1] := PByteArray(aData)^[1];
  7192. PByteArray(aBuffer)^[2] := PByteArray(aData)^[2];
  7193. inc(aBuffer, 3 * Counter.X.dir);
  7194. end;
  7195. 4: begin
  7196. PCardinal(aBuffer)^ := PCardinal(aData)^;
  7197. inc(aBuffer, 4 * Counter.X.dir);
  7198. end;
  7199. end;
  7200. end;
  7201. var
  7202. TotalPixelsToRead, TotalPixelsRead: Integer;
  7203. Temp: Byte;
  7204. buf: array [0..3] of Byte; //1 pixel is max 32bit long
  7205. PixelRepeat: Boolean;
  7206. PixelsToRead, PixelCount: Integer;
  7207. begin
  7208. CacheSize := 0;
  7209. CachePos := 0;
  7210. TotalPixelsToRead := Header.Width * Header.Height;
  7211. TotalPixelsRead := 0;
  7212. LinePixelsRead := 0;
  7213. GetMem(Cache, CACHE_SIZE);
  7214. try
  7215. TmpData := ImageData;
  7216. inc(TmpData, Counter.Y.low * LineSize); //set line
  7217. if (Counter.X.dir < 0) then //if x flipped then
  7218. inc(TmpData, LineSize - PixelSize); //set last pixel
  7219. repeat
  7220. //read CommandByte
  7221. CachedRead(Temp, 1);
  7222. PixelRepeat := (Temp and $80) > 0;
  7223. PixelsToRead := (Temp and $7F) + 1;
  7224. inc(TotalPixelsRead, PixelsToRead);
  7225. if PixelRepeat then
  7226. CachedRead(buf[0], PixelSize);
  7227. while (PixelsToRead > 0) do begin
  7228. CheckLine;
  7229. PixelCount := Min(Header.Width - LinePixelsRead, PixelsToRead); //max read to EOL or EOF
  7230. while (PixelCount > 0) do begin
  7231. if not PixelRepeat then
  7232. CachedRead(buf[0], PixelSize);
  7233. PixelToBuffer(@buf[0], TmpData);
  7234. inc(LinePixelsRead);
  7235. dec(PixelsToRead);
  7236. dec(PixelCount);
  7237. end;
  7238. end;
  7239. until (TotalPixelsRead >= TotalPixelsToRead);
  7240. finally
  7241. FreeMem(Cache);
  7242. end;
  7243. end;
  7244. function IsGrayFormat: Boolean;
  7245. begin
  7246. result := Header.ImageType in [TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_GRAY];
  7247. end;
  7248. begin
  7249. result := false;
  7250. // reading header to test file and set cursor back to begin
  7251. StartPosition := aStream.Position;
  7252. aStream.Read(Header{%H-}, SizeOf(Header));
  7253. // no colormapped files
  7254. if (Header.ColorMapType = TGA_NONE_COLOR_TABLE) and (Header.ImageType in [
  7255. TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY]) then
  7256. begin
  7257. try
  7258. if Header.ImageID <> 0 then // skip image ID
  7259. aStream.Position := aStream.Position + Header.ImageID;
  7260. tgaFormat := tfEmpty;
  7261. case Header.Bpp of
  7262. 8: if IsGrayFormat then case (Header.ImageDesc and $F) of
  7263. 0: tgaFormat := tfLuminance8ub1;
  7264. 8: tgaFormat := tfAlpha8ub1;
  7265. end;
  7266. 16: if IsGrayFormat then case (Header.ImageDesc and $F) of
  7267. 0: tgaFormat := tfLuminance16us1;
  7268. 8: tgaFormat := tfLuminance8Alpha8ub2;
  7269. end else case (Header.ImageDesc and $F) of
  7270. 0: tgaFormat := tfX1RGB5us1;
  7271. 1: tgaFormat := tfA1RGB5us1;
  7272. 4: tgaFormat := tfARGB4us1;
  7273. end;
  7274. 24: if not IsGrayFormat then case (Header.ImageDesc and $F) of
  7275. 0: tgaFormat := tfBGR8ub3;
  7276. end;
  7277. 32: if IsGrayFormat then case (Header.ImageDesc and $F) of
  7278. 0: tgaFormat := tfDepth32ui1;
  7279. end else case (Header.ImageDesc and $F) of
  7280. 0: tgaFormat := tfX2RGB10ui1;
  7281. 2: tgaFormat := tfA2RGB10ui1;
  7282. 8: tgaFormat := tfARGB8ui1;
  7283. end;
  7284. end;
  7285. if (tgaFormat = tfEmpty) then
  7286. raise EglBitmap.Create('LoadTga - unsupported format');
  7287. FormatDesc := TFormatDescriptor.Get(tgaFormat);
  7288. PixelSize := FormatDesc.GetSize(1, 1);
  7289. LineSize := FormatDesc.GetSize(Header.Width, 1);
  7290. GetMem(ImageData, LineSize * Header.Height);
  7291. try
  7292. //column direction
  7293. if ((Header.ImageDesc and (1 shl 4)) > 0) then begin
  7294. Counter.X.low := Header.Height-1;;
  7295. Counter.X.high := 0;
  7296. Counter.X.dir := -1;
  7297. end else begin
  7298. Counter.X.low := 0;
  7299. Counter.X.high := Header.Height-1;
  7300. Counter.X.dir := 1;
  7301. end;
  7302. // Row direction
  7303. if ((Header.ImageDesc and (1 shl 5)) > 0) then begin
  7304. Counter.Y.low := 0;
  7305. Counter.Y.high := Header.Height-1;
  7306. Counter.Y.dir := 1;
  7307. end else begin
  7308. Counter.Y.low := Header.Height-1;;
  7309. Counter.Y.high := 0;
  7310. Counter.Y.dir := -1;
  7311. end;
  7312. // Read Image
  7313. case Header.ImageType of
  7314. TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY:
  7315. ReadUncompressed;
  7316. TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY:
  7317. ReadCompressed;
  7318. end;
  7319. SetDataPointer(ImageData, tgaFormat, Header.Width, Header.Height); //be careful, Data could be freed by this method
  7320. result := true;
  7321. except
  7322. if Assigned(ImageData) then
  7323. FreeMem(ImageData);
  7324. raise;
  7325. end;
  7326. finally
  7327. aStream.Position := StartPosition;
  7328. end;
  7329. end
  7330. else aStream.Position := StartPosition;
  7331. end;
  7332. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7333. procedure TglBitmap.SaveTGA(const aStream: TStream);
  7334. var
  7335. Header: TTGAHeader;
  7336. Size: Integer;
  7337. FormatDesc: TFormatDescriptor;
  7338. begin
  7339. if not (ftTGA in FormatGetSupportedFiles(Format)) then
  7340. raise EglBitmapUnsupportedFormat.Create(Format);
  7341. //prepare header
  7342. FormatDesc := TFormatDescriptor.Get(Format);
  7343. FillChar(Header{%H-}, SizeOf(Header), 0);
  7344. Header.ImageDesc := CountSetBits(FormatDesc.Range.a) and $F;
  7345. Header.Bpp := FormatDesc.BitsPerPixel;
  7346. Header.Width := Width;
  7347. Header.Height := Height;
  7348. Header.ImageDesc := Header.ImageDesc or $20; //flip y
  7349. if FormatDesc.IsGrayscale or (not FormatDesc.IsGrayscale and not FormatDesc.HasRed and FormatDesc.HasAlpha) then
  7350. Header.ImageType := TGA_UNCOMPRESSED_GRAY
  7351. else
  7352. Header.ImageType := TGA_UNCOMPRESSED_RGB;
  7353. aStream.Write(Header, SizeOf(Header));
  7354. // write Data
  7355. Size := FormatDesc.GetSize(Dimension);
  7356. aStream.Write(Data^, Size);
  7357. end;
  7358. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7359. //DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7360. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7361. const
  7362. DDS_MAGIC: Cardinal = $20534444;
  7363. // DDS_header.dwFlags
  7364. DDSD_CAPS = $00000001;
  7365. DDSD_HEIGHT = $00000002;
  7366. DDSD_WIDTH = $00000004;
  7367. DDSD_PIXELFORMAT = $00001000;
  7368. // DDS_header.sPixelFormat.dwFlags
  7369. DDPF_ALPHAPIXELS = $00000001;
  7370. DDPF_ALPHA = $00000002;
  7371. DDPF_FOURCC = $00000004;
  7372. DDPF_RGB = $00000040;
  7373. DDPF_LUMINANCE = $00020000;
  7374. // DDS_header.sCaps.dwCaps1
  7375. DDSCAPS_TEXTURE = $00001000;
  7376. // DDS_header.sCaps.dwCaps2
  7377. DDSCAPS2_CUBEMAP = $00000200;
  7378. D3DFMT_DXT1 = $31545844;
  7379. D3DFMT_DXT3 = $33545844;
  7380. D3DFMT_DXT5 = $35545844;
  7381. type
  7382. TDDSPixelFormat = packed record
  7383. dwSize: Cardinal;
  7384. dwFlags: Cardinal;
  7385. dwFourCC: Cardinal;
  7386. dwRGBBitCount: Cardinal;
  7387. dwRBitMask: Cardinal;
  7388. dwGBitMask: Cardinal;
  7389. dwBBitMask: Cardinal;
  7390. dwABitMask: Cardinal;
  7391. end;
  7392. TDDSCaps = packed record
  7393. dwCaps1: Cardinal;
  7394. dwCaps2: Cardinal;
  7395. dwDDSX: Cardinal;
  7396. dwReserved: Cardinal;
  7397. end;
  7398. TDDSHeader = packed record
  7399. dwSize: Cardinal;
  7400. dwFlags: Cardinal;
  7401. dwHeight: Cardinal;
  7402. dwWidth: Cardinal;
  7403. dwPitchOrLinearSize: Cardinal;
  7404. dwDepth: Cardinal;
  7405. dwMipMapCount: Cardinal;
  7406. dwReserved: array[0..10] of Cardinal;
  7407. PixelFormat: TDDSPixelFormat;
  7408. Caps: TDDSCaps;
  7409. dwReserved2: Cardinal;
  7410. end;
  7411. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7412. function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
  7413. var
  7414. Header: TDDSHeader;
  7415. Converter: TbmpBitfieldFormat;
  7416. function GetDDSFormat: TglBitmapFormat;
  7417. var
  7418. fd: TFormatDescriptor;
  7419. i: Integer;
  7420. Mask: TglBitmapRec4ul;
  7421. Range: TglBitmapRec4ui;
  7422. match: Boolean;
  7423. begin
  7424. result := tfEmpty;
  7425. with Header.PixelFormat do begin
  7426. // Compresses
  7427. if ((dwFlags and DDPF_FOURCC) > 0) then begin
  7428. case Header.PixelFormat.dwFourCC of
  7429. D3DFMT_DXT1: result := tfS3tcDtx1RGBA;
  7430. D3DFMT_DXT3: result := tfS3tcDtx3RGBA;
  7431. D3DFMT_DXT5: result := tfS3tcDtx5RGBA;
  7432. end;
  7433. end else if ((dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE or DDPF_ALPHA)) > 0) then begin
  7434. // prepare masks
  7435. if ((dwFlags and DDPF_LUMINANCE) = 0) then begin
  7436. Mask.r := dwRBitMask;
  7437. Mask.g := dwGBitMask;
  7438. Mask.b := dwBBitMask;
  7439. end else begin
  7440. Mask.r := dwRBitMask;
  7441. Mask.g := dwRBitMask;
  7442. Mask.b := dwRBitMask;
  7443. end;
  7444. if (dwFlags and DDPF_ALPHAPIXELS > 0) then
  7445. Mask.a := dwABitMask
  7446. else
  7447. Mask.a := 0;;
  7448. //find matching format
  7449. fd := TFormatDescriptor.GetFromMask(Mask, dwRGBBitCount);
  7450. result := fd.Format;
  7451. if (result <> tfEmpty) then
  7452. exit;
  7453. //find format with same Range
  7454. for i := 0 to 3 do
  7455. Range.arr[i] := (2 shl CountSetBits(Mask.arr[i])) - 1;
  7456. for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
  7457. fd := TFormatDescriptor.Get(result);
  7458. match := true;
  7459. for i := 0 to 3 do
  7460. if (fd.Range.arr[i] <> Range.arr[i]) then begin
  7461. match := false;
  7462. break;
  7463. end;
  7464. if match then
  7465. break;
  7466. end;
  7467. //no format with same range found -> use default
  7468. if (result = tfEmpty) then begin
  7469. if (dwABitMask > 0) then
  7470. result := tfRGBA8ui1
  7471. else
  7472. result := tfRGB8ub3;
  7473. end;
  7474. Converter := TbmpBitfieldFormat.Create;
  7475. Converter.SetCustomValues(dwRGBBitCount, glBitmapRec4ul(dwRBitMask, dwGBitMask, dwBBitMask, dwABitMask));
  7476. end;
  7477. end;
  7478. end;
  7479. var
  7480. StreamPos: Int64;
  7481. x, y, LineSize, RowSize, Magic: Cardinal;
  7482. NewImage, TmpData, RowData, SrcData: System.PByte;
  7483. SourceMD, DestMD: Pointer;
  7484. Pixel: TglBitmapPixelData;
  7485. ddsFormat: TglBitmapFormat;
  7486. FormatDesc: TFormatDescriptor;
  7487. begin
  7488. result := false;
  7489. Converter := nil;
  7490. StreamPos := aStream.Position;
  7491. // Magic
  7492. aStream.Read(Magic{%H-}, sizeof(Magic));
  7493. if (Magic <> DDS_MAGIC) then begin
  7494. aStream.Position := StreamPos;
  7495. exit;
  7496. end;
  7497. //Header
  7498. aStream.Read(Header{%H-}, sizeof(Header));
  7499. if (Header.dwSize <> SizeOf(Header)) or
  7500. ((Header.dwFlags and (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) <>
  7501. (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) then
  7502. begin
  7503. aStream.Position := StreamPos;
  7504. exit;
  7505. end;
  7506. if ((Header.Caps.dwCaps1 and DDSCAPS2_CUBEMAP) > 0) then
  7507. raise EglBitmap.Create('LoadDDS - CubeMaps are not supported');
  7508. ddsFormat := GetDDSFormat;
  7509. try
  7510. if (ddsFormat = tfEmpty) then
  7511. raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
  7512. FormatDesc := TFormatDescriptor.Get(ddsFormat);
  7513. LineSize := Trunc(Header.dwWidth * FormatDesc.BytesPerPixel);
  7514. GetMem(NewImage, Header.dwHeight * LineSize);
  7515. try
  7516. TmpData := NewImage;
  7517. //Converter needed
  7518. if Assigned(Converter) then begin
  7519. RowSize := Round(Header.dwWidth * Header.PixelFormat.dwRGBBitCount / 8);
  7520. GetMem(RowData, RowSize);
  7521. SourceMD := Converter.CreateMappingData;
  7522. DestMD := FormatDesc.CreateMappingData;
  7523. try
  7524. for y := 0 to Header.dwHeight-1 do begin
  7525. TmpData := NewImage;
  7526. inc(TmpData, y * LineSize);
  7527. SrcData := RowData;
  7528. aStream.Read(SrcData^, RowSize);
  7529. for x := 0 to Header.dwWidth-1 do begin
  7530. Converter.Unmap(SrcData, Pixel, SourceMD);
  7531. glBitmapConvertPixel(Pixel, Converter, FormatDesc);
  7532. FormatDesc.Map(Pixel, TmpData, DestMD);
  7533. end;
  7534. end;
  7535. finally
  7536. Converter.FreeMappingData(SourceMD);
  7537. FormatDesc.FreeMappingData(DestMD);
  7538. FreeMem(RowData);
  7539. end;
  7540. end else
  7541. // Compressed
  7542. if ((Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0) then begin
  7543. RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
  7544. for Y := 0 to Header.dwHeight-1 do begin
  7545. aStream.Read(TmpData^, RowSize);
  7546. Inc(TmpData, LineSize);
  7547. end;
  7548. end else
  7549. // Uncompressed
  7550. if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0 then begin
  7551. RowSize := (Header.PixelFormat.dwRGBBitCount * Header.dwWidth) shr 3;
  7552. for Y := 0 to Header.dwHeight-1 do begin
  7553. aStream.Read(TmpData^, RowSize);
  7554. Inc(TmpData, LineSize);
  7555. end;
  7556. end else
  7557. raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
  7558. SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight); //be careful, Data could be freed by this method
  7559. result := true;
  7560. except
  7561. if Assigned(NewImage) then
  7562. FreeMem(NewImage);
  7563. raise;
  7564. end;
  7565. finally
  7566. FreeAndNil(Converter);
  7567. end;
  7568. end;
  7569. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7570. procedure TglBitmap.SaveDDS(const aStream: TStream);
  7571. var
  7572. Header: TDDSHeader;
  7573. FormatDesc: TFormatDescriptor;
  7574. begin
  7575. if not (ftDDS in FormatGetSupportedFiles(Format)) then
  7576. raise EglBitmapUnsupportedFormat.Create(Format);
  7577. FormatDesc := TFormatDescriptor.Get(Format);
  7578. // Generell
  7579. FillChar(Header{%H-}, SizeOf(Header), 0);
  7580. Header.dwSize := SizeOf(Header);
  7581. Header.dwFlags := DDSD_WIDTH or DDSD_HEIGHT or DDSD_CAPS or DDSD_PIXELFORMAT;
  7582. Header.dwWidth := Max(1, Width);
  7583. Header.dwHeight := Max(1, Height);
  7584. // Caps
  7585. Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
  7586. // Pixelformat
  7587. Header.PixelFormat.dwSize := sizeof(Header);
  7588. if (FormatDesc.IsCompressed) then begin
  7589. Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_FOURCC;
  7590. case Format of
  7591. tfS3tcDtx1RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT1;
  7592. tfS3tcDtx3RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT3;
  7593. tfS3tcDtx5RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT5;
  7594. end;
  7595. end else if not FormatDesc.HasColor and FormatDesc.HasAlpha then begin
  7596. Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHA;
  7597. Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
  7598. Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
  7599. end else if FormatDesc.IsGrayscale then begin
  7600. Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_LUMINANCE;
  7601. Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
  7602. Header.PixelFormat.dwRBitMask := FormatDesc.Mask.r;
  7603. Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
  7604. end else begin
  7605. Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_RGB;
  7606. Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
  7607. Header.PixelFormat.dwRBitMask := FormatDesc.Mask.r;
  7608. Header.PixelFormat.dwGBitMask := FormatDesc.Mask.g;
  7609. Header.PixelFormat.dwBBitMask := FormatDesc.Mask.b;
  7610. Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
  7611. end;
  7612. if (FormatDesc.HasAlpha) then
  7613. Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
  7614. aStream.Write(DDS_MAGIC, sizeof(DDS_MAGIC));
  7615. aStream.Write(Header, SizeOf(Header));
  7616. aStream.Write(Data^, FormatDesc.GetSize(Dimension));
  7617. end;
  7618. {$IFNDEF OPENGL_ES}
  7619. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7620. //TglBitmap1D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7621. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7622. procedure TglBitmap1D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
  7623. const aWidth: Integer; const aHeight: Integer);
  7624. var
  7625. pTemp: pByte;
  7626. Size: Integer;
  7627. begin
  7628. if (aHeight > 1) then begin
  7629. Size := TFormatDescriptor.Get(aFormat).GetSize(aWidth, 1);
  7630. GetMem(pTemp, Size);
  7631. try
  7632. Move(aData^, pTemp^, Size);
  7633. FreeMem(aData);
  7634. aData := nil;
  7635. except
  7636. FreeMem(pTemp);
  7637. raise;
  7638. end;
  7639. end else
  7640. pTemp := aData;
  7641. inherited SetDataPointer(pTemp, aFormat, aWidth);
  7642. end;
  7643. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7644. function TglBitmap1D.FlipHorz: Boolean;
  7645. var
  7646. Col: Integer;
  7647. pTempDest, pDest, pSource: PByte;
  7648. begin
  7649. result := inherited FlipHorz;
  7650. if Assigned(Data) and not TFormatDescriptor.Get(Format).IsCompressed then begin
  7651. pSource := Data;
  7652. GetMem(pDest, fRowSize);
  7653. try
  7654. pTempDest := pDest;
  7655. Inc(pTempDest, fRowSize);
  7656. for Col := 0 to Width-1 do begin
  7657. dec(pTempDest, fPixelSize); //dec before, because ptr is behind last byte of data
  7658. Move(pSource^, pTempDest^, fPixelSize);
  7659. Inc(pSource, fPixelSize);
  7660. end;
  7661. SetDataPointer(pDest, Format, Width); //be careful, Data could be freed by this method
  7662. result := true;
  7663. except
  7664. if Assigned(pDest) then
  7665. FreeMem(pDest);
  7666. raise;
  7667. end;
  7668. end;
  7669. end;
  7670. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7671. procedure TglBitmap1D.UploadData(const aBuildWithGlu: Boolean);
  7672. var
  7673. FormatDesc: TFormatDescriptor;
  7674. begin
  7675. // Upload data
  7676. FormatDesc := TFormatDescriptor.Get(Format);
  7677. if (FormatDesc.glInternalFormat = 0) or (FormatDesc.glDataFormat = 0) then
  7678. raise EglBitmap.Create('format is not supported by video adapter, please convert before uploading data');
  7679. if FormatDesc.IsCompressed then begin
  7680. if not Assigned(glCompressedTexImage1D) then
  7681. raise EglBitmap.Create('compressed formats not supported by video adapter');
  7682. glCompressedTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.GetSize(Width, 1), Data)
  7683. end else if aBuildWithGlu then
  7684. gluBuild1DMipmaps(Target, FormatDesc.glInternalFormat, Width, FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
  7685. else
  7686. glTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
  7687. // Free Data
  7688. if (FreeDataAfterGenTexture) then
  7689. FreeData;
  7690. end;
  7691. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7692. procedure TglBitmap1D.GenTexture(const aTestTextureSize: Boolean);
  7693. var
  7694. BuildWithGlu, TexRec: Boolean;
  7695. TexSize: Integer;
  7696. begin
  7697. if Assigned(Data) then begin
  7698. // Check Texture Size
  7699. if (aTestTextureSize) then begin
  7700. glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
  7701. if (Width > TexSize) then
  7702. raise EglBitmapSizeToLarge.Create('TglBitmap1D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
  7703. TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
  7704. (Target = GL_TEXTURE_RECTANGLE);
  7705. if not (IsPowerOfTwo(Width) or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
  7706. raise EglBitmapNonPowerOfTwo.Create('TglBitmap1D.GenTexture - Rendercontex dosn''t support non power of two texture.');
  7707. end;
  7708. CreateId;
  7709. SetupParameters(BuildWithGlu);
  7710. UploadData(BuildWithGlu);
  7711. glAreTexturesResident(1, @fID, @fIsResident);
  7712. end;
  7713. end;
  7714. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7715. procedure TglBitmap1D.AfterConstruction;
  7716. begin
  7717. inherited;
  7718. Target := GL_TEXTURE_1D;
  7719. end;
  7720. {$ENDIF}
  7721. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7722. //TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7723. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7724. function TglBitmap2D.GetScanline(const aIndex: Integer): Pointer;
  7725. begin
  7726. if (aIndex >= Low(fLines)) and (aIndex <= High(fLines)) then
  7727. result := fLines[aIndex]
  7728. else
  7729. result := nil;
  7730. end;
  7731. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7732. procedure TglBitmap2D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
  7733. const aWidth: Integer; const aHeight: Integer);
  7734. var
  7735. Idx, LineWidth: Integer;
  7736. begin
  7737. inherited SetDataPointer(aData, aFormat, aWidth, aHeight);
  7738. if not TFormatDescriptor.Get(aFormat).IsCompressed then begin
  7739. // Assigning Data
  7740. if Assigned(Data) then begin
  7741. SetLength(fLines, GetHeight);
  7742. LineWidth := Trunc(GetWidth * TFormatDescriptor.Get(Format).BytesPerPixel);
  7743. for Idx := 0 to GetHeight-1 do begin
  7744. fLines[Idx] := Data;
  7745. Inc(fLines[Idx], Idx * LineWidth);
  7746. end;
  7747. end
  7748. else SetLength(fLines, 0);
  7749. end else begin
  7750. SetLength(fLines, 0);
  7751. end;
  7752. end;
  7753. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7754. procedure TglBitmap2D.UploadData(const aTarget: GLenum{$IFNDEF OPENGL_ES}; const aBuildWithGlu: Boolean{$ENDIF});
  7755. var
  7756. FormatDesc: TFormatDescriptor;
  7757. begin
  7758. FormatDesc := TFormatDescriptor.Get(Format);
  7759. if (FormatDesc.glInternalFormat = 0) or (FormatDesc.glDataFormat = 0) then
  7760. raise EglBitmap.Create('format is not supported by video adapter, please convert before uploading data');
  7761. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  7762. if FormatDesc.IsCompressed then begin
  7763. if not Assigned(glCompressedTexImage2D) then
  7764. raise EglBitmap.Create('compressed formats not supported by video adapter');
  7765. glCompressedTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0, FormatDesc.GetSize(fDimension), Data)
  7766. {$IFNDEF OPENGL_ES}
  7767. end else if aBuildWithGlu then begin
  7768. gluBuild2DMipmaps(aTarget, FormatDesc.ChannelCount, Width, Height,
  7769. FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
  7770. {$ENDIF}
  7771. end else begin
  7772. glTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0,
  7773. FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
  7774. end;
  7775. // Freigeben
  7776. if (FreeDataAfterGenTexture) then
  7777. FreeData;
  7778. end;
  7779. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7780. procedure TglBitmap2D.AfterConstruction;
  7781. begin
  7782. inherited;
  7783. Target := GL_TEXTURE_2D;
  7784. end;
  7785. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7786. procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
  7787. var
  7788. Temp: pByte;
  7789. Size, w, h: Integer;
  7790. FormatDesc: TFormatDescriptor;
  7791. begin
  7792. FormatDesc := TFormatDescriptor.Get(aFormat);
  7793. if FormatDesc.IsCompressed then
  7794. raise EglBitmapUnsupportedFormat.Create(aFormat);
  7795. w := aRight - aLeft;
  7796. h := aBottom - aTop;
  7797. Size := FormatDesc.GetSize(w, h);
  7798. GetMem(Temp, Size);
  7799. try
  7800. glPixelStorei(GL_PACK_ALIGNMENT, 1);
  7801. glReadPixels(aLeft, aTop, w, h, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
  7802. SetDataPointer(Temp, aFormat, w, h); //be careful, Data could be freed by this method
  7803. FlipVert;
  7804. except
  7805. if Assigned(Temp) then
  7806. FreeMem(Temp);
  7807. raise;
  7808. end;
  7809. end;
  7810. {$IFNDEF OPENGL_ES}
  7811. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7812. procedure TglBitmap2D.GetDataFromTexture;
  7813. var
  7814. Temp: PByte;
  7815. TempWidth, TempHeight: Integer;
  7816. TempIntFormat: GLint;
  7817. IntFormat: TglBitmapFormat;
  7818. FormatDesc: TFormatDescriptor;
  7819. begin
  7820. Bind;
  7821. // Request Data
  7822. glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
  7823. glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
  7824. glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
  7825. FormatDesc := (TglBitmapFormatDescriptor.GetByFormat(TempIntFormat) as TFormatDescriptor);
  7826. IntFormat := FormatDesc.Format;
  7827. // Getting data from OpenGL
  7828. FormatDesc := TFormatDescriptor.Get(IntFormat);
  7829. GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
  7830. try
  7831. if FormatDesc.IsCompressed then begin
  7832. if not Assigned(glGetCompressedTexImage) then
  7833. raise EglBitmap.Create('compressed formats not supported by video adapter');
  7834. glGetCompressedTexImage(Target, 0, Temp)
  7835. end else
  7836. glGetTexImage(Target, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
  7837. SetDataPointer(Temp, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
  7838. except
  7839. if Assigned(Temp) then
  7840. FreeMem(Temp);
  7841. raise;
  7842. end;
  7843. end;
  7844. {$ENDIF}
  7845. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7846. procedure TglBitmap2D.GenTexture(const aTestTextureSize: Boolean);
  7847. var
  7848. {$IFNDEF OPENGL_ES}
  7849. BuildWithGlu, TexRec: Boolean;
  7850. {$ENDIF}
  7851. PotTex: Boolean;
  7852. TexSize: Integer;
  7853. begin
  7854. if Assigned(Data) then begin
  7855. // Check Texture Size
  7856. if (aTestTextureSize) then begin
  7857. glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
  7858. if ((Height > TexSize) or (Width > TexSize)) then
  7859. raise EglBitmapSizeToLarge.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
  7860. PotTex := IsPowerOfTwo(Height) and IsPowerOfTwo(Width);
  7861. {$IF NOT DEFINED(OPENGL_ES)}
  7862. TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE);
  7863. if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
  7864. raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
  7865. {$ELSEIF DEFINED(OPENGL_ES_EXT)}
  7866. if not PotTex and not GL_OES_texture_npot then
  7867. raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
  7868. {$ELSE}
  7869. if not PotTex then
  7870. raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
  7871. {$IFEND}
  7872. end;
  7873. CreateId;
  7874. SetupParameters({$IFNDEF OPENGL_ES}BuildWithGlu{$ENDIF});
  7875. UploadData(Target{$IFNDEF OPENGL_ES}, BuildWithGlu{$ENDIF});
  7876. {$IFNDEF OPENGL_ES}
  7877. glAreTexturesResident(1, @fID, @fIsResident);
  7878. {$ENDIF}
  7879. end;
  7880. end;
  7881. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7882. function TglBitmap2D.FlipHorz: Boolean;
  7883. var
  7884. Col, Row: Integer;
  7885. TempDestData, DestData, SourceData: PByte;
  7886. ImgSize: Integer;
  7887. begin
  7888. result := inherited FlipHorz;
  7889. if Assigned(Data) then begin
  7890. SourceData := Data;
  7891. ImgSize := Height * fRowSize;
  7892. GetMem(DestData, ImgSize);
  7893. try
  7894. TempDestData := DestData;
  7895. Dec(TempDestData, fRowSize + fPixelSize);
  7896. for Row := 0 to Height -1 do begin
  7897. Inc(TempDestData, fRowSize * 2);
  7898. for Col := 0 to Width -1 do begin
  7899. Move(SourceData^, TempDestData^, fPixelSize);
  7900. Inc(SourceData, fPixelSize);
  7901. Dec(TempDestData, fPixelSize);
  7902. end;
  7903. end;
  7904. SetDataPointer(DestData, Format, Width, Height); //be careful, Data could be freed by this method
  7905. result := true;
  7906. except
  7907. if Assigned(DestData) then
  7908. FreeMem(DestData);
  7909. raise;
  7910. end;
  7911. end;
  7912. end;
  7913. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7914. function TglBitmap2D.FlipVert: Boolean;
  7915. var
  7916. Row: Integer;
  7917. TempDestData, DestData, SourceData: PByte;
  7918. begin
  7919. result := inherited FlipVert;
  7920. if Assigned(Data) then begin
  7921. SourceData := Data;
  7922. GetMem(DestData, Height * fRowSize);
  7923. try
  7924. TempDestData := DestData;
  7925. Inc(TempDestData, Width * (Height -1) * fPixelSize);
  7926. for Row := 0 to Height -1 do begin
  7927. Move(SourceData^, TempDestData^, fRowSize);
  7928. Dec(TempDestData, fRowSize);
  7929. Inc(SourceData, fRowSize);
  7930. end;
  7931. SetDataPointer(DestData, Format, Width, Height); //be careful, Data could be freed by this method
  7932. result := true;
  7933. except
  7934. if Assigned(DestData) then
  7935. FreeMem(DestData);
  7936. raise;
  7937. end;
  7938. end;
  7939. end;
  7940. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7941. //TglBitmap2D - ToNormalMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7942. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7943. type
  7944. TMatrixItem = record
  7945. X, Y: Integer;
  7946. W: Single;
  7947. end;
  7948. PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
  7949. TglBitmapToNormalMapRec = Record
  7950. Scale: Single;
  7951. Heights: array of Single;
  7952. MatrixU : array of TMatrixItem;
  7953. MatrixV : array of TMatrixItem;
  7954. end;
  7955. const
  7956. ONE_OVER_255 = 1 / 255;
  7957. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7958. procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
  7959. var
  7960. Val: Single;
  7961. begin
  7962. with FuncRec do begin
  7963. Val :=
  7964. Source.Data.r * LUMINANCE_WEIGHT_R +
  7965. Source.Data.g * LUMINANCE_WEIGHT_G +
  7966. Source.Data.b * LUMINANCE_WEIGHT_B;
  7967. PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255;
  7968. end;
  7969. end;
  7970. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7971. procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
  7972. begin
  7973. with FuncRec do
  7974. PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
  7975. end;
  7976. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7977. procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
  7978. type
  7979. TVec = Array[0..2] of Single;
  7980. var
  7981. Idx: Integer;
  7982. du, dv: Double;
  7983. Len: Single;
  7984. Vec: TVec;
  7985. function GetHeight(X, Y: Integer): Single;
  7986. begin
  7987. with FuncRec do begin
  7988. X := Max(0, Min(Size.X -1, X));
  7989. Y := Max(0, Min(Size.Y -1, Y));
  7990. result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
  7991. end;
  7992. end;
  7993. begin
  7994. with FuncRec do begin
  7995. with PglBitmapToNormalMapRec(Args)^ do begin
  7996. du := 0;
  7997. for Idx := Low(MatrixU) to High(MatrixU) do
  7998. du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
  7999. dv := 0;
  8000. for Idx := Low(MatrixU) to High(MatrixU) do
  8001. dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
  8002. Vec[0] := -du * Scale;
  8003. Vec[1] := -dv * Scale;
  8004. Vec[2] := 1;
  8005. end;
  8006. // Normalize
  8007. Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
  8008. if Len <> 0 then begin
  8009. Vec[0] := Vec[0] * Len;
  8010. Vec[1] := Vec[1] * Len;
  8011. Vec[2] := Vec[2] * Len;
  8012. end;
  8013. // Farbe zuweisem
  8014. Dest.Data.r := Trunc((Vec[0] + 1) * 127.5);
  8015. Dest.Data.g := Trunc((Vec[1] + 1) * 127.5);
  8016. Dest.Data.b := Trunc((Vec[2] + 1) * 127.5);
  8017. end;
  8018. end;
  8019. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8020. procedure TglBitmap2D.GenerateNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
  8021. var
  8022. Rec: TglBitmapToNormalMapRec;
  8023. procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
  8024. begin
  8025. if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
  8026. Matrix[Index].X := X;
  8027. Matrix[Index].Y := Y;
  8028. Matrix[Index].W := W;
  8029. end;
  8030. end;
  8031. begin
  8032. if TFormatDescriptor.Get(Format).IsCompressed then
  8033. raise EglBitmapUnsupportedFormat.Create(Format);
  8034. if aScale > 100 then
  8035. Rec.Scale := 100
  8036. else if aScale < -100 then
  8037. Rec.Scale := -100
  8038. else
  8039. Rec.Scale := aScale;
  8040. SetLength(Rec.Heights, Width * Height);
  8041. try
  8042. case aFunc of
  8043. nm4Samples: begin
  8044. SetLength(Rec.MatrixU, 2);
  8045. SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
  8046. SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
  8047. SetLength(Rec.MatrixV, 2);
  8048. SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
  8049. SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
  8050. end;
  8051. nmSobel: begin
  8052. SetLength(Rec.MatrixU, 6);
  8053. SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
  8054. SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
  8055. SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
  8056. SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
  8057. SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
  8058. SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
  8059. SetLength(Rec.MatrixV, 6);
  8060. SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
  8061. SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
  8062. SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
  8063. SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
  8064. SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
  8065. SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
  8066. end;
  8067. nm3x3: begin
  8068. SetLength(Rec.MatrixU, 6);
  8069. SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
  8070. SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
  8071. SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
  8072. SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
  8073. SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
  8074. SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
  8075. SetLength(Rec.MatrixV, 6);
  8076. SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
  8077. SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
  8078. SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
  8079. SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
  8080. SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
  8081. SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
  8082. end;
  8083. nm5x5: begin
  8084. SetLength(Rec.MatrixU, 20);
  8085. SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
  8086. SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
  8087. SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
  8088. SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
  8089. SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
  8090. SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
  8091. SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
  8092. SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
  8093. SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
  8094. SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
  8095. SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
  8096. SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
  8097. SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
  8098. SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
  8099. SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
  8100. SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
  8101. SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
  8102. SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
  8103. SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
  8104. SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
  8105. SetLength(Rec.MatrixV, 20);
  8106. SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
  8107. SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
  8108. SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
  8109. SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
  8110. SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
  8111. SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
  8112. SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
  8113. SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
  8114. SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
  8115. SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
  8116. SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
  8117. SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
  8118. SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
  8119. SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
  8120. SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
  8121. SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
  8122. SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
  8123. SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
  8124. SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
  8125. SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
  8126. end;
  8127. end;
  8128. // Daten Sammeln
  8129. if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
  8130. Convert(glBitmapToNormalMapPrepareAlphaFunc, false, @Rec)
  8131. else
  8132. Convert(glBitmapToNormalMapPrepareFunc, false, @Rec);
  8133. Convert(glBitmapToNormalMapFunc, false, @Rec);
  8134. finally
  8135. SetLength(Rec.Heights, 0);
  8136. end;
  8137. end;
  8138. {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
  8139. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8140. //TglBitmapCubeMap////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8141. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8142. procedure TglBitmapCubeMap.GenTexture(const aTestTextureSize: Boolean);
  8143. begin
  8144. Assert(false, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
  8145. end;
  8146. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8147. procedure TglBitmapCubeMap.AfterConstruction;
  8148. begin
  8149. inherited;
  8150. {$IFNDEF OPENGL_ES}
  8151. if not (GL_VERSION_1_3 or GL_ARB_texture_cube_map or GL_EXT_texture_cube_map) then
  8152. raise EglBitmap.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
  8153. {$ELSE}
  8154. if not (GL_VERSION_2_0) then
  8155. raise EglBitmap.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
  8156. {$ENDIF}
  8157. SetWrap;
  8158. Target := GL_TEXTURE_CUBE_MAP;
  8159. {$IFNDEF OPENGL_ES}
  8160. fGenMode := GL_REFLECTION_MAP;
  8161. {$ENDIF}
  8162. end;
  8163. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8164. procedure TglBitmapCubeMap.GenerateCubeMap(const aCubeTarget: Cardinal; const aTestTextureSize: Boolean);
  8165. var
  8166. {$IFNDEF OPENGL_ES}
  8167. BuildWithGlu: Boolean;
  8168. {$ENDIF}
  8169. TexSize: Integer;
  8170. begin
  8171. if (aTestTextureSize) then begin
  8172. glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @TexSize);
  8173. if (Height > TexSize) or (Width > TexSize) then
  8174. raise EglBitmapSizeToLarge.Create('TglBitmapCubeMap.GenerateCubeMap - The size for the Cubemap is to large. It''s may be not conform with the Hardware.');
  8175. {$IF NOT DEFINED(OPENGL_ES)}
  8176. if not ((IsPowerOfTwo(Height) and IsPowerOfTwo(Width)) or GL_VERSION_2_0 or GL_ARB_texture_non_power_of_two) then
  8177. raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenerateCubeMap - Cubemaps dosn''t support non power of two texture.');
  8178. {$ELSEIF DEFINED(OPENGL_ES_EXT)}
  8179. if not (IsPowerOfTwo(Height) and IsPowerOfTwo(Width)) and not GL_OES_texture_npot then
  8180. raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenerateCubeMap - Cubemaps dosn''t support non power of two texture.');
  8181. {$ELSE}
  8182. if not (IsPowerOfTwo(Height) and IsPowerOfTwo(Width)) then
  8183. raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenerateCubeMap - Cubemaps dosn''t support non power of two texture.');
  8184. {$IFEND}
  8185. end;
  8186. if (ID = 0) then
  8187. CreateID;
  8188. SetupParameters({$IFNDEF OPENGL_ES}BuildWithGlu{$ENDIF});
  8189. UploadData(aCubeTarget{$IFNDEF OPENGL_ES}, BuildWithGlu{$ENDIF});
  8190. end;
  8191. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8192. procedure TglBitmapCubeMap.Bind({$IFNDEF OPENGL_ES}const aEnableTexCoordsGen: Boolean;{$ENDIF} const aEnableTextureUnit: Boolean);
  8193. begin
  8194. inherited Bind (aEnableTextureUnit);
  8195. {$IFNDEF OPENGL_ES}
  8196. if aEnableTexCoordsGen then begin
  8197. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, fGenMode);
  8198. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, fGenMode);
  8199. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, fGenMode);
  8200. glEnable(GL_TEXTURE_GEN_S);
  8201. glEnable(GL_TEXTURE_GEN_T);
  8202. glEnable(GL_TEXTURE_GEN_R);
  8203. end;
  8204. {$ENDIF}
  8205. end;
  8206. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8207. procedure TglBitmapCubeMap.Unbind({$IFNDEF OPENGL_ES}const aDisableTexCoordsGen: Boolean;{$ENDIF} const aDisableTextureUnit: Boolean);
  8208. begin
  8209. inherited Unbind(aDisableTextureUnit);
  8210. {$IFNDEF OPENGL_ES}
  8211. if aDisableTexCoordsGen then begin
  8212. glDisable(GL_TEXTURE_GEN_S);
  8213. glDisable(GL_TEXTURE_GEN_T);
  8214. glDisable(GL_TEXTURE_GEN_R);
  8215. end;
  8216. {$ENDIF}
  8217. end;
  8218. {$IFEND}
  8219. {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
  8220. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8221. //TglBitmapNormalMap//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8222. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8223. type
  8224. TVec = Array[0..2] of Single;
  8225. TglBitmapNormalMapGetVectorFunc = procedure (out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
  8226. PglBitmapNormalMapRec = ^TglBitmapNormalMapRec;
  8227. TglBitmapNormalMapRec = record
  8228. HalfSize : Integer;
  8229. Func: TglBitmapNormalMapGetVectorFunc;
  8230. end;
  8231. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8232. procedure glBitmapNormalMapPosX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
  8233. begin
  8234. aVec[0] := aHalfSize;
  8235. aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
  8236. aVec[2] := - (aPosition.X + 0.5 - aHalfSize);
  8237. end;
  8238. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8239. procedure glBitmapNormalMapNegX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
  8240. begin
  8241. aVec[0] := - aHalfSize;
  8242. aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
  8243. aVec[2] := aPosition.X + 0.5 - aHalfSize;
  8244. end;
  8245. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8246. procedure glBitmapNormalMapPosY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
  8247. begin
  8248. aVec[0] := aPosition.X + 0.5 - aHalfSize;
  8249. aVec[1] := aHalfSize;
  8250. aVec[2] := aPosition.Y + 0.5 - aHalfSize;
  8251. end;
  8252. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8253. procedure glBitmapNormalMapNegY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
  8254. begin
  8255. aVec[0] := aPosition.X + 0.5 - aHalfSize;
  8256. aVec[1] := - aHalfSize;
  8257. aVec[2] := - (aPosition.Y + 0.5 - aHalfSize);
  8258. end;
  8259. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8260. procedure glBitmapNormalMapPosZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
  8261. begin
  8262. aVec[0] := aPosition.X + 0.5 - aHalfSize;
  8263. aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
  8264. aVec[2] := aHalfSize;
  8265. end;
  8266. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8267. procedure glBitmapNormalMapNegZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
  8268. begin
  8269. aVec[0] := - (aPosition.X + 0.5 - aHalfSize);
  8270. aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
  8271. aVec[2] := - aHalfSize;
  8272. end;
  8273. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8274. procedure glBitmapNormalMapFunc(var FuncRec: TglBitmapFunctionRec);
  8275. var
  8276. i: Integer;
  8277. Vec: TVec;
  8278. Len: Single;
  8279. begin
  8280. with FuncRec do begin
  8281. with PglBitmapNormalMapRec(Args)^ do begin
  8282. Func(Vec, Position, HalfSize);
  8283. // Normalize
  8284. Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
  8285. if Len <> 0 then begin
  8286. Vec[0] := Vec[0] * Len;
  8287. Vec[1] := Vec[1] * Len;
  8288. Vec[2] := Vec[2] * Len;
  8289. end;
  8290. // Scale Vector and AddVectro
  8291. Vec[0] := Vec[0] * 0.5 + 0.5;
  8292. Vec[1] := Vec[1] * 0.5 + 0.5;
  8293. Vec[2] := Vec[2] * 0.5 + 0.5;
  8294. end;
  8295. // Set Color
  8296. for i := 0 to 2 do
  8297. Dest.Data.arr[i] := Round(Vec[i] * 255);
  8298. end;
  8299. end;
  8300. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8301. procedure TglBitmapNormalMap.AfterConstruction;
  8302. begin
  8303. inherited;
  8304. {$IFNDEF OPENGL_ES}
  8305. fGenMode := GL_NORMAL_MAP;
  8306. {$ENDIF}
  8307. end;
  8308. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8309. procedure TglBitmapNormalMap.GenerateNormalMap(const aSize: Integer; const aTestTextureSize: Boolean);
  8310. var
  8311. Rec: TglBitmapNormalMapRec;
  8312. SizeRec: TglBitmapSize;
  8313. begin
  8314. Rec.HalfSize := aSize div 2;
  8315. FreeDataAfterGenTexture := false;
  8316. SizeRec.Fields := [ffX, ffY];
  8317. SizeRec.X := aSize;
  8318. SizeRec.Y := aSize;
  8319. // Positive X
  8320. Rec.Func := glBitmapNormalMapPosX;
  8321. LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
  8322. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X, aTestTextureSize);
  8323. // Negative X
  8324. Rec.Func := glBitmapNormalMapNegX;
  8325. LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
  8326. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, aTestTextureSize);
  8327. // Positive Y
  8328. Rec.Func := glBitmapNormalMapPosY;
  8329. LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
  8330. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, aTestTextureSize);
  8331. // Negative Y
  8332. Rec.Func := glBitmapNormalMapNegY;
  8333. LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
  8334. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, aTestTextureSize);
  8335. // Positive Z
  8336. Rec.Func := glBitmapNormalMapPosZ;
  8337. LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
  8338. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, aTestTextureSize);
  8339. // Negative Z
  8340. Rec.Func := glBitmapNormalMapNegZ;
  8341. LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
  8342. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, aTestTextureSize);
  8343. end;
  8344. {$IFEND}
  8345. initialization
  8346. glBitmapSetDefaultFormat (tfEmpty);
  8347. glBitmapSetDefaultMipmap (mmMipmap);
  8348. glBitmapSetDefaultFilter (GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
  8349. glBitmapSetDefaultWrap (GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
  8350. {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
  8351. glBitmapSetDefaultSwizzle(GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA);
  8352. {$IFEND}
  8353. glBitmapSetDefaultFreeDataAfterGenTexture(true);
  8354. glBitmapSetDefaultDeleteTextureOnFree (true);
  8355. TFormatDescriptor.Init;
  8356. {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
  8357. OpenGLInitialized := false;
  8358. InitOpenGLCS := TCriticalSection.Create;
  8359. {$ENDIF}
  8360. finalization
  8361. TFormatDescriptor.Finalize;
  8362. {$IFDEF GLB_NATIVE_OGL}
  8363. if Assigned(GL_LibHandle) then
  8364. glbFreeLibrary(GL_LibHandle);
  8365. {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
  8366. if Assigned(GLU_LibHandle) then
  8367. glbFreeLibrary(GLU_LibHandle);
  8368. FreeAndNil(InitOpenGLCS);
  8369. {$ENDIF}
  8370. {$ENDIF}
  8371. end.