No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

8358 líneas
289 KiB

  1. {***********************************************************
  2. glBitmap by Steffen Xonna aka Lossy eX (2003-2008)
  3. http://www.opengl24.de/index.php?cat=header&file=glbitmap
  4. modified by Delphi OpenGL Community (http://delphigl.com/) (2013)
  5. ------------------------------------------------------------
  6. The contents of this file are used with permission, subject to
  7. the Mozilla Public License Version 1.1 (the "License"); you may
  8. not use this file except in compliance with the License. You may
  9. obtain a copy of the License at
  10. http://www.mozilla.org/MPL/MPL-1.1.html
  11. ------------------------------------------------------------
  12. Version 3.0.0 unstable
  13. ------------------------------------------------------------
  14. History
  15. 20-11-2013
  16. - refactoring of the complete library
  17. 21-03-2010
  18. - The define GLB_DELPHI dosn't check versions anymore. If you say you are using delphi
  19. then it's your problem if that isn't true. This prevents the unit for incompatibility
  20. with newer versions of Delphi.
  21. - Problems with D2009+ resolved (Thanks noeska and all i forgot)
  22. - GetPixel isn't set if you are loading textures inside the constructor (Thanks Wilson)
  23. 10-08-2008
  24. - AddAlphaFromglBitmap used the custom pointer instead the imagedatapointer (Thanks Wilson)
  25. - Additional Datapointer for functioninterface now has the name CustomData
  26. 24-07-2008
  27. - AssigneAlphaToBitmap overwrites his own palette (Thanks Wilson)
  28. - If you load an texture from an file the property Filename will be set to the name of the file
  29. - Three new properties to attach custom data to the Texture objects
  30. - CustomName (free for use string)
  31. - CustomNameW (free for use widestring)
  32. - CustomDataPointer (free for use pointer to attach other objects or complex structures)
  33. 27-05-2008
  34. - RLE TGAs loaded much faster
  35. 26-05-2008
  36. - fixed some problem with reading RLE TGAs.
  37. 21-05-2008
  38. - function clone now only copys data if it's assigned and now it also copies the ID
  39. - it seems that lazarus dont like comments in comments.
  40. 01-05-2008
  41. - It's possible to set the id of the texture
  42. - define GLB_NO_NATIVE_GL deactivated by default
  43. 27-04-2008
  44. - Now supports the following libraries
  45. - SDL and SDL_image
  46. - libPNG
  47. - libJPEG
  48. - Linux compatibillity via free pascal compatibility (delphi sources optional)
  49. - BMPs now loaded manuel
  50. - Large restructuring
  51. - Property DataPtr now has the name Data
  52. - Functions are more flexible between RGB(A) and BGR(A). RGB can be saved as Bitmap and will be saved as BGR
  53. - Unused Depth removed
  54. - Function FreeData to freeing image data added
  55. 24-10-2007
  56. - ImageID flag of TGAs was ignored. (Thanks Zwoetzen)
  57. 15-11-2006
  58. - Function SetBorderColor implemented (only used by opengl if wrap is set to GL_CLAMP_TO_BORDER)
  59. - Function AddAlphaFromValue implemented to use an fixed Value as Alphachannel
  60. - Function ReadOpenGLExtension is now only intern
  61. 29-06-2006
  62. - pngimage now disabled by default like all other versions.
  63. 26-06-2006
  64. - Setting up an anisotropic filter of 0 isnt allowed by nvidia (Thanks Ogridi)
  65. 22-06-2006
  66. - Fixed some Problem with Delphi 5
  67. - Now uses the newest version of pngimage. Makes saving pngs much easier.
  68. 22-03-2006
  69. - Property IsCompressed and Size removed. Not really supported by Spec (Thanks Ogridi)
  70. 09-03-2006
  71. - Internal Format ifDepth8 added
  72. - function GrabScreen now supports all uncompressed formats
  73. 31-01-2006
  74. - AddAlphaFromglBitmap implemented
  75. 29-12-2005
  76. - LoadFromResource and LoadFromResourceId now needs an Instance and an ResourceType (for ID)
  77. 28-12-2005
  78. - Width, Height and Depth internal changed to TglBitmapPixelPosition.
  79. property Width, Height, Depth are still existing and new property Dimension are avail
  80. 11-12-2005
  81. - Added native OpenGL Support. Breaking the dglOpenGL "barrier".
  82. 19-10-2005
  83. - Added function GrabScreen to class TglBitmap2D
  84. 18-10-2005
  85. - Added support to Save images
  86. - Added function Clone to Clone Instance
  87. 11-10-2005
  88. - Functions now works with Cardinals for each channel. Up to 32 Bits per channel.
  89. Usefull for Future
  90. - Several speed optimizations
  91. 09-10-2005
  92. - Internal structure change. Loading of TGA, PNG and DDS improved.
  93. Data, format and size will now set directly with SetDataPtr.
  94. - AddFunc now works with all Types of Images and Formats
  95. - Some Funtions moved to Baseclass TglBitmap
  96. 06-10-2005
  97. - Added Support to decompress DXT3 and DXT5 compressed Images.
  98. - Added Mapping to convert data from one format into an other.
  99. 05-10-2005
  100. - Added method ConvertTo in Class TglBitmap2D. Method allows to convert every
  101. supported Input format (supported by GetPixel) into any uncompresed Format
  102. - Added Support to decompress DXT1 compressed Images.
  103. - SwapColors replaced by ConvertTo
  104. 04-10-2005
  105. - Added Support for compressed DDSs
  106. - Added new internal formats (DXT1, DXT3, DXT5)
  107. 29-09-2005
  108. - Parameter Components renamed to InternalFormat
  109. 23-09-2005
  110. - Some AllocMem replaced with GetMem (little speed change)
  111. - better exception handling. Better protection from memory leaks.
  112. 22-09-2005
  113. - Added support for Direct Draw Surfaces (.DDS) (uncompressed images only)
  114. - Added new internal formats (RGB8, RGBA8, RGBA4, RGB5A1, RGB10A2, R5G6B5)
  115. 07-09-2005
  116. - Added support for Grayscale textures
  117. - Added internal formats (Alpha, Luminance, LuminanceAlpha, BGR8, BGRA8)
  118. 10-07-2005
  119. - Added support for GL_VERSION_2_0
  120. - Added support for GL_EXT_texture_filter_anisotropic
  121. 04-07-2005
  122. - Function FillWithColor fills the Image with one Color
  123. - Function LoadNormalMap added
  124. 30-06-2005
  125. - ToNormalMap allows to Create an NormalMap from the Alphachannel
  126. - ToNormalMap now supports Sobel (nmSobel) function.
  127. 29-06-2005
  128. - support for RLE Compressed RGB TGAs added
  129. 28-06-2005
  130. - Class TglBitmapNormalMap added to support Normalmap generation
  131. - Added function ToNormalMap in class TglBitmap2D to genereate normal maps from textures.
  132. 3 Filters are supported. (4 Samples, 3x3 and 5x5)
  133. 16-06-2005
  134. - Method LoadCubeMapClass removed
  135. - LoadCubeMap returnvalue is now the Texture paramter. Such as LoadTextures
  136. - virtual abstract method GenTexture in class TglBitmap now is protected
  137. 12-06-2005
  138. - now support DescriptionFlag in LoadTga. Allows vertical flipped images to be loaded as normal
  139. 10-06-2005
  140. - little enhancement for IsPowerOfTwo
  141. - TglBitmap1D.GenTexture now tests NPOT Textures
  142. 06-06-2005
  143. - some little name changes. All properties or function with Texture in name are
  144. now without texture in name. We have allways texture so we dosn't name it.
  145. 03-06-2005
  146. - GenTexture now tests if texture is NPOT and NPOT-Texture are supported or
  147. TextureTarget is GL_TEXTURE_RECTANGLE. Else it raised an exception.
  148. 02-06-2005
  149. - added support for GL_ARB_texture_rectangle, GL_EXT_texture_rectangle and GL_NV_texture_rectangle
  150. 25-04-2005
  151. - Function Unbind added
  152. - call of SetFilter or SetTextureWrap if TextureID exists results in setting properties to opengl texture.
  153. 21-04-2005
  154. - class TglBitmapCubeMap added (allows to Create Cubemaps)
  155. 29-03-2005
  156. - Added Support for PNG Images. (http://pngdelphi.sourceforge.net/)
  157. To Enable png's use the define pngimage
  158. 22-03-2005
  159. - New Functioninterface added
  160. - Function GetPixel added
  161. 27-11-2004
  162. - Property BuildMipMaps renamed to MipMap
  163. 21-11-2004
  164. - property Name removed.
  165. - BuildMipMaps is now a set of 3 values. None, GluBuildMipmaps and SGIS_generate_mipmap
  166. 22-05-2004
  167. - property name added. Only used in glForms!
  168. 26-11-2003
  169. - property FreeDataAfterGenTexture is now available as default (default = true)
  170. - BuildMipmaps now implemented in TglBitmap1D (i've forgotten it)
  171. - function MoveMemory replaced with function Move (little speed change)
  172. - several calculations stored in variables (little speed change)
  173. 29-09-2003
  174. - property BuildMipsMaps added (default = true)
  175. if BuildMipMaps isn't set GenTextures uses glTexImage[12]D else it use gluBuild[12]dMipmaps
  176. - property FreeDataAfterGenTexture added (default = true)
  177. if FreeDataAfterGenTexture is set the texturedata were deleted after the texture was generated.
  178. - parameter DisableOtherTextureUnits of Bind removed
  179. - parameter FreeDataAfterGeneration of GenTextures removed
  180. 12-09-2003
  181. - TglBitmap dosn't delete data if class was destroyed (fixed)
  182. 09-09-2003
  183. - Bind now enables TextureUnits (by params)
  184. - GenTextures can leave data (by param)
  185. - LoadTextures now optimal
  186. 03-09-2003
  187. - Performance optimization in AddFunc
  188. - procedure Bind moved to subclasses
  189. - Added new Class TglBitmap1D to support real OpenGL 1D Textures
  190. 19-08-2003
  191. - Texturefilter and texturewrap now also as defaults
  192. Minfilter = GL_LINEAR_MIPMAP_LINEAR
  193. Magfilter = GL_LINEAR
  194. Wrap(str) = GL_CLAMP_TO_EDGE
  195. - Added new format tfCompressed to create a compressed texture.
  196. - propertys IsCompressed, TextureSize and IsResident added
  197. IsCompressed and TextureSize only contains data from level 0
  198. 18-08-2003
  199. - Added function AddFunc to add PerPixelEffects to Image
  200. - LoadFromFunc now based on AddFunc
  201. - Invert now based on AddFunc
  202. - SwapColors now based on AddFunc
  203. 16-08-2003
  204. - Added function FlipHorz
  205. 15-08-2003
  206. - Added function LaodFromFunc to create images with function
  207. - Added function FlipVert
  208. - Added internal format RGB(A) if GL_EXT_bgra or OpenGL 1.2 isn't supported
  209. 29-07-2003
  210. - Added Alphafunctions to calculate alpha per function
  211. - Added Alpha from ColorKey using alphafunctions
  212. 28-07-2003
  213. - First full functionally Version of glBitmap
  214. - Support for 24Bit and 32Bit TGA Pictures added
  215. 25-07-2003
  216. - begin of programming
  217. ***********************************************************}
  218. unit glBitmap;
  219. // Please uncomment the defines below to configure the glBitmap to your preferences.
  220. // If you have configured the unit you can uncomment the warning above.
  221. {$MESSAGE warn 'Hey. I''m the glBitmap.pas and i need to be configured. My master tell me your preferences! ;)'}
  222. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  223. // Preferences ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  224. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  225. // activate to enable build-in OpenGL support with statically linked methods
  226. // use dglOpenGL.pas if not enabled
  227. {.$DEFINE GLB_NATIVE_OGL_STATIC}
  228. // activate to enable build-in OpenGL support with dynamically linked methods
  229. // use dglOpenGL.pas if not enabled
  230. {.$DEFINE GLB_NATIVE_OGL_DYNAMIC}
  231. // activate to enable the support for SDL_surfaces
  232. {.$DEFINE GLB_SDL}
  233. // activate to enable the support for TBitmap from Delphi (not lazarus)
  234. {.$DEFINE GLB_DELPHI}
  235. // activate to enable the support for TLazIntfImage from Lazarus
  236. {$DEFINE GLB_LAZARUS}
  237. // activate to enable the support of SDL_image to load files. (READ ONLY)
  238. // If you enable SDL_image all other libraries will be ignored!
  239. {.$DEFINE GLB_SDL_IMAGE}
  240. // activate to enable png support with the unit pngimage -> http://pngdelphi.sourceforge.net/
  241. // if you enable pngimage the libPNG will be ignored
  242. {.$DEFINE GLB_PNGIMAGE}
  243. // activate to use the libPNG -> http://www.libpng.org/
  244. // You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libpng
  245. {.$DEFINE GLB_LIB_PNG}
  246. // if you enable delphi jpegs the libJPEG will be ignored
  247. {.$DEFINE GLB_DELPHI_JPEG}
  248. // activate to use the libJPEG -> http://www.ijg.org/
  249. // You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libjpeg
  250. {.$DEFINE GLB_LIB_JPEG}
  251. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  252. // PRIVATE: do not change anything! //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  253. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  254. // Delphi Versions
  255. {$IFDEF fpc}
  256. {$MODE Delphi}
  257. {$IFDEF CPUI386}
  258. {$DEFINE CPU386}
  259. {$ASMMODE INTEL}
  260. {$ENDIF}
  261. {$IFNDEF WINDOWS}
  262. {$linklib c}
  263. {$ENDIF}
  264. {$ENDIF}
  265. // Operation System
  266. {$IF DEFINED(WIN32) or DEFINED(WIN64) or DEFINED(WINDOWS)}
  267. {$DEFINE GLB_WIN}
  268. {$ELSEIF DEFINED(LINUX)}
  269. {$DEFINE GLB_LINUX}
  270. {$IFEND}
  271. // native OpenGL Support
  272. {$IF DEFINED(GLB_NATIVE_OGL_STATIC) OR DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
  273. {$DEFINE GLB_NATIVE_OGL}
  274. {$IFEND}
  275. // checking define combinations
  276. //SDL Image
  277. {$IFDEF GLB_SDL_IMAGE}
  278. {$IFNDEF GLB_SDL}
  279. {$MESSAGE warn 'SDL_image won''t work without SDL. SDL will be activated.'}
  280. {$DEFINE GLB_SDL}
  281. {$ENDIF}
  282. {$IFDEF GLB_PNGIMAGE}
  283. {$MESSAGE warn 'The unit pngimage will be ignored because you are using SDL_image.'}
  284. {$undef GLB_PNGIMAGE}
  285. {$ENDIF}
  286. {$IFDEF GLB_DELPHI_JPEG}
  287. {$MESSAGE warn 'The unit JPEG will be ignored because you are using SDL_image.'}
  288. {$undef GLB_DELPHI_JPEG}
  289. {$ENDIF}
  290. {$IFDEF GLB_LIB_PNG}
  291. {$MESSAGE warn 'The library libPNG will be ignored because you are using SDL_image.'}
  292. {$undef GLB_LIB_PNG}
  293. {$ENDIF}
  294. {$IFDEF GLB_LIB_JPEG}
  295. {$MESSAGE warn 'The library libJPEG will be ignored because you are using SDL_image.'}
  296. {$undef GLB_LIB_JPEG}
  297. {$ENDIF}
  298. {$DEFINE GLB_SUPPORT_PNG_READ}
  299. {$DEFINE GLB_SUPPORT_JPEG_READ}
  300. {$ENDIF}
  301. // PNG Image
  302. {$IFDEF GLB_PNGIMAGE}
  303. {$IFDEF GLB_LIB_PNG}
  304. {$MESSAGE warn 'The library libPNG will be ignored if you are using pngimage.'}
  305. {$undef GLB_LIB_PNG}
  306. {$ENDIF}
  307. {$DEFINE GLB_SUPPORT_PNG_READ}
  308. {$DEFINE GLB_SUPPORT_PNG_WRITE}
  309. {$ENDIF}
  310. // libPNG
  311. {$IFDEF GLB_LIB_PNG}
  312. {$DEFINE GLB_SUPPORT_PNG_READ}
  313. {$DEFINE GLB_SUPPORT_PNG_WRITE}
  314. {$ENDIF}
  315. // JPEG Image
  316. {$IFDEF GLB_DELPHI_JPEG}
  317. {$IFDEF GLB_LIB_JPEG}
  318. {$MESSAGE warn 'The library libJPEG will be ignored if you are using the unit JPEG.'}
  319. {$undef GLB_LIB_JPEG}
  320. {$ENDIF}
  321. {$DEFINE GLB_SUPPORT_JPEG_READ}
  322. {$DEFINE GLB_SUPPORT_JPEG_WRITE}
  323. {$ENDIF}
  324. // libJPEG
  325. {$IFDEF GLB_LIB_JPEG}
  326. {$DEFINE GLB_SUPPORT_JPEG_READ}
  327. {$DEFINE GLB_SUPPORT_JPEG_WRITE}
  328. {$ENDIF}
  329. // native OpenGL
  330. {$IF DEFINED(GLB_NATIVE_OGL_STATIC) AND DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
  331. {$MESSAGE warn 'GLB_NATIVE_OGL_STATIC will be ignored because you enabled GLB_NATIVE_OGL_DYNAMIC'}
  332. {$IFEND}
  333. // general options
  334. {$EXTENDEDSYNTAX ON}
  335. {$LONGSTRINGS ON}
  336. {$ALIGN ON}
  337. {$IFNDEF FPC}
  338. {$OPTIMIZATION ON}
  339. {$ENDIF}
  340. interface
  341. uses
  342. {$IFNDEF GLB_NATIVE_OGL} dglOpenGL, {$ENDIF}
  343. {$IF DEFINED(GLB_WIN) AND
  344. DEFINED(GLB_NATIVE_OGL)} windows, {$IFEND}
  345. {$IFDEF GLB_SDL} SDL, {$ENDIF}
  346. {$IFDEF GLB_LAZARUS} IntfGraphics, GraphType, {$ENDIF}
  347. {$IFDEF GLB_DELPHI} Dialogs, Graphics, {$ENDIF}
  348. {$IFDEF GLB_SDL_IMAGE} SDL_image, {$ENDIF}
  349. {$IFDEF GLB_PNGIMAGE} pngimage, {$ENDIF}
  350. {$IFDEF GLB_LIB_PNG} libPNG, {$ENDIF}
  351. {$IFDEF GLB_DELPHI_JPEG} JPEG, {$ENDIF}
  352. {$IFDEF GLB_LIB_JPEG} libJPEG, {$ENDIF}
  353. Classes, SysUtils;
  354. {$IFDEF GLB_NATIVE_OGL}
  355. const
  356. GL_TRUE = 1;
  357. GL_FALSE = 0;
  358. GL_ZERO = 0;
  359. GL_ONE = 1;
  360. GL_VERSION = $1F02;
  361. GL_EXTENSIONS = $1F03;
  362. GL_TEXTURE_1D = $0DE0;
  363. GL_TEXTURE_2D = $0DE1;
  364. GL_TEXTURE_RECTANGLE = $84F5;
  365. GL_NORMAL_MAP = $8511;
  366. GL_TEXTURE_CUBE_MAP = $8513;
  367. GL_REFLECTION_MAP = $8512;
  368. GL_TEXTURE_CUBE_MAP_POSITIVE_X = $8515;
  369. GL_TEXTURE_CUBE_MAP_NEGATIVE_X = $8516;
  370. GL_TEXTURE_CUBE_MAP_POSITIVE_Y = $8517;
  371. GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = $8518;
  372. GL_TEXTURE_CUBE_MAP_POSITIVE_Z = $8519;
  373. GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = $851A;
  374. GL_TEXTURE_WIDTH = $1000;
  375. GL_TEXTURE_HEIGHT = $1001;
  376. GL_TEXTURE_INTERNAL_FORMAT = $1003;
  377. GL_TEXTURE_SWIZZLE_RGBA = $8E46;
  378. GL_S = $2000;
  379. GL_T = $2001;
  380. GL_R = $2002;
  381. GL_Q = $2003;
  382. GL_TEXTURE_GEN_S = $0C60;
  383. GL_TEXTURE_GEN_T = $0C61;
  384. GL_TEXTURE_GEN_R = $0C62;
  385. GL_TEXTURE_GEN_Q = $0C63;
  386. GL_RED = $1903;
  387. GL_GREEN = $1904;
  388. GL_BLUE = $1905;
  389. GL_ALPHA = $1906;
  390. GL_ALPHA4 = $803B;
  391. GL_ALPHA8 = $803C;
  392. GL_ALPHA12 = $803D;
  393. GL_ALPHA16 = $803E;
  394. GL_LUMINANCE = $1909;
  395. GL_LUMINANCE4 = $803F;
  396. GL_LUMINANCE8 = $8040;
  397. GL_LUMINANCE12 = $8041;
  398. GL_LUMINANCE16 = $8042;
  399. GL_LUMINANCE_ALPHA = $190A;
  400. GL_LUMINANCE4_ALPHA4 = $8043;
  401. GL_LUMINANCE6_ALPHA2 = $8044;
  402. GL_LUMINANCE8_ALPHA8 = $8045;
  403. GL_LUMINANCE12_ALPHA4 = $8046;
  404. GL_LUMINANCE12_ALPHA12 = $8047;
  405. GL_LUMINANCE16_ALPHA16 = $8048;
  406. GL_RGB = $1907;
  407. GL_BGR = $80E0;
  408. GL_R3_G3_B2 = $2A10;
  409. GL_RGB4 = $804F;
  410. GL_RGB5 = $8050;
  411. GL_RGB565 = $8D62;
  412. GL_RGB8 = $8051;
  413. GL_RGB10 = $8052;
  414. GL_RGB12 = $8053;
  415. GL_RGB16 = $8054;
  416. GL_RGBA = $1908;
  417. GL_BGRA = $80E1;
  418. GL_RGBA2 = $8055;
  419. GL_RGBA4 = $8056;
  420. GL_RGB5_A1 = $8057;
  421. GL_RGBA8 = $8058;
  422. GL_RGB10_A2 = $8059;
  423. GL_RGBA12 = $805A;
  424. GL_RGBA16 = $805B;
  425. GL_DEPTH_COMPONENT = $1902;
  426. GL_DEPTH_COMPONENT16 = $81A5;
  427. GL_DEPTH_COMPONENT24 = $81A6;
  428. GL_DEPTH_COMPONENT32 = $81A7;
  429. GL_COMPRESSED_RGB = $84ED;
  430. GL_COMPRESSED_RGBA = $84EE;
  431. GL_COMPRESSED_RGB_S3TC_DXT1_EXT = $83F0;
  432. GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = $83F1;
  433. GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = $83F2;
  434. GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = $83F3;
  435. GL_UNSIGNED_BYTE = $1401;
  436. GL_UNSIGNED_BYTE_3_3_2 = $8032;
  437. GL_UNSIGNED_BYTE_2_3_3_REV = $8362;
  438. GL_UNSIGNED_SHORT = $1403;
  439. GL_UNSIGNED_SHORT_5_6_5 = $8363;
  440. GL_UNSIGNED_SHORT_4_4_4_4 = $8033;
  441. GL_UNSIGNED_SHORT_5_5_5_1 = $8034;
  442. GL_UNSIGNED_SHORT_5_6_5_REV = $8364;
  443. GL_UNSIGNED_SHORT_4_4_4_4_REV = $8365;
  444. GL_UNSIGNED_SHORT_1_5_5_5_REV = $8366;
  445. GL_UNSIGNED_INT = $1405;
  446. GL_UNSIGNED_INT_8_8_8_8 = $8035;
  447. GL_UNSIGNED_INT_10_10_10_2 = $8036;
  448. GL_UNSIGNED_INT_8_8_8_8_REV = $8367;
  449. GL_UNSIGNED_INT_2_10_10_10_REV = $8368;
  450. { Texture Filter }
  451. GL_TEXTURE_MAG_FILTER = $2800;
  452. GL_TEXTURE_MIN_FILTER = $2801;
  453. GL_NEAREST = $2600;
  454. GL_NEAREST_MIPMAP_NEAREST = $2700;
  455. GL_NEAREST_MIPMAP_LINEAR = $2702;
  456. GL_LINEAR = $2601;
  457. GL_LINEAR_MIPMAP_NEAREST = $2701;
  458. GL_LINEAR_MIPMAP_LINEAR = $2703;
  459. { Texture Wrap }
  460. GL_TEXTURE_WRAP_S = $2802;
  461. GL_TEXTURE_WRAP_T = $2803;
  462. GL_TEXTURE_WRAP_R = $8072;
  463. GL_CLAMP = $2900;
  464. GL_REPEAT = $2901;
  465. GL_CLAMP_TO_EDGE = $812F;
  466. GL_CLAMP_TO_BORDER = $812D;
  467. GL_MIRRORED_REPEAT = $8370;
  468. { Other }
  469. GL_GENERATE_MIPMAP = $8191;
  470. GL_TEXTURE_BORDER_COLOR = $1004;
  471. GL_MAX_TEXTURE_SIZE = $0D33;
  472. GL_PACK_ALIGNMENT = $0D05;
  473. GL_UNPACK_ALIGNMENT = $0CF5;
  474. GL_TEXTURE_MAX_ANISOTROPY_EXT = $84FE;
  475. GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = $84FF;
  476. GL_MAX_CUBE_MAP_TEXTURE_SIZE = $851C;
  477. GL_TEXTURE_GEN_MODE = $2500;
  478. {$IF DEFINED(GLB_WIN)}
  479. libglu = 'glu32.dll';
  480. libopengl = 'opengl32.dll';
  481. {$ELSEIF DEFINED(GLB_LINUX)}
  482. libglu = 'libGLU.so.1';
  483. libopengl = 'libGL.so.1';
  484. {$IFEND}
  485. type
  486. GLboolean = BYTEBOOL;
  487. GLint = Integer;
  488. GLsizei = Integer;
  489. GLuint = Cardinal;
  490. GLfloat = Single;
  491. GLenum = Cardinal;
  492. PGLvoid = Pointer;
  493. PGLboolean = ^GLboolean;
  494. PGLint = ^GLint;
  495. PGLuint = ^GLuint;
  496. PGLfloat = ^GLfloat;
  497. TglCompressedTexImage1D = procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  498. 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}
  499. TglGetCompressedTexImage = procedure(target: GLenum; level: GLint; img: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  500. {$IF DEFINED(GLB_WIN)}
  501. TwglGetProcAddress = function (ProcName: PAnsiChar): Pointer; stdcall;
  502. {$ELSEIF DEFINED(GLB_LINUX)}
  503. TglXGetProcAddress = function(ProcName: PAnsiChar): Pointer; cdecl;
  504. TglXGetProcAddressARB = function(const name: PAnsiChar): pointer; cdecl;
  505. {$IFEND}
  506. {$IF DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
  507. TglEnable = procedure(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  508. TglDisable = procedure(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  509. TglGetString = function(name: GLenum): PAnsiChar; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  510. TglGetIntegerv = procedure(pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  511. TglTexParameteri = procedure(target: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  512. TglTexParameteriv = procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  513. TglTexParameterfv = procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  514. TglGetTexParameteriv = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  515. TglGetTexParameterfv = procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  516. TglGetTexLevelParameteriv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  517. TglGetTexLevelParameterfv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  518. TglTexGeni = procedure(coord: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  519. TglGenTextures = procedure(n: GLsizei; textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  520. TglBindTexture = procedure(target: GLenum; texture: GLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  521. TglDeleteTextures = procedure(n: GLsizei; const textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  522. TglAreTexturesResident = function(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  523. TglReadPixels = procedure(x: GLint; y: GLint; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  524. TglPixelStorei = procedure(pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  525. 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}
  526. 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}
  527. TglGetTexImage = procedure(target: GLenum; level: GLint; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  528. TgluBuild1DMipmaps = function(target: GLEnum; components, width: GLint; format, atype: GLEnum; const data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  529. TgluBuild2DMipmaps = function(target: GLEnum; components, width, height: GLint; format, atype: GLEnum; const Data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  530. {$ELSEIF DEFINED(GLB_NATIVE_OGL_STATIC)}
  531. procedure glEnable(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  532. procedure glDisable(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  533. function glGetString(name: GLenum): PAnsiChar; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  534. procedure glGetIntegerv(pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  535. procedure glTexParameteri(target: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  536. procedure glTexParameteriv(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  537. procedure glTexParameterfv(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  538. procedure glGetTexParameteriv(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  539. procedure glGetTexParameterfv(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  540. procedure glGetTexLevelParameteriv(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  541. procedure glGetTexLevelParameterfv(target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  542. procedure glTexGeni(coord: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  543. procedure glGenTextures(n: GLsizei; textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  544. procedure glBindTexture(target: GLenum; texture: GLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  545. procedure glDeleteTextures(n: GLsizei; const textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  546. function glAreTexturesResident(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  547. 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;
  548. procedure glPixelStorei(pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  549. 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;
  550. 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;
  551. procedure glGetTexImage(target: GLenum; level: GLint; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  552. function gluBuild1DMipmaps(target: GLEnum; components, width: GLint; format, atype: GLEnum; const data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libglu;
  553. function gluBuild2DMipmaps(target: GLEnum; components, width, height: GLint; format, atype: GLEnum; const Data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libglu;
  554. {$IFEND}
  555. var
  556. GL_VERSION_1_2,
  557. GL_VERSION_1_3,
  558. GL_VERSION_1_4,
  559. GL_VERSION_2_0,
  560. GL_VERSION_3_3,
  561. GL_SGIS_generate_mipmap,
  562. GL_ARB_texture_border_clamp,
  563. GL_ARB_texture_mirrored_repeat,
  564. GL_ARB_texture_rectangle,
  565. GL_ARB_texture_non_power_of_two,
  566. GL_ARB_texture_swizzle,
  567. GL_ARB_texture_cube_map,
  568. GL_IBM_texture_mirrored_repeat,
  569. GL_NV_texture_rectangle,
  570. GL_EXT_texture_edge_clamp,
  571. GL_EXT_texture_rectangle,
  572. GL_EXT_texture_swizzle,
  573. GL_EXT_texture_cube_map,
  574. GL_EXT_texture_filter_anisotropic: Boolean;
  575. glCompressedTexImage1D: TglCompressedTexImage1D;
  576. glCompressedTexImage2D: TglCompressedTexImage2D;
  577. glGetCompressedTexImage: TglGetCompressedTexImage;
  578. {$IF DEFINED(GLB_WIN)}
  579. wglGetProcAddress: TwglGetProcAddress;
  580. {$ELSEIF DEFINED(GLB_LINUX)}
  581. glXGetProcAddress: TglXGetProcAddress;
  582. glXGetProcAddressARB: TglXGetProcAddress;
  583. {$IFEND}
  584. {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
  585. glEnable: TglEnable;
  586. glDisable: TglDisable;
  587. glGetString: TglGetString;
  588. glGetIntegerv: TglGetIntegerv;
  589. glTexParameteri: TglTexParameteri;
  590. glTexParameteriv: TglTexParameteriv;
  591. glTexParameterfv: TglTexParameterfv;
  592. glGetTexParameteriv: TglGetTexParameteriv;
  593. glGetTexParameterfv: TglGetTexParameterfv;
  594. glGetTexLevelParameteriv: TglGetTexLevelParameteriv;
  595. glGetTexLevelParameterfv: TglGetTexLevelParameterfv;
  596. glTexGeni: TglTexGeni;
  597. glGenTextures: TglGenTextures;
  598. glBindTexture: TglBindTexture;
  599. glDeleteTextures: TglDeleteTextures;
  600. glAreTexturesResident: TglAreTexturesResident;
  601. glReadPixels: TglReadPixels;
  602. glPixelStorei: TglPixelStorei;
  603. glTexImage1D: TglTexImage1D;
  604. glTexImage2D: TglTexImage2D;
  605. glGetTexImage: TglGetTexImage;
  606. gluBuild1DMipmaps: TgluBuild1DMipmaps;
  607. gluBuild2DMipmaps: TgluBuild2DMipmaps;
  608. {$ENDIF}
  609. {$ENDIF}
  610. type
  611. ////////////////////////////////////////////////////////////////////////////////////////////////////
  612. TglBitmapFormat = (
  613. tfEmpty = 0, //must be smallest value!
  614. tfAlpha4,
  615. tfAlpha8,
  616. tfAlpha12,
  617. tfAlpha16,
  618. tfLuminance4,
  619. tfLuminance8,
  620. tfLuminance12,
  621. tfLuminance16,
  622. tfLuminance4Alpha4,
  623. tfLuminance6Alpha2,
  624. tfLuminance8Alpha8,
  625. tfLuminance12Alpha4,
  626. tfLuminance12Alpha12,
  627. tfLuminance16Alpha16,
  628. tfR3G3B2,
  629. tfRGB4,
  630. tfR5G6B5,
  631. tfRGB5,
  632. tfRGB8,
  633. tfRGB10,
  634. tfRGB12,
  635. tfRGB16,
  636. tfRGBA2,
  637. tfRGBA4,
  638. tfRGB5A1,
  639. tfRGBA8,
  640. tfRGB10A2,
  641. tfRGBA12,
  642. tfRGBA16,
  643. tfBGR4,
  644. tfB5G6R5,
  645. tfBGR5,
  646. tfBGR8,
  647. tfBGR10,
  648. tfBGR12,
  649. tfBGR16,
  650. tfBGRA2,
  651. tfBGRA4,
  652. tfBGR5A1,
  653. tfBGRA8,
  654. tfBGR10A2,
  655. tfBGRA12,
  656. tfBGRA16,
  657. tfDepth16,
  658. tfDepth24,
  659. tfDepth32,
  660. tfS3tcDtx1RGBA,
  661. tfS3tcDtx3RGBA,
  662. tfS3tcDtx5RGBA
  663. );
  664. TglBitmapFileType = (
  665. {$IFDEF GLB_SUPPORT_PNG_WRITE} ftPNG, {$ENDIF}
  666. {$IFDEF GLB_SUPPORT_JPEG_WRITE}ftJPEG, {$ENDIF}
  667. ftDDS,
  668. ftTGA,
  669. ftBMP);
  670. TglBitmapFileTypes = set of TglBitmapFileType;
  671. TglBitmapMipMap = (
  672. mmNone,
  673. mmMipmap,
  674. mmMipmapGlu);
  675. TglBitmapNormalMapFunc = (
  676. nm4Samples,
  677. nmSobel,
  678. nm3x3,
  679. nm5x5);
  680. ////////////////////////////////////////////////////////////////////////////////////////////////////
  681. EglBitmap = class(Exception);
  682. EglBitmapNotSupported = class(Exception);
  683. EglBitmapSizeToLarge = class(EglBitmap);
  684. EglBitmapNonPowerOfTwo = class(EglBitmap);
  685. EglBitmapUnsupportedFormat = class(EglBitmap)
  686. constructor Create(const aFormat: TglBitmapFormat); overload;
  687. constructor Create(const aMsg: String; const aFormat: TglBitmapFormat); overload;
  688. end;
  689. ////////////////////////////////////////////////////////////////////////////////////////////////////
  690. TglBitmapColorRec = packed record
  691. case Integer of
  692. 0: (r, g, b, a: Cardinal);
  693. 1: (arr: array[0..3] of Cardinal);
  694. end;
  695. TglBitmapPixelData = packed record
  696. Data, Range: TglBitmapColorRec;
  697. Format: TglBitmapFormat;
  698. end;
  699. PglBitmapPixelData = ^TglBitmapPixelData;
  700. ////////////////////////////////////////////////////////////////////////////////////////////////////
  701. TglBitmapPixelPositionFields = set of (ffX, ffY);
  702. TglBitmapPixelPosition = record
  703. Fields : TglBitmapPixelPositionFields;
  704. X : Word;
  705. Y : Word;
  706. end;
  707. TglBitmapFormatDescriptor = class(TObject)
  708. protected
  709. function GetIsCompressed: Boolean; virtual; abstract;
  710. function GetHasAlpha: Boolean; virtual; abstract;
  711. function GetglDataFormat: GLenum; virtual; abstract;
  712. function GetglFormat: GLenum; virtual; abstract;
  713. function GetglInternalFormat: GLenum; virtual; abstract;
  714. public
  715. property IsCompressed: Boolean read GetIsCompressed;
  716. property HasAlpha: Boolean read GetHasAlpha;
  717. property glFormat: GLenum read GetglFormat;
  718. property glInternalFormat: GLenum read GetglInternalFormat;
  719. property glDataFormat: GLenum read GetglDataFormat;
  720. end;
  721. ////////////////////////////////////////////////////////////////////////////////////////////////////
  722. TglBitmap = class;
  723. TglBitmapFunctionRec = record
  724. Sender: TglBitmap;
  725. Size: TglBitmapPixelPosition;
  726. Position: TglBitmapPixelPosition;
  727. Source: TglBitmapPixelData;
  728. Dest: TglBitmapPixelData;
  729. Args: Pointer;
  730. end;
  731. TglBitmapFunction = procedure(var FuncRec: TglBitmapFunctionRec);
  732. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  733. TglBitmap = class
  734. private
  735. function GetFormatDesc: TglBitmapFormatDescriptor;
  736. protected
  737. fID: GLuint;
  738. fTarget: GLuint;
  739. fAnisotropic: Integer;
  740. fDeleteTextureOnFree: Boolean;
  741. fFreeDataAfterGenTexture: Boolean;
  742. fData: PByte;
  743. fIsResident: Boolean;
  744. fBorderColor: array[0..3] of Single;
  745. fDimension: TglBitmapPixelPosition;
  746. fMipMap: TglBitmapMipMap;
  747. fFormat: TglBitmapFormat;
  748. // Mapping
  749. fPixelSize: Integer;
  750. fRowSize: Integer;
  751. // Filtering
  752. fFilterMin: GLenum;
  753. fFilterMag: GLenum;
  754. // TexturWarp
  755. fWrapS: GLenum;
  756. fWrapT: GLenum;
  757. fWrapR: GLenum;
  758. //Swizzle
  759. fSwizzle: array[0..3] of GLenum;
  760. // CustomData
  761. fFilename: String;
  762. fCustomName: String;
  763. fCustomNameW: WideString;
  764. fCustomData: Pointer;
  765. //Getter
  766. function GetWidth: Integer; virtual;
  767. function GetHeight: Integer; virtual;
  768. function GetFileWidth: Integer; virtual;
  769. function GetFileHeight: Integer; virtual;
  770. //Setter
  771. procedure SetCustomData(const aValue: Pointer);
  772. procedure SetCustomName(const aValue: String);
  773. procedure SetCustomNameW(const aValue: WideString);
  774. procedure SetDeleteTextureOnFree(const aValue: Boolean);
  775. procedure SetFormat(const aValue: TglBitmapFormat);
  776. procedure SetFreeDataAfterGenTexture(const aValue: Boolean);
  777. procedure SetID(const aValue: Cardinal);
  778. procedure SetMipMap(const aValue: TglBitmapMipMap);
  779. procedure SetTarget(const aValue: Cardinal);
  780. procedure SetAnisotropic(const aValue: Integer);
  781. procedure CreateID;
  782. procedure SetupParameters(out aBuildWithGlu: Boolean);
  783. procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
  784. const aWidth: Integer = -1; const aHeight: Integer = -1); virtual; //be careful, aData could be freed by this method
  785. procedure GenTexture(const aTestTextureSize: Boolean = true); virtual; abstract;
  786. function FlipHorz: Boolean; virtual;
  787. function FlipVert: Boolean; virtual;
  788. property Width: Integer read GetWidth;
  789. property Height: Integer read GetHeight;
  790. property FileWidth: Integer read GetFileWidth;
  791. property FileHeight: Integer read GetFileHeight;
  792. public
  793. //Properties
  794. property ID: Cardinal read fID write SetID;
  795. property Target: Cardinal read fTarget write SetTarget;
  796. property Format: TglBitmapFormat read fFormat write SetFormat;
  797. property MipMap: TglBitmapMipMap read fMipMap write SetMipMap;
  798. property Anisotropic: Integer read fAnisotropic write SetAnisotropic;
  799. property FormatDesc: TglBitmapFormatDescriptor read GetFormatDesc;
  800. property Filename: String read fFilename;
  801. property CustomName: String read fCustomName write SetCustomName;
  802. property CustomNameW: WideString read fCustomNameW write SetCustomNameW;
  803. property CustomData: Pointer read fCustomData write SetCustomData;
  804. property DeleteTextureOnFree: Boolean read fDeleteTextureOnFree write SetDeleteTextureOnFree;
  805. property FreeDataAfterGenTexture: Boolean read fFreeDataAfterGenTexture write SetFreeDataAfterGenTexture;
  806. property Dimension: TglBitmapPixelPosition read fDimension;
  807. property Data: PByte read fData;
  808. property IsResident: Boolean read fIsResident;
  809. procedure AfterConstruction; override;
  810. procedure BeforeDestruction; override;
  811. procedure PrepareResType(var aResource: String; var aResType: PChar);
  812. //Load
  813. procedure LoadFromFile(const aFilename: String);
  814. procedure LoadFromStream(const aStream: TStream); virtual;
  815. procedure LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
  816. const aFormat: TglBitmapFormat; const aArgs: Pointer = nil);
  817. procedure LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil);
  818. procedure LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
  819. //Save
  820. procedure SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
  821. procedure SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType); virtual;
  822. //Convert
  823. function AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer = nil): Boolean; overload;
  824. function AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
  825. const aFormat: TglBitmapFormat; const aArgs: Pointer = nil): Boolean; overload;
  826. public
  827. //Alpha & Co
  828. {$IFDEF GLB_SDL}
  829. function AssignToSurface(out aSurface: PSDL_Surface): Boolean;
  830. function AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
  831. function AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
  832. function AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil;
  833. const aArgs: Pointer = nil): Boolean;
  834. {$ENDIF}
  835. {$IFDEF GLB_DELPHI}
  836. function AssignToBitmap(const aBitmap: TBitmap): Boolean;
  837. function AssignFromBitmap(const aBitmap: TBitmap): Boolean;
  838. function AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
  839. function AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction = nil;
  840. const aArgs: Pointer = nil): Boolean;
  841. {$ENDIF}
  842. {$IFDEF GLB_LAZARUS}
  843. function AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
  844. function AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
  845. function AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
  846. function AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction = nil;
  847. const aArgs: Pointer = nil): Boolean;
  848. {$ENDIF}
  849. function AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil;
  850. const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  851. function AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
  852. const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  853. function AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer = nil): Boolean; virtual;
  854. function AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  855. function AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  856. function AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  857. function AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte = 0): Boolean;
  858. function AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal = 0): Boolean;
  859. function AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single = 0): Boolean;
  860. function AddAlphaFromValue(const aAlpha: Byte): Boolean;
  861. function AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
  862. function AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
  863. function RemoveAlpha: Boolean; virtual;
  864. public
  865. //Common
  866. function Clone: TglBitmap;
  867. function ConvertTo(const aFormat: TglBitmapFormat): Boolean; virtual;
  868. procedure Invert(const aUseRGB: Boolean = true; const aUseAlpha: Boolean = false);
  869. procedure SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
  870. procedure FreeData;
  871. //ColorFill
  872. procedure FillWithColor(const aRed, aGreen, aBlue: Byte; const aAlpha: Byte = 255);
  873. procedure FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal = $FFFFFFFF);
  874. procedure FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha : Single = 1);
  875. //TexParameters
  876. procedure SetFilter(const aMin, aMag: GLenum);
  877. procedure SetWrap(
  878. const S: GLenum = GL_CLAMP_TO_EDGE;
  879. const T: GLenum = GL_CLAMP_TO_EDGE;
  880. const R: GLenum = GL_CLAMP_TO_EDGE);
  881. procedure SetSwizzle(const r, g, b, a: GLenum);
  882. procedure Bind(const aEnableTextureUnit: Boolean = true); virtual;
  883. procedure Unbind(const aDisableTextureUnit: Boolean = true); virtual;
  884. //Constructors
  885. constructor Create; overload;
  886. constructor Create(const aFileName: String); overload;
  887. constructor Create(const aStream: TStream); overload;
  888. constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat); overload;
  889. constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer = nil); overload;
  890. constructor Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil); overload;
  891. constructor Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar); overload;
  892. private
  893. {$IFDEF GLB_SUPPORT_PNG_READ} function LoadPNG(const aStream: TStream): Boolean; virtual; {$ENDIF}
  894. {$ifdef GLB_SUPPORT_PNG_WRITE} procedure SavePNG(const aStream: TStream); virtual; {$ENDIF}
  895. {$IFDEF GLB_SUPPORT_JPEG_READ} function LoadJPEG(const aStream: TStream): Boolean; virtual; {$ENDIF}
  896. {$IFDEF GLB_SUPPORT_JPEG_WRITE} procedure SaveJPEG(const aStream: TStream); virtual; {$ENDIF}
  897. function LoadBMP(const aStream: TStream): Boolean; virtual;
  898. procedure SaveBMP(const aStream: TStream); virtual;
  899. function LoadTGA(const aStream: TStream): Boolean; virtual;
  900. procedure SaveTGA(const aStream: TStream); virtual;
  901. function LoadDDS(const aStream: TStream): Boolean; virtual;
  902. procedure SaveDDS(const aStream: TStream); virtual;
  903. end;
  904. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  905. TglBitmap1D = class(TglBitmap)
  906. protected
  907. procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
  908. const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
  909. procedure UploadData(const aBuildWithGlu: Boolean);
  910. public
  911. property Width;
  912. procedure AfterConstruction; override;
  913. function FlipHorz: Boolean; override;
  914. procedure GenTexture(const aTestTextureSize: Boolean = true); override;
  915. end;
  916. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  917. TglBitmap2D = class(TglBitmap)
  918. protected
  919. fLines: array of PByte;
  920. function GetScanline(const aIndex: Integer): Pointer;
  921. procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
  922. const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
  923. procedure UploadData(const aTarget: GLenum; const aBuildWithGlu: Boolean);
  924. public
  925. property Width;
  926. property Height;
  927. property Scanline[const aIndex: Integer]: Pointer read GetScanline;
  928. procedure AfterConstruction; override;
  929. procedure GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
  930. procedure GetDataFromTexture;
  931. procedure GenTexture(const aTestTextureSize: Boolean = true); override;
  932. function FlipHorz: Boolean; override;
  933. function FlipVert: Boolean; override;
  934. procedure ToNormalMap(const aFunc: TglBitmapNormalMapFunc = nm3x3;
  935. const aScale: Single = 2; const aUseAlpha: Boolean = false);
  936. end;
  937. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  938. TglBitmapCubeMap = class(TglBitmap2D)
  939. protected
  940. fGenMode: Integer;
  941. procedure GenTexture(const aTestTextureSize: Boolean = true); reintroduce;
  942. public
  943. procedure AfterConstruction; override;
  944. procedure GenerateCubeMap(const aCubeTarget: Cardinal; const aTestTextureSize: Boolean = true);
  945. procedure Bind(const aEnableTexCoordsGen: Boolean = true; const aEnableTextureUnit: Boolean = true); reintroduce; virtual;
  946. procedure Unbind(const aDisableTexCoordsGen: Boolean = true; const aDisableTextureUnit: Boolean = true); reintroduce; virtual;
  947. end;
  948. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  949. TglBitmapNormalMap = class(TglBitmapCubeMap)
  950. public
  951. procedure AfterConstruction; override;
  952. procedure GenerateNormalMap(const aSize: Integer = 32; const aTestTextureSize: Boolean = true);
  953. end;
  954. const
  955. NULL_SIZE: TglBitmapPixelPosition = (Fields: []; X: 0; Y: 0);
  956. procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
  957. procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
  958. procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
  959. procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
  960. procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
  961. procedure glBitmapSetDefaultWrap(
  962. const S: Cardinal = GL_CLAMP_TO_EDGE;
  963. const T: Cardinal = GL_CLAMP_TO_EDGE;
  964. const R: Cardinal = GL_CLAMP_TO_EDGE);
  965. function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
  966. function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
  967. function glBitmapGetDefaultMipmap: TglBitmapMipMap;
  968. function glBitmapGetDefaultFormat: TglBitmapFormat;
  969. procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
  970. procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
  971. function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
  972. function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
  973. function glBitmapColorRecCmp(const r1, r2: TglBitmapColorRec): Boolean;
  974. var
  975. glBitmapDefaultDeleteTextureOnFree: Boolean;
  976. glBitmapDefaultFreeDataAfterGenTextures: Boolean;
  977. glBitmapDefaultFormat: TglBitmapFormat;
  978. glBitmapDefaultMipmap: TglBitmapMipMap;
  979. glBitmapDefaultFilterMin: Cardinal;
  980. glBitmapDefaultFilterMag: Cardinal;
  981. glBitmapDefaultWrapS: Cardinal;
  982. glBitmapDefaultWrapT: Cardinal;
  983. glBitmapDefaultWrapR: Cardinal;
  984. glDefaultSwizzle: array[0..3] of GLenum;
  985. {$IFDEF GLB_DELPHI}
  986. function CreateGrayPalette: HPALETTE;
  987. {$ENDIF}
  988. implementation
  989. uses
  990. Math, syncobjs, typinfo;
  991. type
  992. {$IFNDEF fpc}
  993. QWord = System.UInt64;
  994. PQWord = ^QWord;
  995. PtrInt = Longint;
  996. PtrUInt = DWord;
  997. {$ENDIF}
  998. ////////////////////////////////////////////////////////////////////////////////////////////////////
  999. TShiftRec = packed record
  1000. case Integer of
  1001. 0: (r, g, b, a: Byte);
  1002. 1: (arr: array[0..3] of Byte);
  1003. end;
  1004. TFormatDescriptor = class(TglBitmapFormatDescriptor)
  1005. private
  1006. function GetRedMask: QWord;
  1007. function GetGreenMask: QWord;
  1008. function GetBlueMask: QWord;
  1009. function GetAlphaMask: QWord;
  1010. protected
  1011. fFormat: TglBitmapFormat;
  1012. fWithAlpha: TglBitmapFormat;
  1013. fWithoutAlpha: TglBitmapFormat;
  1014. fRGBInverted: TglBitmapFormat;
  1015. fUncompressed: TglBitmapFormat;
  1016. fPixelSize: Single;
  1017. fIsCompressed: Boolean;
  1018. fRange: TglBitmapColorRec;
  1019. fShift: TShiftRec;
  1020. fglFormat: GLenum;
  1021. fglInternalFormat: GLenum;
  1022. fglDataFormat: GLenum;
  1023. function GetIsCompressed: Boolean; override;
  1024. function GetHasAlpha: Boolean; override;
  1025. function GetglFormat: GLenum; override;
  1026. function GetglInternalFormat: GLenum; override;
  1027. function GetglDataFormat: GLenum; override;
  1028. function GetComponents: Integer; virtual;
  1029. public
  1030. property Format: TglBitmapFormat read fFormat;
  1031. property WithAlpha: TglBitmapFormat read fWithAlpha;
  1032. property WithoutAlpha: TglBitmapFormat read fWithoutAlpha;
  1033. property RGBInverted: TglBitmapFormat read fRGBInverted;
  1034. property Components: Integer read GetComponents;
  1035. property PixelSize: Single read fPixelSize;
  1036. property Range: TglBitmapColorRec read fRange;
  1037. property Shift: TShiftRec read fShift;
  1038. property RedMask: QWord read GetRedMask;
  1039. property GreenMask: QWord read GetGreenMask;
  1040. property BlueMask: QWord read GetBlueMask;
  1041. property AlphaMask: QWord read GetAlphaMask;
  1042. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); virtual; abstract;
  1043. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract;
  1044. function GetSize(const aSize: TglBitmapPixelPosition): Integer; overload; virtual;
  1045. function GetSize(const aWidth, aHeight: Integer): Integer; overload; virtual;
  1046. function CreateMappingData: Pointer; virtual;
  1047. procedure FreeMappingData(var aMappingData: Pointer); virtual;
  1048. function IsEmpty: Boolean; virtual;
  1049. function MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: QWord): Boolean; virtual;
  1050. procedure PreparePixel(out aPixel: TglBitmapPixelData); virtual;
  1051. constructor Create; virtual;
  1052. public
  1053. class procedure Init;
  1054. class function Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
  1055. class function GetWithAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
  1056. class procedure Clear;
  1057. class procedure Finalize;
  1058. end;
  1059. TFormatDescriptorClass = class of TFormatDescriptor;
  1060. TfdEmpty = class(TFormatDescriptor);
  1061. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1062. TfdAlpha_UB1 = class(TFormatDescriptor) //1* unsigned byte
  1063. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1064. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1065. constructor Create; override;
  1066. end;
  1067. TfdLuminance_UB1 = class(TFormatDescriptor) //1* unsigned byte
  1068. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1069. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1070. constructor Create; override;
  1071. end;
  1072. TfdUniversal_UB1 = class(TFormatDescriptor) //1* unsigned byte
  1073. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1074. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1075. constructor Create; override;
  1076. end;
  1077. TfdLuminanceAlpha_UB2 = class(TfdLuminance_UB1) //2* unsigned byte
  1078. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1079. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1080. constructor Create; override;
  1081. end;
  1082. TfdRGB_UB3 = class(TFormatDescriptor) //3* unsigned byte
  1083. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1084. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1085. constructor Create; override;
  1086. end;
  1087. TfdBGR_UB3 = class(TFormatDescriptor) //3* unsigned byte (inverse)
  1088. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1089. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1090. constructor Create; override;
  1091. end;
  1092. TfdRGBA_UB4 = class(TfdRGB_UB3) //4* unsigned byte
  1093. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1094. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1095. constructor Create; override;
  1096. end;
  1097. TfdBGRA_UB4 = class(TfdBGR_UB3) //4* unsigned byte (inverse)
  1098. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1099. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1100. constructor Create; override;
  1101. end;
  1102. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1103. TfdAlpha_US1 = class(TFormatDescriptor) //1* unsigned short
  1104. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1105. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1106. constructor Create; override;
  1107. end;
  1108. TfdLuminance_US1 = class(TFormatDescriptor) //1* unsigned short
  1109. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1110. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1111. constructor Create; override;
  1112. end;
  1113. TfdUniversal_US1 = class(TFormatDescriptor) //1* unsigned short
  1114. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1115. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1116. constructor Create; override;
  1117. end;
  1118. TfdDepth_US1 = class(TFormatDescriptor) //1* unsigned short
  1119. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1120. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1121. constructor Create; override;
  1122. end;
  1123. TfdLuminanceAlpha_US2 = class(TfdLuminance_US1) //2* unsigned short
  1124. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1125. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1126. constructor Create; override;
  1127. end;
  1128. TfdRGB_US3 = class(TFormatDescriptor) //3* unsigned short
  1129. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1130. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1131. constructor Create; override;
  1132. end;
  1133. TfdBGR_US3 = class(TFormatDescriptor) //3* unsigned short (inverse)
  1134. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1135. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1136. constructor Create; override;
  1137. end;
  1138. TfdRGBA_US4 = class(TfdRGB_US3) //4* unsigned short
  1139. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1140. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1141. constructor Create; override;
  1142. end;
  1143. TfdBGRA_US4 = class(TfdBGR_US3) //4* unsigned short (inverse)
  1144. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1145. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1146. constructor Create; override;
  1147. end;
  1148. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1149. TfdUniversal_UI1 = class(TFormatDescriptor) //1* unsigned int
  1150. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1151. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1152. constructor Create; override;
  1153. end;
  1154. TfdDepth_UI1 = class(TFormatDescriptor) //1* unsigned int
  1155. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1156. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1157. constructor Create; override;
  1158. end;
  1159. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1160. TfdAlpha4 = class(TfdAlpha_UB1)
  1161. constructor Create; override;
  1162. end;
  1163. TfdAlpha8 = class(TfdAlpha_UB1)
  1164. constructor Create; override;
  1165. end;
  1166. TfdAlpha12 = class(TfdAlpha_US1)
  1167. constructor Create; override;
  1168. end;
  1169. TfdAlpha16 = class(TfdAlpha_US1)
  1170. constructor Create; override;
  1171. end;
  1172. TfdLuminance4 = class(TfdLuminance_UB1)
  1173. constructor Create; override;
  1174. end;
  1175. TfdLuminance8 = class(TfdLuminance_UB1)
  1176. constructor Create; override;
  1177. end;
  1178. TfdLuminance12 = class(TfdLuminance_US1)
  1179. constructor Create; override;
  1180. end;
  1181. TfdLuminance16 = class(TfdLuminance_US1)
  1182. constructor Create; override;
  1183. end;
  1184. TfdLuminance4Alpha4 = class(TfdLuminanceAlpha_UB2)
  1185. constructor Create; override;
  1186. end;
  1187. TfdLuminance6Alpha2 = class(TfdLuminanceAlpha_UB2)
  1188. constructor Create; override;
  1189. end;
  1190. TfdLuminance8Alpha8 = class(TfdLuminanceAlpha_UB2)
  1191. constructor Create; override;
  1192. end;
  1193. TfdLuminance12Alpha4 = class(TfdLuminanceAlpha_US2)
  1194. constructor Create; override;
  1195. end;
  1196. TfdLuminance12Alpha12 = class(TfdLuminanceAlpha_US2)
  1197. constructor Create; override;
  1198. end;
  1199. TfdLuminance16Alpha16 = class(TfdLuminanceAlpha_US2)
  1200. constructor Create; override;
  1201. end;
  1202. TfdR3G3B2 = class(TfdUniversal_UB1)
  1203. constructor Create; override;
  1204. end;
  1205. TfdRGB4 = class(TfdUniversal_US1)
  1206. constructor Create; override;
  1207. end;
  1208. TfdR5G6B5 = class(TfdUniversal_US1)
  1209. constructor Create; override;
  1210. end;
  1211. TfdRGB5 = class(TfdUniversal_US1)
  1212. constructor Create; override;
  1213. end;
  1214. TfdRGB8 = class(TfdRGB_UB3)
  1215. constructor Create; override;
  1216. end;
  1217. TfdRGB10 = class(TfdUniversal_UI1)
  1218. constructor Create; override;
  1219. end;
  1220. TfdRGB12 = class(TfdRGB_US3)
  1221. constructor Create; override;
  1222. end;
  1223. TfdRGB16 = class(TfdRGB_US3)
  1224. constructor Create; override;
  1225. end;
  1226. TfdRGBA2 = class(TfdRGBA_UB4)
  1227. constructor Create; override;
  1228. end;
  1229. TfdRGBA4 = class(TfdUniversal_US1)
  1230. constructor Create; override;
  1231. end;
  1232. TfdRGB5A1 = class(TfdUniversal_US1)
  1233. constructor Create; override;
  1234. end;
  1235. TfdRGBA8 = class(TfdRGBA_UB4)
  1236. constructor Create; override;
  1237. end;
  1238. TfdRGB10A2 = class(TfdUniversal_UI1)
  1239. constructor Create; override;
  1240. end;
  1241. TfdRGBA12 = class(TfdRGBA_US4)
  1242. constructor Create; override;
  1243. end;
  1244. TfdRGBA16 = class(TfdRGBA_US4)
  1245. constructor Create; override;
  1246. end;
  1247. TfdBGR4 = class(TfdUniversal_US1)
  1248. constructor Create; override;
  1249. end;
  1250. TfdB5G6R5 = class(TfdUniversal_US1)
  1251. constructor Create; override;
  1252. end;
  1253. TfdBGR5 = class(TfdUniversal_US1)
  1254. constructor Create; override;
  1255. end;
  1256. TfdBGR8 = class(TfdBGR_UB3)
  1257. constructor Create; override;
  1258. end;
  1259. TfdBGR10 = class(TfdUniversal_UI1)
  1260. constructor Create; override;
  1261. end;
  1262. TfdBGR12 = class(TfdBGR_US3)
  1263. constructor Create; override;
  1264. end;
  1265. TfdBGR16 = class(TfdBGR_US3)
  1266. constructor Create; override;
  1267. end;
  1268. TfdBGRA2 = class(TfdBGRA_UB4)
  1269. constructor Create; override;
  1270. end;
  1271. TfdBGRA4 = class(TfdUniversal_US1)
  1272. constructor Create; override;
  1273. end;
  1274. TfdBGR5A1 = class(TfdUniversal_US1)
  1275. constructor Create; override;
  1276. end;
  1277. TfdBGRA8 = class(TfdBGRA_UB4)
  1278. constructor Create; override;
  1279. end;
  1280. TfdBGR10A2 = class(TfdUniversal_UI1)
  1281. constructor Create; override;
  1282. end;
  1283. TfdBGRA12 = class(TfdBGRA_US4)
  1284. constructor Create; override;
  1285. end;
  1286. TfdBGRA16 = class(TfdBGRA_US4)
  1287. constructor Create; override;
  1288. end;
  1289. TfdDepth16 = class(TfdDepth_US1)
  1290. constructor Create; override;
  1291. end;
  1292. TfdDepth24 = class(TfdDepth_UI1)
  1293. constructor Create; override;
  1294. end;
  1295. TfdDepth32 = class(TfdDepth_UI1)
  1296. constructor Create; override;
  1297. end;
  1298. TfdS3tcDtx1RGBA = class(TFormatDescriptor)
  1299. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1300. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1301. constructor Create; override;
  1302. end;
  1303. TfdS3tcDtx3RGBA = class(TFormatDescriptor)
  1304. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1305. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1306. constructor Create; override;
  1307. end;
  1308. TfdS3tcDtx5RGBA = class(TFormatDescriptor)
  1309. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1310. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1311. constructor Create; override;
  1312. end;
  1313. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1314. TbmpBitfieldFormat = class(TFormatDescriptor)
  1315. private
  1316. procedure SetRedMask (const aValue: QWord);
  1317. procedure SetGreenMask(const aValue: QWord);
  1318. procedure SetBlueMask (const aValue: QWord);
  1319. procedure SetAlphaMask(const aValue: QWord);
  1320. procedure Update(aMask: QWord; out aRange: Cardinal; out aShift: Byte);
  1321. public
  1322. property RedMask: QWord read GetRedMask write SetRedMask;
  1323. property GreenMask: QWord read GetGreenMask write SetGreenMask;
  1324. property BlueMask: QWord read GetBlueMask write SetBlueMask;
  1325. property AlphaMask: QWord read GetAlphaMask write SetAlphaMask;
  1326. property PixelSize: Single read fPixelSize write fPixelSize;
  1327. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1328. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1329. end;
  1330. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1331. TbmpColorTableEnty = packed record
  1332. b, g, r, a: Byte;
  1333. end;
  1334. TbmpColorTable = array of TbmpColorTableEnty;
  1335. TbmpColorTableFormat = class(TFormatDescriptor)
  1336. private
  1337. fColorTable: TbmpColorTable;
  1338. public
  1339. property PixelSize: Single read fPixelSize write fPixelSize;
  1340. property ColorTable: TbmpColorTable read fColorTable write fColorTable;
  1341. property Range: TglBitmapColorRec read fRange write fRange;
  1342. property Shift: TShiftRec read fShift write fShift;
  1343. property Format: TglBitmapFormat read fFormat write fFormat;
  1344. procedure CreateColorTable;
  1345. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1346. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1347. destructor Destroy; override;
  1348. end;
  1349. const
  1350. LUMINANCE_WEIGHT_R = 0.30;
  1351. LUMINANCE_WEIGHT_G = 0.59;
  1352. LUMINANCE_WEIGHT_B = 0.11;
  1353. ALPHA_WEIGHT_R = 0.30;
  1354. ALPHA_WEIGHT_G = 0.59;
  1355. ALPHA_WEIGHT_B = 0.11;
  1356. DEPTH_WEIGHT_R = 0.333333333;
  1357. DEPTH_WEIGHT_G = 0.333333333;
  1358. DEPTH_WEIGHT_B = 0.333333333;
  1359. UNSUPPORTED_FORMAT = 'the given format isn''t supported by this function.';
  1360. FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
  1361. TfdEmpty,
  1362. TfdAlpha4,
  1363. TfdAlpha8,
  1364. TfdAlpha12,
  1365. TfdAlpha16,
  1366. TfdLuminance4,
  1367. TfdLuminance8,
  1368. TfdLuminance12,
  1369. TfdLuminance16,
  1370. TfdLuminance4Alpha4,
  1371. TfdLuminance6Alpha2,
  1372. TfdLuminance8Alpha8,
  1373. TfdLuminance12Alpha4,
  1374. TfdLuminance12Alpha12,
  1375. TfdLuminance16Alpha16,
  1376. TfdR3G3B2,
  1377. TfdRGB4,
  1378. TfdR5G6B5,
  1379. TfdRGB5,
  1380. TfdRGB8,
  1381. TfdRGB10,
  1382. TfdRGB12,
  1383. TfdRGB16,
  1384. TfdRGBA2,
  1385. TfdRGBA4,
  1386. TfdRGB5A1,
  1387. TfdRGBA8,
  1388. TfdRGB10A2,
  1389. TfdRGBA12,
  1390. TfdRGBA16,
  1391. TfdBGR4,
  1392. TfdB5G6R5,
  1393. TfdBGR5,
  1394. TfdBGR8,
  1395. TfdBGR10,
  1396. TfdBGR12,
  1397. TfdBGR16,
  1398. TfdBGRA2,
  1399. TfdBGRA4,
  1400. TfdBGR5A1,
  1401. TfdBGRA8,
  1402. TfdBGR10A2,
  1403. TfdBGRA12,
  1404. TfdBGRA16,
  1405. TfdDepth16,
  1406. TfdDepth24,
  1407. TfdDepth32,
  1408. TfdS3tcDtx1RGBA,
  1409. TfdS3tcDtx3RGBA,
  1410. TfdS3tcDtx5RGBA
  1411. );
  1412. var
  1413. FormatDescriptorCS: TCriticalSection;
  1414. FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
  1415. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1416. constructor EglBitmapUnsupportedFormat.Create(const aFormat: TglBitmapFormat);
  1417. begin
  1418. inherited Create('unsupported format: ' + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
  1419. end;
  1420. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1421. constructor EglBitmapUnsupportedFormat.Create(const aMsg: String; const aFormat: TglBitmapFormat);
  1422. begin
  1423. inherited Create(aMsg + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
  1424. end;
  1425. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1426. function glBitmapPosition(X, Y: Integer): TglBitmapPixelPosition;
  1427. begin
  1428. result.Fields := [];
  1429. if X >= 0 then
  1430. result.Fields := result.Fields + [ffX];
  1431. if Y >= 0 then
  1432. result.Fields := result.Fields + [ffY];
  1433. result.X := Max(0, X);
  1434. result.Y := Max(0, Y);
  1435. end;
  1436. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1437. function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
  1438. begin
  1439. result.r := r;
  1440. result.g := g;
  1441. result.b := b;
  1442. result.a := a;
  1443. end;
  1444. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1445. function glBitmapColorRecCmp(const r1, r2: TglBitmapColorRec): Boolean;
  1446. var
  1447. i: Integer;
  1448. begin
  1449. result := false;
  1450. for i := 0 to high(r1.arr) do
  1451. if (r1.arr[i] <> r2.arr[i]) then
  1452. exit;
  1453. result := true;
  1454. end;
  1455. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1456. function glBitmapShiftRec(const r, g, b, a: Byte): TShiftRec;
  1457. begin
  1458. result.r := r;
  1459. result.g := g;
  1460. result.b := b;
  1461. result.a := a;
  1462. end;
  1463. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1464. function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
  1465. begin
  1466. result := [];
  1467. if (aFormat in [
  1468. //4 bbp
  1469. tfLuminance4,
  1470. //8bpp
  1471. tfR3G3B2, tfLuminance8,
  1472. //16bpp
  1473. tfRGB4, tfRGB5, tfR5G6B5, tfRGB5A1, tfRGBA4,
  1474. tfBGR4, tfBGR5, tfB5G6R5, tfBGR5A1, tfBGRA4,
  1475. //24bpp
  1476. tfBGR8, tfRGB8,
  1477. //32bpp
  1478. tfRGB10, tfRGB10A2, tfRGBA8,
  1479. tfBGR10, tfBGR10A2, tfBGRA8]) then
  1480. result := result + [ftBMP];
  1481. if (aFormat in [
  1482. //8 bpp
  1483. tfLuminance8, tfAlpha8,
  1484. //16 bpp
  1485. tfLuminance16, tfLuminance8Alpha8,
  1486. tfRGB5, tfRGB5A1, tfRGBA4,
  1487. tfBGR5, tfBGR5A1, tfBGRA4,
  1488. //24 bpp
  1489. tfRGB8, tfBGR8,
  1490. //32 bpp
  1491. tfRGB10A2, tfRGBA8, tfBGR10A2, tfBGRA8]) then
  1492. result := result + [ftTGA];
  1493. if (aFormat in [
  1494. //8 bpp
  1495. tfAlpha8, tfLuminance8, tfLuminance4Alpha4, tfLuminance6Alpha2,
  1496. tfR3G3B2, tfRGBA2, tfBGRA2,
  1497. //16 bpp
  1498. tfAlpha16, tfLuminance16, tfLuminance8Alpha8, tfLuminance12Alpha4,
  1499. tfRGB4, tfR5G6B5, tfRGB5, tfRGBA4, tfRGB5A1,
  1500. tfBGR4, tfB5G6R5, tfBGR5, tfBGRA4, tfBGR5A1,
  1501. //24 bpp
  1502. tfRGB8, tfBGR8,
  1503. //32 bbp
  1504. tfLuminance16Alpha16,
  1505. tfRGBA8, tfRGB10A2,
  1506. tfBGRA8, tfBGR10A2,
  1507. //compressed
  1508. tfS3tcDtx1RGBA, tfS3tcDtx3RGBA, tfS3tcDtx5RGBA]) then
  1509. result := result + [ftDDS];
  1510. {$IFDEF GLB_SUPPORT_PNG_WRITE}
  1511. if aFormat in [
  1512. tfAlpha8, tfLuminance8, tfLuminance8Alpha8,
  1513. tfRGB8, tfRGBA8,
  1514. tfBGR8, tfBGRA8] then
  1515. result := result + [ftPNG];
  1516. {$ENDIF}
  1517. {$IFDEF GLB_SUPPORT_JPEG_WRITE}
  1518. if aFormat in [tfAlpha8, tfLuminance8, tfRGB8, tfBGR8] then
  1519. result := result + [ftJPEG];
  1520. {$ENDIF}
  1521. end;
  1522. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1523. function IsPowerOfTwo(aNumber: Integer): Boolean;
  1524. begin
  1525. while (aNumber and 1) = 0 do
  1526. aNumber := aNumber shr 1;
  1527. result := aNumber = 1;
  1528. end;
  1529. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1530. function GetTopMostBit(aBitSet: QWord): Integer;
  1531. begin
  1532. result := 0;
  1533. while aBitSet > 0 do begin
  1534. inc(result);
  1535. aBitSet := aBitSet shr 1;
  1536. end;
  1537. end;
  1538. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1539. function CountSetBits(aBitSet: QWord): Integer;
  1540. begin
  1541. result := 0;
  1542. while aBitSet > 0 do begin
  1543. if (aBitSet and 1) = 1 then
  1544. inc(result);
  1545. aBitSet := aBitSet shr 1;
  1546. end;
  1547. end;
  1548. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1549. function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
  1550. begin
  1551. result := Trunc(
  1552. LUMINANCE_WEIGHT_R * aPixel.Data.r +
  1553. LUMINANCE_WEIGHT_G * aPixel.Data.g +
  1554. LUMINANCE_WEIGHT_B * aPixel.Data.b);
  1555. end;
  1556. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1557. function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
  1558. begin
  1559. result := Trunc(
  1560. DEPTH_WEIGHT_R * aPixel.Data.r +
  1561. DEPTH_WEIGHT_G * aPixel.Data.g +
  1562. DEPTH_WEIGHT_B * aPixel.Data.b);
  1563. end;
  1564. {$IFDEF GLB_NATIVE_OGL}
  1565. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1566. //OpenGLInitialization///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1567. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1568. var
  1569. GL_LibHandle: Pointer = nil;
  1570. function glbGetProcAddress(aProcName: PChar; aLibHandle: Pointer = nil): Pointer;
  1571. begin
  1572. if not Assigned(aLibHandle) then
  1573. aLibHandle := GL_LibHandle;
  1574. {$IF DEFINED(GLB_WIN)}
  1575. result := GetProcAddress({%H-}HMODULE(aLibHandle), aProcName);
  1576. if Assigned(result) then
  1577. exit;
  1578. if Assigned(wglGetProcAddress) then
  1579. result := wglGetProcAddress(aProcName);
  1580. {$ELSEIF DEFINED(GLB_LINUX)}
  1581. if Assigned(glXGetProcAddress) then begin
  1582. result := glXGetProcAddress(aProcName);
  1583. if Assigned(result) then
  1584. exit;
  1585. end;
  1586. if Assigned(glXGetProcAddressARB) then begin
  1587. result := glXGetProcAddressARB(aProcName);
  1588. if Assigned(result) then
  1589. exit;
  1590. end;
  1591. result := dlsym(aLibHandle, aProcName);
  1592. {$IFEND}
  1593. if not Assigned(result) then
  1594. raise EglBitmap.Create('unable to load procedure form library: ' + aProcName);
  1595. end;
  1596. {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
  1597. var
  1598. GLU_LibHandle: Pointer = nil;
  1599. OpenGLInitialized: Boolean;
  1600. InitOpenGLCS: TCriticalSection;
  1601. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1602. procedure glbInitOpenGL;
  1603. ////////////////////////////////////////////////////////////////////////////////
  1604. function glbLoadLibrary(const aName: PChar): Pointer;
  1605. begin
  1606. {$IF DEFINED(GLB_WIN)}
  1607. result := {%H-}Pointer(LoadLibrary(aName));
  1608. {$ELSEIF DEFINED(GLB_LINUX)}
  1609. result := dlopen(Name, RTLD_LAZY);
  1610. {$ELSE}
  1611. result := nil;
  1612. {$IFEND}
  1613. end;
  1614. ////////////////////////////////////////////////////////////////////////////////
  1615. function glbFreeLibrary(const aLibHandle: Pointer): Boolean;
  1616. begin
  1617. result := false;
  1618. if not Assigned(aLibHandle) then
  1619. exit;
  1620. {$IF DEFINED(GLB_WIN)}
  1621. Result := FreeLibrary({%H-}HINST(aLibHandle));
  1622. {$ELSEIF DEFINED(GLB_LINUX)}
  1623. Result := dlclose(aLibHandle) = 0;
  1624. {$IFEND}
  1625. end;
  1626. begin
  1627. if Assigned(GL_LibHandle) then
  1628. glbFreeLibrary(GL_LibHandle);
  1629. if Assigned(GLU_LibHandle) then
  1630. glbFreeLibrary(GLU_LibHandle);
  1631. GL_LibHandle := glbLoadLibrary(libopengl);
  1632. if not Assigned(GL_LibHandle) then
  1633. raise EglBitmap.Create('unable to load library: ' + libopengl);
  1634. GLU_LibHandle := glbLoadLibrary(libglu);
  1635. if not Assigned(GLU_LibHandle) then
  1636. raise EglBitmap.Create('unable to load library: ' + libglu);
  1637. try
  1638. {$IF DEFINED(GLB_WIN)}
  1639. wglGetProcAddress := glbGetProcAddress('wglGetProcAddress');
  1640. {$ELSEIF DEFINED(GLB_LINUX)}
  1641. glXGetProcAddress := glbGetProcAddress('glXGetProcAddress');
  1642. glXGetProcAddressARB := glbGetProcAddress('glXGetProcAddressARB');
  1643. {$IFEND}
  1644. glEnable := glbGetProcAddress('glEnable');
  1645. glDisable := glbGetProcAddress('glDisable');
  1646. glGetString := glbGetProcAddress('glGetString');
  1647. glGetIntegerv := glbGetProcAddress('glGetIntegerv');
  1648. glTexParameteri := glbGetProcAddress('glTexParameteri');
  1649. glTexParameteriv := glbGetProcAddress('glTexParameteriv');
  1650. glTexParameterfv := glbGetProcAddress('glTexParameterfv');
  1651. glGetTexParameteriv := glbGetProcAddress('glGetTexParameteriv');
  1652. glGetTexParameterfv := glbGetProcAddress('glGetTexParameterfv');
  1653. glGetTexLevelParameteriv := glbGetProcAddress('glGetTexLevelParameteriv');
  1654. glGetTexLevelParameterfv := glbGetProcAddress('glGetTexLevelParameterfv');
  1655. glTexGeni := glbGetProcAddress('glTexGeni');
  1656. glGenTextures := glbGetProcAddress('glGenTextures');
  1657. glBindTexture := glbGetProcAddress('glBindTexture');
  1658. glDeleteTextures := glbGetProcAddress('glDeleteTextures');
  1659. glAreTexturesResident := glbGetProcAddress('glAreTexturesResident');
  1660. glReadPixels := glbGetProcAddress('glReadPixels');
  1661. glPixelStorei := glbGetProcAddress('glPixelStorei');
  1662. glTexImage1D := glbGetProcAddress('glTexImage1D');
  1663. glTexImage2D := glbGetProcAddress('glTexImage2D');
  1664. glGetTexImage := glbGetProcAddress('glGetTexImage');
  1665. gluBuild1DMipmaps := glbGetProcAddress('gluBuild1DMipmaps', GLU_LibHandle);
  1666. gluBuild2DMipmaps := glbGetProcAddress('gluBuild2DMipmaps', GLU_LibHandle);
  1667. finally
  1668. glbFreeLibrary(GL_LibHandle);
  1669. glbFreeLibrary(GLU_LibHandle);
  1670. end;
  1671. end;
  1672. {$ENDIF}
  1673. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1674. procedure glbReadOpenGLExtensions;
  1675. var
  1676. Buffer: AnsiString;
  1677. MajorVersion, MinorVersion: Integer;
  1678. ///////////////////////////////////////////////////////////////////////////////////////////
  1679. procedure TrimVersionString(aBuffer: AnsiString; out aMajor, aMinor: Integer);
  1680. var
  1681. Separator: Integer;
  1682. begin
  1683. aMinor := 0;
  1684. aMajor := 0;
  1685. Separator := Pos(AnsiString('.'), aBuffer);
  1686. if (Separator > 1) and (Separator < Length(aBuffer)) and
  1687. (aBuffer[Separator - 1] in ['0'..'9']) and
  1688. (aBuffer[Separator + 1] in ['0'..'9']) then begin
  1689. Dec(Separator);
  1690. while (Separator > 0) and (aBuffer[Separator] in ['0'..'9']) do
  1691. Dec(Separator);
  1692. Delete(aBuffer, 1, Separator);
  1693. Separator := Pos(AnsiString('.'), aBuffer) + 1;
  1694. while (Separator <= Length(aBuffer)) and (AnsiChar(aBuffer[Separator]) in ['0'..'9']) do
  1695. Inc(Separator);
  1696. Delete(aBuffer, Separator, 255);
  1697. Separator := Pos(AnsiString('.'), aBuffer);
  1698. aMajor := StrToInt(Copy(String(aBuffer), 1, Separator - 1));
  1699. aMinor := StrToInt(Copy(String(aBuffer), Separator + 1, 1));
  1700. end;
  1701. end;
  1702. ///////////////////////////////////////////////////////////////////////////////////////////
  1703. function CheckExtension(const Extension: AnsiString): Boolean;
  1704. var
  1705. ExtPos: Integer;
  1706. begin
  1707. ExtPos := Pos(Extension, Buffer);
  1708. result := ExtPos > 0;
  1709. if result then
  1710. result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
  1711. end;
  1712. ///////////////////////////////////////////////////////////////////////////////////////////
  1713. function CheckVersion(const aMajor, aMinor: Integer): Boolean;
  1714. begin
  1715. result := (MajorVersion > aMajor) or ((MajorVersion = aMajor) and (MinorVersion >= aMinor));
  1716. end;
  1717. begin
  1718. {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
  1719. InitOpenGLCS.Enter;
  1720. try
  1721. if not OpenGLInitialized then begin
  1722. glbInitOpenGL;
  1723. OpenGLInitialized := true;
  1724. end;
  1725. finally
  1726. InitOpenGLCS.Leave;
  1727. end;
  1728. {$ENDIF}
  1729. // Version
  1730. Buffer := glGetString(GL_VERSION);
  1731. TrimVersionString(Buffer, MajorVersion, MinorVersion);
  1732. GL_VERSION_1_2 := CheckVersion(1, 2);
  1733. GL_VERSION_1_3 := CheckVersion(1, 3);
  1734. GL_VERSION_1_4 := CheckVersion(1, 4);
  1735. GL_VERSION_2_0 := CheckVersion(2, 0);
  1736. GL_VERSION_3_3 := CheckVersion(3, 3);
  1737. // Extensions
  1738. Buffer := glGetString(GL_EXTENSIONS);
  1739. GL_ARB_texture_border_clamp := CheckExtension('GL_ARB_texture_border_clamp');
  1740. GL_ARB_texture_non_power_of_two := CheckExtension('GL_ARB_texture_non_power_of_two');
  1741. GL_ARB_texture_swizzle := CheckExtension('GL_ARB_texture_swizzle');
  1742. GL_ARB_texture_cube_map := CheckExtension('GL_ARB_texture_cube_map');
  1743. GL_ARB_texture_rectangle := CheckExtension('GL_ARB_texture_rectangle');
  1744. GL_ARB_texture_mirrored_repeat := CheckExtension('GL_ARB_texture_mirrored_repeat');
  1745. GL_EXT_texture_edge_clamp := CheckExtension('GL_EXT_texture_edge_clamp');
  1746. GL_EXT_texture_filter_anisotropic := CheckExtension('GL_EXT_texture_filter_anisotropic');
  1747. GL_EXT_texture_rectangle := CheckExtension('GL_EXT_texture_rectangle');
  1748. GL_EXT_texture_swizzle := CheckExtension('GL_EXT_texture_swizzle');
  1749. GL_EXT_texture_cube_map := CheckExtension('GL_EXT_texture_cube_map');
  1750. GL_NV_texture_rectangle := CheckExtension('GL_NV_texture_rectangle');
  1751. GL_IBM_texture_mirrored_repeat := CheckExtension('GL_IBM_texture_mirrored_repeat');
  1752. GL_SGIS_generate_mipmap := CheckExtension('GL_SGIS_generate_mipmap');
  1753. if GL_VERSION_1_3 then begin
  1754. glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1D');
  1755. glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2D');
  1756. glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImage');
  1757. end else begin
  1758. glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1DARB');
  1759. glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2DARB');
  1760. glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImageARB');
  1761. end;
  1762. end;
  1763. {$ENDIF}
  1764. {$IFDEF GLB_SDL_IMAGE}
  1765. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1766. // SDL Image Helper /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1767. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1768. function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
  1769. begin
  1770. result := TStream(context^.unknown.data1).Seek(offset, whence);
  1771. end;
  1772. function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
  1773. begin
  1774. result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
  1775. end;
  1776. function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
  1777. begin
  1778. result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
  1779. end;
  1780. function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
  1781. begin
  1782. result := 0;
  1783. end;
  1784. function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
  1785. begin
  1786. result := SDL_AllocRW;
  1787. if result = nil then
  1788. raise EglBitmapException.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
  1789. result^.seek := glBitmapRWseek;
  1790. result^.read := glBitmapRWread;
  1791. result^.write := glBitmapRWwrite;
  1792. result^.close := glBitmapRWclose;
  1793. result^.unknown.data1 := Stream;
  1794. end;
  1795. {$ENDIF}
  1796. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1797. procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
  1798. begin
  1799. glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
  1800. end;
  1801. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1802. procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
  1803. begin
  1804. glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
  1805. end;
  1806. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1807. procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
  1808. begin
  1809. glBitmapDefaultMipmap := aValue;
  1810. end;
  1811. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1812. procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
  1813. begin
  1814. glBitmapDefaultFormat := aFormat;
  1815. end;
  1816. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1817. procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
  1818. begin
  1819. glBitmapDefaultFilterMin := aMin;
  1820. glBitmapDefaultFilterMag := aMag;
  1821. end;
  1822. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1823. procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
  1824. begin
  1825. glBitmapDefaultWrapS := S;
  1826. glBitmapDefaultWrapT := T;
  1827. glBitmapDefaultWrapR := R;
  1828. end;
  1829. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1830. procedure glBitmapSetDefaultSwizzle(const r: GLenum = GL_RED; g: GLenum = GL_GREEN; b: GLenum = GL_BLUE; a: GLenum = GL_ALPHA);
  1831. begin
  1832. glDefaultSwizzle[0] := r;
  1833. glDefaultSwizzle[1] := g;
  1834. glDefaultSwizzle[2] := b;
  1835. glDefaultSwizzle[3] := a;
  1836. end;
  1837. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1838. function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
  1839. begin
  1840. result := glBitmapDefaultDeleteTextureOnFree;
  1841. end;
  1842. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1843. function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
  1844. begin
  1845. result := glBitmapDefaultFreeDataAfterGenTextures;
  1846. end;
  1847. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1848. function glBitmapGetDefaultMipmap: TglBitmapMipMap;
  1849. begin
  1850. result := glBitmapDefaultMipmap;
  1851. end;
  1852. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1853. function glBitmapGetDefaultFormat: TglBitmapFormat;
  1854. begin
  1855. result := glBitmapDefaultFormat;
  1856. end;
  1857. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1858. procedure glBitmapGetDefaultFilter(var aMin, aMag: GLenum);
  1859. begin
  1860. aMin := glBitmapDefaultFilterMin;
  1861. aMag := glBitmapDefaultFilterMag;
  1862. end;
  1863. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1864. procedure glBitmapGetDefaultTextureWrap(var S, T, R: GLenum);
  1865. begin
  1866. S := glBitmapDefaultWrapS;
  1867. T := glBitmapDefaultWrapT;
  1868. R := glBitmapDefaultWrapR;
  1869. end;
  1870. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1871. procedure glBitmapGetDefaultSwizzle(var r, g, b, a: GLenum);
  1872. begin
  1873. r := glDefaultSwizzle[0];
  1874. g := glDefaultSwizzle[1];
  1875. b := glDefaultSwizzle[2];
  1876. a := glDefaultSwizzle[3];
  1877. end;
  1878. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1879. //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1880. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1881. function TFormatDescriptor.GetRedMask: QWord;
  1882. begin
  1883. result := fRange.r shl fShift.r;
  1884. end;
  1885. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1886. function TFormatDescriptor.GetGreenMask: QWord;
  1887. begin
  1888. result := fRange.g shl fShift.g;
  1889. end;
  1890. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1891. function TFormatDescriptor.GetBlueMask: QWord;
  1892. begin
  1893. result := fRange.b shl fShift.b;
  1894. end;
  1895. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1896. function TFormatDescriptor.GetAlphaMask: QWord;
  1897. begin
  1898. result := fRange.a shl fShift.a;
  1899. end;
  1900. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1901. function TFormatDescriptor.GetIsCompressed: Boolean;
  1902. begin
  1903. result := fIsCompressed;
  1904. end;
  1905. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1906. function TFormatDescriptor.GetHasAlpha: Boolean;
  1907. begin
  1908. result := (fRange.a > 0);
  1909. end;
  1910. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1911. function TFormatDescriptor.GetglFormat: GLenum;
  1912. begin
  1913. result := fglFormat;
  1914. end;
  1915. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1916. function TFormatDescriptor.GetglInternalFormat: GLenum;
  1917. begin
  1918. result := fglInternalFormat;
  1919. end;
  1920. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1921. function TFormatDescriptor.GetglDataFormat: GLenum;
  1922. begin
  1923. result := fglDataFormat;
  1924. end;
  1925. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1926. function TFormatDescriptor.GetComponents: Integer;
  1927. var
  1928. i: Integer;
  1929. begin
  1930. result := 0;
  1931. for i := 0 to 3 do
  1932. if (fRange.arr[i] > 0) then
  1933. inc(result);
  1934. end;
  1935. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1936. function TFormatDescriptor.GetSize(const aSize: TglBitmapPixelPosition): Integer;
  1937. var
  1938. w, h: Integer;
  1939. begin
  1940. if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
  1941. w := Max(1, aSize.X);
  1942. h := Max(1, aSize.Y);
  1943. result := GetSize(w, h);
  1944. end else
  1945. result := 0;
  1946. end;
  1947. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1948. function TFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer;
  1949. begin
  1950. result := 0;
  1951. if (aWidth <= 0) or (aHeight <= 0) then
  1952. exit;
  1953. result := Ceil(aWidth * aHeight * fPixelSize);
  1954. end;
  1955. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1956. function TFormatDescriptor.CreateMappingData: Pointer;
  1957. begin
  1958. result := nil;
  1959. end;
  1960. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1961. procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
  1962. begin
  1963. //DUMMY
  1964. end;
  1965. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1966. function TFormatDescriptor.IsEmpty: Boolean;
  1967. begin
  1968. result := (fFormat = tfEmpty);
  1969. end;
  1970. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1971. function TFormatDescriptor.MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: QWord): Boolean;
  1972. begin
  1973. result := false;
  1974. if (aRedMask = 0) and (aGreenMask = 0) and (aBlueMask = 0) and (aAlphaMask = 0) then
  1975. raise EglBitmap.Create('FormatCheckFormat - All Masks are 0');
  1976. if (aRedMask <> RedMask) then
  1977. exit;
  1978. if (aGreenMask <> GreenMask) then
  1979. exit;
  1980. if (aBlueMask <> BlueMask) then
  1981. exit;
  1982. if (aAlphaMask <> AlphaMask) then
  1983. exit;
  1984. result := true;
  1985. end;
  1986. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1987. procedure TFormatDescriptor.PreparePixel(out aPixel: TglBitmapPixelData);
  1988. begin
  1989. FillChar(aPixel{%H-}, SizeOf(aPixel), 0);
  1990. aPixel.Data := fRange;
  1991. aPixel.Range := fRange;
  1992. aPixel.Format := fFormat;
  1993. end;
  1994. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1995. constructor TFormatDescriptor.Create;
  1996. begin
  1997. inherited Create;
  1998. fFormat := tfEmpty;
  1999. fWithAlpha := tfEmpty;
  2000. fWithoutAlpha := tfEmpty;
  2001. fRGBInverted := tfEmpty;
  2002. fUncompressed := tfEmpty;
  2003. fPixelSize := 0.0;
  2004. fIsCompressed := false;
  2005. fglFormat := 0;
  2006. fglInternalFormat := 0;
  2007. fglDataFormat := 0;
  2008. FillChar(fRange, 0, SizeOf(fRange));
  2009. FillChar(fShift, 0, SizeOf(fShift));
  2010. end;
  2011. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2012. //TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2013. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2014. procedure TfdAlpha_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2015. begin
  2016. aData^ := aPixel.Data.a;
  2017. inc(aData);
  2018. end;
  2019. procedure TfdAlpha_UB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2020. begin
  2021. aPixel.Data.r := 0;
  2022. aPixel.Data.g := 0;
  2023. aPixel.Data.b := 0;
  2024. aPixel.Data.a := aData^;
  2025. inc(aData);
  2026. end;
  2027. constructor TfdAlpha_UB1.Create;
  2028. begin
  2029. inherited Create;
  2030. fPixelSize := 1.0;
  2031. fRange.a := $FF;
  2032. fglFormat := GL_ALPHA;
  2033. fglDataFormat := GL_UNSIGNED_BYTE;
  2034. end;
  2035. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2036. //TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2037. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2038. procedure TfdLuminance_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2039. begin
  2040. aData^ := LuminanceWeight(aPixel);
  2041. inc(aData);
  2042. end;
  2043. procedure TfdLuminance_UB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2044. begin
  2045. aPixel.Data.r := aData^;
  2046. aPixel.Data.g := aData^;
  2047. aPixel.Data.b := aData^;
  2048. aPixel.Data.a := 0;
  2049. inc(aData);
  2050. end;
  2051. constructor TfdLuminance_UB1.Create;
  2052. begin
  2053. inherited Create;
  2054. fPixelSize := 1.0;
  2055. fRange.r := $FF;
  2056. fRange.g := $FF;
  2057. fRange.b := $FF;
  2058. fglFormat := GL_LUMINANCE;
  2059. fglDataFormat := GL_UNSIGNED_BYTE;
  2060. end;
  2061. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2062. //TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2063. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2064. procedure TfdUniversal_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2065. var
  2066. i: Integer;
  2067. begin
  2068. aData^ := 0;
  2069. for i := 0 to 3 do
  2070. if (fRange.arr[i] > 0) then
  2071. aData^ := aData^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
  2072. inc(aData);
  2073. end;
  2074. procedure TfdUniversal_UB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2075. var
  2076. i: Integer;
  2077. begin
  2078. for i := 0 to 3 do
  2079. aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and fRange.arr[i];
  2080. inc(aData);
  2081. end;
  2082. constructor TfdUniversal_UB1.Create;
  2083. begin
  2084. inherited Create;
  2085. fPixelSize := 1.0;
  2086. end;
  2087. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2088. //TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2089. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2090. procedure TfdLuminanceAlpha_UB2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2091. begin
  2092. inherited Map(aPixel, aData, aMapData);
  2093. aData^ := aPixel.Data.a;
  2094. inc(aData);
  2095. end;
  2096. procedure TfdLuminanceAlpha_UB2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2097. begin
  2098. inherited Unmap(aData, aPixel, aMapData);
  2099. aPixel.Data.a := aData^;
  2100. inc(aData);
  2101. end;
  2102. constructor TfdLuminanceAlpha_UB2.Create;
  2103. begin
  2104. inherited Create;
  2105. fPixelSize := 2.0;
  2106. fRange.a := $FF;
  2107. fShift.a := 8;
  2108. fglFormat := GL_LUMINANCE_ALPHA;
  2109. fglDataFormat := GL_UNSIGNED_BYTE;
  2110. end;
  2111. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2112. //TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2113. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2114. procedure TfdRGB_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2115. begin
  2116. aData^ := aPixel.Data.r;
  2117. inc(aData);
  2118. aData^ := aPixel.Data.g;
  2119. inc(aData);
  2120. aData^ := aPixel.Data.b;
  2121. inc(aData);
  2122. end;
  2123. procedure TfdRGB_UB3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2124. begin
  2125. aPixel.Data.r := aData^;
  2126. inc(aData);
  2127. aPixel.Data.g := aData^;
  2128. inc(aData);
  2129. aPixel.Data.b := aData^;
  2130. inc(aData);
  2131. aPixel.Data.a := 0;
  2132. end;
  2133. constructor TfdRGB_UB3.Create;
  2134. begin
  2135. inherited Create;
  2136. fPixelSize := 3.0;
  2137. fRange.r := $FF;
  2138. fRange.g := $FF;
  2139. fRange.b := $FF;
  2140. fShift.r := 0;
  2141. fShift.g := 8;
  2142. fShift.b := 16;
  2143. fglFormat := GL_RGB;
  2144. fglDataFormat := GL_UNSIGNED_BYTE;
  2145. end;
  2146. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2147. //TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2148. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2149. procedure TfdBGR_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2150. begin
  2151. aData^ := aPixel.Data.b;
  2152. inc(aData);
  2153. aData^ := aPixel.Data.g;
  2154. inc(aData);
  2155. aData^ := aPixel.Data.r;
  2156. inc(aData);
  2157. end;
  2158. procedure TfdBGR_UB3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2159. begin
  2160. aPixel.Data.b := aData^;
  2161. inc(aData);
  2162. aPixel.Data.g := aData^;
  2163. inc(aData);
  2164. aPixel.Data.r := aData^;
  2165. inc(aData);
  2166. aPixel.Data.a := 0;
  2167. end;
  2168. constructor TfdBGR_UB3.Create;
  2169. begin
  2170. fPixelSize := 3.0;
  2171. fRange.r := $FF;
  2172. fRange.g := $FF;
  2173. fRange.b := $FF;
  2174. fShift.r := 16;
  2175. fShift.g := 8;
  2176. fShift.b := 0;
  2177. fglFormat := GL_BGR;
  2178. fglDataFormat := GL_UNSIGNED_BYTE;
  2179. end;
  2180. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2181. //TdfRGBA_UB4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2182. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2183. procedure TfdRGBA_UB4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2184. begin
  2185. inherited Map(aPixel, aData, aMapData);
  2186. aData^ := aPixel.Data.a;
  2187. inc(aData);
  2188. end;
  2189. procedure TfdRGBA_UB4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2190. begin
  2191. inherited Unmap(aData, aPixel, aMapData);
  2192. aPixel.Data.a := aData^;
  2193. inc(aData);
  2194. end;
  2195. constructor TfdRGBA_UB4.Create;
  2196. begin
  2197. inherited Create;
  2198. fPixelSize := 4.0;
  2199. fRange.a := $FF;
  2200. fShift.a := 24;
  2201. fglFormat := GL_RGBA;
  2202. fglDataFormat := GL_UNSIGNED_BYTE;
  2203. end;
  2204. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2205. //TfdBGRA_UB4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2206. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2207. procedure TfdBGRA_UB4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2208. begin
  2209. inherited Map(aPixel, aData, aMapData);
  2210. aData^ := aPixel.Data.a;
  2211. inc(aData);
  2212. end;
  2213. procedure TfdBGRA_UB4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2214. begin
  2215. inherited Unmap(aData, aPixel, aMapData);
  2216. aPixel.Data.a := aData^;
  2217. inc(aData);
  2218. end;
  2219. constructor TfdBGRA_UB4.Create;
  2220. begin
  2221. inherited Create;
  2222. fPixelSize := 4.0;
  2223. fRange.a := $FF;
  2224. fShift.a := 24;
  2225. fglFormat := GL_BGRA;
  2226. fglDataFormat := GL_UNSIGNED_BYTE;
  2227. end;
  2228. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2229. //TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2230. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2231. procedure TfdAlpha_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2232. begin
  2233. PWord(aData)^ := aPixel.Data.a;
  2234. inc(aData, 2);
  2235. end;
  2236. procedure TfdAlpha_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2237. begin
  2238. aPixel.Data.r := 0;
  2239. aPixel.Data.g := 0;
  2240. aPixel.Data.b := 0;
  2241. aPixel.Data.a := PWord(aData)^;
  2242. inc(aData, 2);
  2243. end;
  2244. constructor TfdAlpha_US1.Create;
  2245. begin
  2246. inherited Create;
  2247. fPixelSize := 2.0;
  2248. fRange.a := $FFFF;
  2249. fglFormat := GL_ALPHA;
  2250. fglDataFormat := GL_UNSIGNED_SHORT;
  2251. end;
  2252. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2253. //TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2254. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2255. procedure TfdLuminance_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2256. begin
  2257. PWord(aData)^ := LuminanceWeight(aPixel);
  2258. inc(aData, 2);
  2259. end;
  2260. procedure TfdLuminance_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2261. begin
  2262. aPixel.Data.r := PWord(aData)^;
  2263. aPixel.Data.g := PWord(aData)^;
  2264. aPixel.Data.b := PWord(aData)^;
  2265. aPixel.Data.a := 0;
  2266. inc(aData, 2);
  2267. end;
  2268. constructor TfdLuminance_US1.Create;
  2269. begin
  2270. inherited Create;
  2271. fPixelSize := 2.0;
  2272. fRange.r := $FFFF;
  2273. fRange.g := $FFFF;
  2274. fRange.b := $FFFF;
  2275. fglFormat := GL_LUMINANCE;
  2276. fglDataFormat := GL_UNSIGNED_SHORT;
  2277. end;
  2278. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2279. //TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2280. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2281. procedure TfdUniversal_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2282. var
  2283. i: Integer;
  2284. begin
  2285. PWord(aData)^ := 0;
  2286. for i := 0 to 3 do
  2287. if (fRange.arr[i] > 0) then
  2288. PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
  2289. inc(aData, 2);
  2290. end;
  2291. procedure TfdUniversal_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2292. var
  2293. i: Integer;
  2294. begin
  2295. for i := 0 to 3 do
  2296. aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and fRange.arr[i];
  2297. inc(aData, 2);
  2298. end;
  2299. constructor TfdUniversal_US1.Create;
  2300. begin
  2301. inherited Create;
  2302. fPixelSize := 2.0;
  2303. end;
  2304. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2305. //TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2306. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2307. procedure TfdDepth_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2308. begin
  2309. PWord(aData)^ := DepthWeight(aPixel);
  2310. inc(aData, 2);
  2311. end;
  2312. procedure TfdDepth_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2313. begin
  2314. aPixel.Data.r := PWord(aData)^;
  2315. aPixel.Data.g := PWord(aData)^;
  2316. aPixel.Data.b := PWord(aData)^;
  2317. aPixel.Data.a := 0;
  2318. inc(aData, 2);
  2319. end;
  2320. constructor TfdDepth_US1.Create;
  2321. begin
  2322. inherited Create;
  2323. fPixelSize := 2.0;
  2324. fRange.r := $FFFF;
  2325. fRange.g := $FFFF;
  2326. fRange.b := $FFFF;
  2327. fglFormat := GL_DEPTH_COMPONENT;
  2328. fglDataFormat := GL_UNSIGNED_SHORT;
  2329. end;
  2330. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2331. //TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2332. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2333. procedure TfdLuminanceAlpha_US2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2334. begin
  2335. inherited Map(aPixel, aData, aMapData);
  2336. PWord(aData)^ := aPixel.Data.a;
  2337. inc(aData, 2);
  2338. end;
  2339. procedure TfdLuminanceAlpha_US2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2340. begin
  2341. inherited Unmap(aData, aPixel, aMapData);
  2342. aPixel.Data.a := PWord(aData)^;
  2343. inc(aData, 2);
  2344. end;
  2345. constructor TfdLuminanceAlpha_US2.Create;
  2346. begin
  2347. inherited Create;
  2348. fPixelSize := 4.0;
  2349. fRange.a := $FFFF;
  2350. fShift.a := 16;
  2351. fglFormat := GL_LUMINANCE_ALPHA;
  2352. fglDataFormat := GL_UNSIGNED_SHORT;
  2353. end;
  2354. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2355. //TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2356. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2357. procedure TfdRGB_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2358. begin
  2359. PWord(aData)^ := aPixel.Data.r;
  2360. inc(aData, 2);
  2361. PWord(aData)^ := aPixel.Data.g;
  2362. inc(aData, 2);
  2363. PWord(aData)^ := aPixel.Data.b;
  2364. inc(aData, 2);
  2365. end;
  2366. procedure TfdRGB_US3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2367. begin
  2368. aPixel.Data.r := PWord(aData)^;
  2369. inc(aData, 2);
  2370. aPixel.Data.g := PWord(aData)^;
  2371. inc(aData, 2);
  2372. aPixel.Data.b := PWord(aData)^;
  2373. inc(aData, 2);
  2374. aPixel.Data.a := 0;
  2375. end;
  2376. constructor TfdRGB_US3.Create;
  2377. begin
  2378. inherited Create;
  2379. fPixelSize := 6.0;
  2380. fRange.r := $FFFF;
  2381. fRange.g := $FFFF;
  2382. fRange.b := $FFFF;
  2383. fShift.r := 0;
  2384. fShift.g := 16;
  2385. fShift.b := 32;
  2386. fglFormat := GL_RGB;
  2387. fglDataFormat := GL_UNSIGNED_SHORT;
  2388. end;
  2389. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2390. //TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2391. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2392. procedure TfdBGR_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2393. begin
  2394. PWord(aData)^ := aPixel.Data.b;
  2395. inc(aData, 2);
  2396. PWord(aData)^ := aPixel.Data.g;
  2397. inc(aData, 2);
  2398. PWord(aData)^ := aPixel.Data.r;
  2399. inc(aData, 2);
  2400. end;
  2401. procedure TfdBGR_US3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2402. begin
  2403. aPixel.Data.b := PWord(aData)^;
  2404. inc(aData, 2);
  2405. aPixel.Data.g := PWord(aData)^;
  2406. inc(aData, 2);
  2407. aPixel.Data.r := PWord(aData)^;
  2408. inc(aData, 2);
  2409. aPixel.Data.a := 0;
  2410. end;
  2411. constructor TfdBGR_US3.Create;
  2412. begin
  2413. inherited Create;
  2414. fPixelSize := 6.0;
  2415. fRange.r := $FFFF;
  2416. fRange.g := $FFFF;
  2417. fRange.b := $FFFF;
  2418. fShift.r := 32;
  2419. fShift.g := 16;
  2420. fShift.b := 0;
  2421. fglFormat := GL_BGR;
  2422. fglDataFormat := GL_UNSIGNED_SHORT;
  2423. end;
  2424. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2425. //TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2426. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2427. procedure TfdRGBA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2428. begin
  2429. inherited Map(aPixel, aData, aMapData);
  2430. PWord(aData)^ := aPixel.Data.a;
  2431. inc(aData, 2);
  2432. end;
  2433. procedure TfdRGBA_US4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2434. begin
  2435. inherited Unmap(aData, aPixel, aMapData);
  2436. aPixel.Data.a := PWord(aData)^;
  2437. inc(aData, 2);
  2438. end;
  2439. constructor TfdRGBA_US4.Create;
  2440. begin
  2441. inherited Create;
  2442. fPixelSize := 8.0;
  2443. fRange.a := $FFFF;
  2444. fShift.a := 48;
  2445. fglFormat := GL_RGBA;
  2446. fglDataFormat := GL_UNSIGNED_SHORT;
  2447. end;
  2448. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2449. //TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2450. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2451. procedure TfdBGRA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2452. begin
  2453. inherited Map(aPixel, aData, aMapData);
  2454. PWord(aData)^ := aPixel.Data.a;
  2455. inc(aData, 2);
  2456. end;
  2457. procedure TfdBGRA_US4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2458. begin
  2459. inherited Unmap(aData, aPixel, aMapData);
  2460. aPixel.Data.a := PWord(aData)^;
  2461. inc(aData, 2);
  2462. end;
  2463. constructor TfdBGRA_US4.Create;
  2464. begin
  2465. inherited Create;
  2466. fPixelSize := 8.0;
  2467. fRange.a := $FFFF;
  2468. fShift.a := 48;
  2469. fglFormat := GL_BGRA;
  2470. fglDataFormat := GL_UNSIGNED_SHORT;
  2471. end;
  2472. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2473. //TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2474. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2475. procedure TfdUniversal_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2476. var
  2477. i: Integer;
  2478. begin
  2479. PCardinal(aData)^ := 0;
  2480. for i := 0 to 3 do
  2481. if (fRange.arr[i] > 0) then
  2482. PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
  2483. inc(aData, 4);
  2484. end;
  2485. procedure TfdUniversal_UI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2486. var
  2487. i: Integer;
  2488. begin
  2489. for i := 0 to 3 do
  2490. aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and fRange.arr[i];
  2491. inc(aData, 2);
  2492. end;
  2493. constructor TfdUniversal_UI1.Create;
  2494. begin
  2495. inherited Create;
  2496. fPixelSize := 4.0;
  2497. end;
  2498. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2499. //TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2500. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2501. procedure TfdDepth_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2502. begin
  2503. PCardinal(aData)^ := DepthWeight(aPixel);
  2504. inc(aData, 4);
  2505. end;
  2506. procedure TfdDepth_UI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2507. begin
  2508. aPixel.Data.r := PCardinal(aData)^;
  2509. aPixel.Data.g := PCardinal(aData)^;
  2510. aPixel.Data.b := PCardinal(aData)^;
  2511. aPixel.Data.a := 0;
  2512. inc(aData, 4);
  2513. end;
  2514. constructor TfdDepth_UI1.Create;
  2515. begin
  2516. inherited Create;
  2517. fPixelSize := 4.0;
  2518. fRange.r := $FFFFFFFF;
  2519. fRange.g := $FFFFFFFF;
  2520. fRange.b := $FFFFFFFF;
  2521. fglFormat := GL_DEPTH_COMPONENT;
  2522. fglDataFormat := GL_UNSIGNED_INT;
  2523. end;
  2524. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2525. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2526. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2527. constructor TfdAlpha4.Create;
  2528. begin
  2529. inherited Create;
  2530. fFormat := tfAlpha4;
  2531. fWithAlpha := tfAlpha4;
  2532. fglInternalFormat := GL_ALPHA4;
  2533. end;
  2534. constructor TfdAlpha8.Create;
  2535. begin
  2536. inherited Create;
  2537. fFormat := tfAlpha8;
  2538. fWithAlpha := tfAlpha8;
  2539. fglInternalFormat := GL_ALPHA8;
  2540. end;
  2541. constructor TfdAlpha12.Create;
  2542. begin
  2543. inherited Create;
  2544. fFormat := tfAlpha12;
  2545. fWithAlpha := tfAlpha12;
  2546. fglInternalFormat := GL_ALPHA12;
  2547. end;
  2548. constructor TfdAlpha16.Create;
  2549. begin
  2550. inherited Create;
  2551. fFormat := tfAlpha16;
  2552. fWithAlpha := tfAlpha16;
  2553. fglInternalFormat := GL_ALPHA16;
  2554. end;
  2555. constructor TfdLuminance4.Create;
  2556. begin
  2557. inherited Create;
  2558. fFormat := tfLuminance4;
  2559. fWithAlpha := tfLuminance4Alpha4;
  2560. fWithoutAlpha := tfLuminance4;
  2561. fglInternalFormat := GL_LUMINANCE4;
  2562. end;
  2563. constructor TfdLuminance8.Create;
  2564. begin
  2565. inherited Create;
  2566. fFormat := tfLuminance8;
  2567. fWithAlpha := tfLuminance8Alpha8;
  2568. fWithoutAlpha := tfLuminance8;
  2569. fglInternalFormat := GL_LUMINANCE8;
  2570. end;
  2571. constructor TfdLuminance12.Create;
  2572. begin
  2573. inherited Create;
  2574. fFormat := tfLuminance12;
  2575. fWithAlpha := tfLuminance12Alpha12;
  2576. fWithoutAlpha := tfLuminance12;
  2577. fglInternalFormat := GL_LUMINANCE12;
  2578. end;
  2579. constructor TfdLuminance16.Create;
  2580. begin
  2581. inherited Create;
  2582. fFormat := tfLuminance16;
  2583. fWithAlpha := tfLuminance16Alpha16;
  2584. fWithoutAlpha := tfLuminance16;
  2585. fglInternalFormat := GL_LUMINANCE16;
  2586. end;
  2587. constructor TfdLuminance4Alpha4.Create;
  2588. begin
  2589. inherited Create;
  2590. fFormat := tfLuminance4Alpha4;
  2591. fWithAlpha := tfLuminance4Alpha4;
  2592. fWithoutAlpha := tfLuminance4;
  2593. fglInternalFormat := GL_LUMINANCE4_ALPHA4;
  2594. end;
  2595. constructor TfdLuminance6Alpha2.Create;
  2596. begin
  2597. inherited Create;
  2598. fFormat := tfLuminance6Alpha2;
  2599. fWithAlpha := tfLuminance6Alpha2;
  2600. fWithoutAlpha := tfLuminance8;
  2601. fglInternalFormat := GL_LUMINANCE6_ALPHA2;
  2602. end;
  2603. constructor TfdLuminance8Alpha8.Create;
  2604. begin
  2605. inherited Create;
  2606. fFormat := tfLuminance8Alpha8;
  2607. fWithAlpha := tfLuminance8Alpha8;
  2608. fWithoutAlpha := tfLuminance8;
  2609. fglInternalFormat := GL_LUMINANCE8_ALPHA8;
  2610. end;
  2611. constructor TfdLuminance12Alpha4.Create;
  2612. begin
  2613. inherited Create;
  2614. fFormat := tfLuminance12Alpha4;
  2615. fWithAlpha := tfLuminance12Alpha4;
  2616. fWithoutAlpha := tfLuminance12;
  2617. fglInternalFormat := GL_LUMINANCE12_ALPHA4;
  2618. end;
  2619. constructor TfdLuminance12Alpha12.Create;
  2620. begin
  2621. inherited Create;
  2622. fFormat := tfLuminance12Alpha12;
  2623. fWithAlpha := tfLuminance12Alpha12;
  2624. fWithoutAlpha := tfLuminance12;
  2625. fglInternalFormat := GL_LUMINANCE12_ALPHA12;
  2626. end;
  2627. constructor TfdLuminance16Alpha16.Create;
  2628. begin
  2629. inherited Create;
  2630. fFormat := tfLuminance16Alpha16;
  2631. fWithAlpha := tfLuminance16Alpha16;
  2632. fWithoutAlpha := tfLuminance16;
  2633. fglInternalFormat := GL_LUMINANCE16_ALPHA16;
  2634. end;
  2635. constructor TfdR3G3B2.Create;
  2636. begin
  2637. inherited Create;
  2638. fFormat := tfR3G3B2;
  2639. fWithAlpha := tfRGBA2;
  2640. fWithoutAlpha := tfR3G3B2;
  2641. fRange.r := $7;
  2642. fRange.g := $7;
  2643. fRange.b := $3;
  2644. fShift.r := 0;
  2645. fShift.g := 3;
  2646. fShift.b := 6;
  2647. fglFormat := GL_RGB;
  2648. fglInternalFormat := GL_R3_G3_B2;
  2649. fglDataFormat := GL_UNSIGNED_BYTE_2_3_3_REV;
  2650. end;
  2651. constructor TfdRGB4.Create;
  2652. begin
  2653. inherited Create;
  2654. fFormat := tfRGB4;
  2655. fWithAlpha := tfRGBA4;
  2656. fWithoutAlpha := tfRGB4;
  2657. fRGBInverted := tfBGR4;
  2658. fRange.r := $F;
  2659. fRange.g := $F;
  2660. fRange.b := $F;
  2661. fShift.r := 0;
  2662. fShift.g := 4;
  2663. fShift.b := 8;
  2664. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2665. fglInternalFormat := GL_RGB4;
  2666. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
  2667. end;
  2668. constructor TfdR5G6B5.Create;
  2669. begin
  2670. inherited Create;
  2671. fFormat := tfR5G6B5;
  2672. fWithAlpha := tfRGBA4;
  2673. fWithoutAlpha := tfR5G6B5;
  2674. fRGBInverted := tfB5G6R5;
  2675. fRange.r := $1F;
  2676. fRange.g := $3F;
  2677. fRange.b := $1F;
  2678. fShift.r := 0;
  2679. fShift.g := 5;
  2680. fShift.b := 11;
  2681. fglFormat := GL_RGB;
  2682. fglInternalFormat := GL_RGB565;
  2683. fglDataFormat := GL_UNSIGNED_SHORT_5_6_5_REV;
  2684. end;
  2685. constructor TfdRGB5.Create;
  2686. begin
  2687. inherited Create;
  2688. fFormat := tfRGB5;
  2689. fWithAlpha := tfRGB5A1;
  2690. fWithoutAlpha := tfRGB5;
  2691. fRGBInverted := tfBGR5;
  2692. fRange.r := $1F;
  2693. fRange.g := $1F;
  2694. fRange.b := $1F;
  2695. fShift.r := 0;
  2696. fShift.g := 5;
  2697. fShift.b := 10;
  2698. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2699. fglInternalFormat := GL_RGB5;
  2700. fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
  2701. end;
  2702. constructor TfdRGB8.Create;
  2703. begin
  2704. inherited Create;
  2705. fFormat := tfRGB8;
  2706. fWithAlpha := tfRGBA8;
  2707. fWithoutAlpha := tfRGB8;
  2708. fRGBInverted := tfBGR8;
  2709. fglInternalFormat := GL_RGB8;
  2710. end;
  2711. constructor TfdRGB10.Create;
  2712. begin
  2713. inherited Create;
  2714. fFormat := tfRGB10;
  2715. fWithAlpha := tfRGB10A2;
  2716. fWithoutAlpha := tfRGB10;
  2717. fRGBInverted := tfBGR10;
  2718. fRange.r := $3FF;
  2719. fRange.g := $3FF;
  2720. fRange.b := $3FF;
  2721. fShift.r := 0;
  2722. fShift.g := 10;
  2723. fShift.b := 20;
  2724. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2725. fglInternalFormat := GL_RGB10;
  2726. fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
  2727. end;
  2728. constructor TfdRGB12.Create;
  2729. begin
  2730. inherited Create;
  2731. fFormat := tfRGB12;
  2732. fWithAlpha := tfRGBA12;
  2733. fWithoutAlpha := tfRGB12;
  2734. fRGBInverted := tfBGR12;
  2735. fglInternalFormat := GL_RGB12;
  2736. end;
  2737. constructor TfdRGB16.Create;
  2738. begin
  2739. inherited Create;
  2740. fFormat := tfRGB16;
  2741. fWithAlpha := tfRGBA16;
  2742. fWithoutAlpha := tfRGB16;
  2743. fRGBInverted := tfBGR16;
  2744. fglInternalFormat := GL_RGB16;
  2745. end;
  2746. constructor TfdRGBA2.Create;
  2747. begin
  2748. inherited Create;
  2749. fFormat := tfRGBA2;
  2750. fWithAlpha := tfRGBA2;
  2751. fWithoutAlpha := tfR3G3B2;
  2752. fRGBInverted := tfBGRA2;
  2753. fglInternalFormat := GL_RGBA2;
  2754. end;
  2755. constructor TfdRGBA4.Create;
  2756. begin
  2757. inherited Create;
  2758. fFormat := tfRGBA4;
  2759. fWithAlpha := tfRGBA4;
  2760. fWithoutAlpha := tfRGB4;
  2761. fRGBInverted := tfBGRA4;
  2762. fRange.r := $F;
  2763. fRange.g := $F;
  2764. fRange.b := $F;
  2765. fRange.a := $F;
  2766. fShift.r := 0;
  2767. fShift.g := 4;
  2768. fShift.b := 8;
  2769. fShift.a := 12;
  2770. fglFormat := GL_RGBA;
  2771. fglInternalFormat := GL_RGBA4;
  2772. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
  2773. end;
  2774. constructor TfdRGB5A1.Create;
  2775. begin
  2776. inherited Create;
  2777. fFormat := tfRGB5A1;
  2778. fWithAlpha := tfRGB5A1;
  2779. fWithoutAlpha := tfRGB5;
  2780. fRGBInverted := tfBGR5A1;
  2781. fRange.r := $1F;
  2782. fRange.g := $1F;
  2783. fRange.b := $1F;
  2784. fRange.a := $01;
  2785. fShift.r := 0;
  2786. fShift.g := 5;
  2787. fShift.b := 10;
  2788. fShift.a := 15;
  2789. fglFormat := GL_RGBA;
  2790. fglInternalFormat := GL_RGB5_A1;
  2791. fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
  2792. end;
  2793. constructor TfdRGBA8.Create;
  2794. begin
  2795. inherited Create;
  2796. fFormat := tfRGBA8;
  2797. fWithAlpha := tfRGBA8;
  2798. fWithoutAlpha := tfRGB8;
  2799. fRGBInverted := tfBGRA8;
  2800. fglInternalFormat := GL_RGBA8;
  2801. end;
  2802. constructor TfdRGB10A2.Create;
  2803. begin
  2804. inherited Create;
  2805. fFormat := tfRGB10A2;
  2806. fWithAlpha := tfRGB10A2;
  2807. fWithoutAlpha := tfRGB10;
  2808. fRGBInverted := tfBGR10A2;
  2809. fRange.r := $3FF;
  2810. fRange.g := $3FF;
  2811. fRange.b := $3FF;
  2812. fRange.a := $003;
  2813. fShift.r := 0;
  2814. fShift.g := 10;
  2815. fShift.b := 20;
  2816. fShift.a := 30;
  2817. fglFormat := GL_RGBA;
  2818. fglInternalFormat := GL_RGB10_A2;
  2819. fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
  2820. end;
  2821. constructor TfdRGBA12.Create;
  2822. begin
  2823. inherited Create;
  2824. fFormat := tfRGBA12;
  2825. fWithAlpha := tfRGBA12;
  2826. fWithoutAlpha := tfRGB12;
  2827. fRGBInverted := tfBGRA12;
  2828. fglInternalFormat := GL_RGBA12;
  2829. end;
  2830. constructor TfdRGBA16.Create;
  2831. begin
  2832. inherited Create;
  2833. fFormat := tfRGBA16;
  2834. fWithAlpha := tfRGBA16;
  2835. fWithoutAlpha := tfRGB16;
  2836. fRGBInverted := tfBGRA16;
  2837. fglInternalFormat := GL_RGBA16;
  2838. end;
  2839. constructor TfdBGR4.Create;
  2840. begin
  2841. inherited Create;
  2842. fPixelSize := 2.0;
  2843. fFormat := tfBGR4;
  2844. fWithAlpha := tfBGRA4;
  2845. fWithoutAlpha := tfBGR4;
  2846. fRGBInverted := tfRGB4;
  2847. fRange.r := $F;
  2848. fRange.g := $F;
  2849. fRange.b := $F;
  2850. fRange.a := $0;
  2851. fShift.r := 8;
  2852. fShift.g := 4;
  2853. fShift.b := 0;
  2854. fShift.a := 0;
  2855. fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2856. fglInternalFormat := GL_RGB4;
  2857. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
  2858. end;
  2859. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2860. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2861. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2862. constructor TfdB5G6R5.Create;
  2863. begin
  2864. inherited Create;
  2865. fFormat := tfB5G6R5;
  2866. fWithAlpha := tfBGRA4;
  2867. fWithoutAlpha := tfB5G6R5;
  2868. fRGBInverted := tfR5G6B5;
  2869. fRange.r := $1F;
  2870. fRange.g := $3F;
  2871. fRange.b := $1F;
  2872. fShift.r := 11;
  2873. fShift.g := 5;
  2874. fShift.b := 0;
  2875. fglFormat := GL_RGB; //B5G6R5 is only possible as R5G6B5 -> use reverted dataformat
  2876. fglInternalFormat := GL_RGB8;
  2877. fglDataFormat := GL_UNSIGNED_SHORT_5_6_5;
  2878. end;
  2879. constructor TfdBGR5.Create;
  2880. begin
  2881. inherited Create;
  2882. fPixelSize := 2.0;
  2883. fFormat := tfBGR5;
  2884. fWithAlpha := tfBGR5A1;
  2885. fWithoutAlpha := tfBGR5;
  2886. fRGBInverted := tfRGB5;
  2887. fRange.r := $1F;
  2888. fRange.g := $1F;
  2889. fRange.b := $1F;
  2890. fRange.a := $00;
  2891. fShift.r := 10;
  2892. fShift.g := 5;
  2893. fShift.b := 0;
  2894. fShift.a := 0;
  2895. fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2896. fglInternalFormat := GL_RGB5;
  2897. fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
  2898. end;
  2899. constructor TfdBGR8.Create;
  2900. begin
  2901. inherited Create;
  2902. fFormat := tfBGR8;
  2903. fWithAlpha := tfBGRA8;
  2904. fWithoutAlpha := tfBGR8;
  2905. fRGBInverted := tfRGB8;
  2906. fglInternalFormat := GL_RGB8;
  2907. end;
  2908. constructor TfdBGR10.Create;
  2909. begin
  2910. inherited Create;
  2911. fFormat := tfBGR10;
  2912. fWithAlpha := tfBGR10A2;
  2913. fWithoutAlpha := tfBGR10;
  2914. fRGBInverted := tfRGB10;
  2915. fRange.r := $3FF;
  2916. fRange.g := $3FF;
  2917. fRange.b := $3FF;
  2918. fRange.a := $000;
  2919. fShift.r := 20;
  2920. fShift.g := 10;
  2921. fShift.b := 0;
  2922. fShift.a := 0;
  2923. fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2924. fglInternalFormat := GL_RGB10;
  2925. fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
  2926. end;
  2927. constructor TfdBGR12.Create;
  2928. begin
  2929. inherited Create;
  2930. fFormat := tfBGR12;
  2931. fWithAlpha := tfBGRA12;
  2932. fWithoutAlpha := tfBGR12;
  2933. fRGBInverted := tfRGB12;
  2934. fglInternalFormat := GL_RGB12;
  2935. end;
  2936. constructor TfdBGR16.Create;
  2937. begin
  2938. inherited Create;
  2939. fFormat := tfBGR16;
  2940. fWithAlpha := tfBGRA16;
  2941. fWithoutAlpha := tfBGR16;
  2942. fRGBInverted := tfRGB16;
  2943. fglInternalFormat := GL_RGB16;
  2944. end;
  2945. constructor TfdBGRA2.Create;
  2946. begin
  2947. inherited Create;
  2948. fFormat := tfBGRA2;
  2949. fWithAlpha := tfBGRA4;
  2950. fWithoutAlpha := tfBGR4;
  2951. fRGBInverted := tfRGBA2;
  2952. fglInternalFormat := GL_RGBA2;
  2953. end;
  2954. constructor TfdBGRA4.Create;
  2955. begin
  2956. inherited Create;
  2957. fFormat := tfBGRA4;
  2958. fWithAlpha := tfBGRA4;
  2959. fWithoutAlpha := tfBGR4;
  2960. fRGBInverted := tfRGBA4;
  2961. fRange.r := $F;
  2962. fRange.g := $F;
  2963. fRange.b := $F;
  2964. fRange.a := $F;
  2965. fShift.r := 8;
  2966. fShift.g := 4;
  2967. fShift.b := 0;
  2968. fShift.a := 12;
  2969. fglFormat := GL_BGRA;
  2970. fglInternalFormat := GL_RGBA4;
  2971. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
  2972. end;
  2973. constructor TfdBGR5A1.Create;
  2974. begin
  2975. inherited Create;
  2976. fFormat := tfBGR5A1;
  2977. fWithAlpha := tfBGR5A1;
  2978. fWithoutAlpha := tfBGR5;
  2979. fRGBInverted := tfRGB5A1;
  2980. fRange.r := $1F;
  2981. fRange.g := $1F;
  2982. fRange.b := $1F;
  2983. fRange.a := $01;
  2984. fShift.r := 10;
  2985. fShift.g := 5;
  2986. fShift.b := 0;
  2987. fShift.a := 15;
  2988. fglFormat := GL_BGRA;
  2989. fglInternalFormat := GL_RGB5_A1;
  2990. fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
  2991. end;
  2992. constructor TfdBGRA8.Create;
  2993. begin
  2994. inherited Create;
  2995. fFormat := tfBGRA8;
  2996. fWithAlpha := tfBGRA8;
  2997. fWithoutAlpha := tfBGR8;
  2998. fRGBInverted := tfRGBA8;
  2999. fglInternalFormat := GL_RGBA8;
  3000. end;
  3001. constructor TfdBGR10A2.Create;
  3002. begin
  3003. inherited Create;
  3004. fFormat := tfBGR10A2;
  3005. fWithAlpha := tfBGR10A2;
  3006. fWithoutAlpha := tfBGR10;
  3007. fRGBInverted := tfRGB10A2;
  3008. fRange.r := $3FF;
  3009. fRange.g := $3FF;
  3010. fRange.b := $3FF;
  3011. fRange.a := $003;
  3012. fShift.r := 20;
  3013. fShift.g := 10;
  3014. fShift.b := 0;
  3015. fShift.a := 30;
  3016. fglFormat := GL_BGRA;
  3017. fglInternalFormat := GL_RGB10_A2;
  3018. fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
  3019. end;
  3020. constructor TfdBGRA12.Create;
  3021. begin
  3022. inherited Create;
  3023. fFormat := tfBGRA12;
  3024. fWithAlpha := tfBGRA12;
  3025. fWithoutAlpha := tfBGR12;
  3026. fRGBInverted := tfRGBA12;
  3027. fglInternalFormat := GL_RGBA12;
  3028. end;
  3029. constructor TfdBGRA16.Create;
  3030. begin
  3031. inherited Create;
  3032. fFormat := tfBGRA16;
  3033. fWithAlpha := tfBGRA16;
  3034. fWithoutAlpha := tfBGR16;
  3035. fRGBInverted := tfRGBA16;
  3036. fglInternalFormat := GL_RGBA16;
  3037. end;
  3038. constructor TfdDepth16.Create;
  3039. begin
  3040. inherited Create;
  3041. fFormat := tfDepth16;
  3042. fWithAlpha := tfEmpty;
  3043. fWithoutAlpha := tfDepth16;
  3044. fglInternalFormat := GL_DEPTH_COMPONENT16;
  3045. end;
  3046. constructor TfdDepth24.Create;
  3047. begin
  3048. inherited Create;
  3049. fFormat := tfDepth24;
  3050. fWithAlpha := tfEmpty;
  3051. fWithoutAlpha := tfDepth24;
  3052. fglInternalFormat := GL_DEPTH_COMPONENT24;
  3053. end;
  3054. constructor TfdDepth32.Create;
  3055. begin
  3056. inherited Create;
  3057. fFormat := tfDepth32;
  3058. fWithAlpha := tfEmpty;
  3059. fWithoutAlpha := tfDepth32;
  3060. fglInternalFormat := GL_DEPTH_COMPONENT32;
  3061. end;
  3062. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3063. //TfdS3tcDtx1RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3064. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3065. procedure TfdS3tcDtx1RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  3066. begin
  3067. raise EglBitmap.Create('mapping for compressed formats is not supported');
  3068. end;
  3069. procedure TfdS3tcDtx1RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  3070. begin
  3071. raise EglBitmap.Create('mapping for compressed formats is not supported');
  3072. end;
  3073. constructor TfdS3tcDtx1RGBA.Create;
  3074. begin
  3075. inherited Create;
  3076. fFormat := tfS3tcDtx1RGBA;
  3077. fWithAlpha := tfS3tcDtx1RGBA;
  3078. fUncompressed := tfRGB5A1;
  3079. fPixelSize := 0.5;
  3080. fIsCompressed := true;
  3081. fglFormat := GL_COMPRESSED_RGBA;
  3082. fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
  3083. fglDataFormat := GL_UNSIGNED_BYTE;
  3084. end;
  3085. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3086. //TfdS3tcDtx3RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3087. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3088. procedure TfdS3tcDtx3RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  3089. begin
  3090. raise EglBitmap.Create('mapping for compressed formats is not supported');
  3091. end;
  3092. procedure TfdS3tcDtx3RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  3093. begin
  3094. raise EglBitmap.Create('mapping for compressed formats is not supported');
  3095. end;
  3096. constructor TfdS3tcDtx3RGBA.Create;
  3097. begin
  3098. inherited Create;
  3099. fFormat := tfS3tcDtx3RGBA;
  3100. fWithAlpha := tfS3tcDtx3RGBA;
  3101. fUncompressed := tfRGBA8;
  3102. fPixelSize := 1.0;
  3103. fIsCompressed := true;
  3104. fglFormat := GL_COMPRESSED_RGBA;
  3105. fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
  3106. fglDataFormat := GL_UNSIGNED_BYTE;
  3107. end;
  3108. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3109. //TfdS3tcDtx5RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3110. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3111. procedure TfdS3tcDtx5RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  3112. begin
  3113. raise EglBitmap.Create('mapping for compressed formats is not supported');
  3114. end;
  3115. procedure TfdS3tcDtx5RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  3116. begin
  3117. raise EglBitmap.Create('mapping for compressed formats is not supported');
  3118. end;
  3119. constructor TfdS3tcDtx5RGBA.Create;
  3120. begin
  3121. inherited Create;
  3122. fFormat := tfS3tcDtx3RGBA;
  3123. fWithAlpha := tfS3tcDtx3RGBA;
  3124. fUncompressed := tfRGBA8;
  3125. fPixelSize := 1.0;
  3126. fIsCompressed := true;
  3127. fglFormat := GL_COMPRESSED_RGBA;
  3128. fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  3129. fglDataFormat := GL_UNSIGNED_BYTE;
  3130. end;
  3131. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3132. //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3133. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3134. class procedure TFormatDescriptor.Init;
  3135. begin
  3136. if not Assigned(FormatDescriptorCS) then
  3137. FormatDescriptorCS := TCriticalSection.Create;
  3138. end;
  3139. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3140. class function TFormatDescriptor.Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
  3141. begin
  3142. FormatDescriptorCS.Enter;
  3143. try
  3144. result := FormatDescriptors[aFormat];
  3145. if not Assigned(result) then begin
  3146. result := FORMAT_DESCRIPTOR_CLASSES[aFormat].Create;
  3147. FormatDescriptors[aFormat] := result;
  3148. end;
  3149. finally
  3150. FormatDescriptorCS.Leave;
  3151. end;
  3152. end;
  3153. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3154. class function TFormatDescriptor.GetWithAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
  3155. begin
  3156. result := Get(Get(aFormat).WithAlpha);
  3157. end;
  3158. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3159. class procedure TFormatDescriptor.Clear;
  3160. var
  3161. f: TglBitmapFormat;
  3162. begin
  3163. FormatDescriptorCS.Enter;
  3164. try
  3165. for f := low(FormatDescriptors) to high(FormatDescriptors) do
  3166. FreeAndNil(FormatDescriptors[f]);
  3167. finally
  3168. FormatDescriptorCS.Leave;
  3169. end;
  3170. end;
  3171. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3172. class procedure TFormatDescriptor.Finalize;
  3173. begin
  3174. Clear;
  3175. FreeAndNil(FormatDescriptorCS);
  3176. end;
  3177. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3178. //TBitfieldFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3179. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3180. procedure TbmpBitfieldFormat.SetRedMask(const aValue: QWord);
  3181. begin
  3182. Update(aValue, fRange.r, fShift.r);
  3183. end;
  3184. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3185. procedure TbmpBitfieldFormat.SetGreenMask(const aValue: QWord);
  3186. begin
  3187. Update(aValue, fRange.g, fShift.g);
  3188. end;
  3189. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3190. procedure TbmpBitfieldFormat.SetBlueMask(const aValue: QWord);
  3191. begin
  3192. Update(aValue, fRange.b, fShift.b);
  3193. end;
  3194. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3195. procedure TbmpBitfieldFormat.SetAlphaMask(const aValue: QWord);
  3196. begin
  3197. Update(aValue, fRange.a, fShift.a);
  3198. end;
  3199. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3200. procedure TbmpBitfieldFormat.Update(aMask: QWord; out aRange: Cardinal; out
  3201. aShift: Byte);
  3202. begin
  3203. aShift := 0;
  3204. aRange := 0;
  3205. if (aMask = 0) then
  3206. exit;
  3207. while (aMask > 0) and ((aMask and 1) = 0) do begin
  3208. inc(aShift);
  3209. aMask := aMask shr 1;
  3210. end;
  3211. aRange := 1;
  3212. while (aMask > 0) do begin
  3213. aRange := aRange shl 1;
  3214. aMask := aMask shr 1;
  3215. end;
  3216. dec(aRange);
  3217. fPixelSize := Round(GetTopMostBit(RedMask or GreenMask or BlueMask or AlphaMask) / 8);
  3218. end;
  3219. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3220. procedure TbmpBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  3221. var
  3222. data: QWord;
  3223. s: Integer;
  3224. begin
  3225. data :=
  3226. ((aPixel.Data.r and fRange.r) shl fShift.r) or
  3227. ((aPixel.Data.g and fRange.g) shl fShift.g) or
  3228. ((aPixel.Data.b and fRange.b) shl fShift.b) or
  3229. ((aPixel.Data.a and fRange.a) shl fShift.a);
  3230. s := Round(fPixelSize);
  3231. case s of
  3232. 1: aData^ := data;
  3233. 2: PWord(aData)^ := data;
  3234. 4: PCardinal(aData)^ := data;
  3235. 8: PQWord(aData)^ := data;
  3236. else
  3237. raise EglBitmap.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
  3238. end;
  3239. inc(aData, s);
  3240. end;
  3241. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3242. procedure TbmpBitfieldFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  3243. var
  3244. data: QWord;
  3245. s, i: Integer;
  3246. begin
  3247. s := Round(fPixelSize);
  3248. case s of
  3249. 1: data := aData^;
  3250. 2: data := PWord(aData)^;
  3251. 4: data := PCardinal(aData)^;
  3252. 8: data := PQWord(aData)^;
  3253. else
  3254. raise EglBitmap.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
  3255. end;
  3256. for i := 0 to 3 do
  3257. aPixel.Data.arr[i] := (data shr fShift.arr[i]) and fRange.arr[i];
  3258. inc(aData, s);
  3259. end;
  3260. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3261. //TColorTableFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3262. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3263. procedure TbmpColorTableFormat.CreateColorTable;
  3264. var
  3265. i: Integer;
  3266. begin
  3267. if not (Format in [tfLuminance4, tfLuminance8, tfR3G3B2]) then
  3268. raise EglBitmap.Create(UNSUPPORTED_FORMAT);
  3269. if (Format = tfLuminance4) then
  3270. SetLength(fColorTable, 16)
  3271. else
  3272. SetLength(fColorTable, 256);
  3273. case Format of
  3274. tfLuminance4: begin
  3275. for i := 0 to High(fColorTable) do begin
  3276. fColorTable[i].r := 16 * i;
  3277. fColorTable[i].g := 16 * i;
  3278. fColorTable[i].b := 16 * i;
  3279. fColorTable[i].a := 0;
  3280. end;
  3281. end;
  3282. tfLuminance8: begin
  3283. for i := 0 to High(fColorTable) do begin
  3284. fColorTable[i].r := i;
  3285. fColorTable[i].g := i;
  3286. fColorTable[i].b := i;
  3287. fColorTable[i].a := 0;
  3288. end;
  3289. end;
  3290. tfR3G3B2: begin
  3291. for i := 0 to High(fColorTable) do begin
  3292. fColorTable[i].r := Round(((i shr Shift.r) and Range.r) / Range.r * 255);
  3293. fColorTable[i].g := Round(((i shr Shift.g) and Range.g) / Range.g * 255);
  3294. fColorTable[i].b := Round(((i shr Shift.b) and Range.b) / Range.b * 255);
  3295. fColorTable[i].a := 0;
  3296. end;
  3297. end;
  3298. end;
  3299. end;
  3300. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3301. procedure TbmpColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  3302. var
  3303. d: Byte;
  3304. begin
  3305. if not (Format in [tfLuminance4, tfLuminance8, tfR3G3B2]) then
  3306. raise EglBitmap.Create(UNSUPPORTED_FORMAT);
  3307. case Format of
  3308. tfLuminance4: begin
  3309. if (aMapData = nil) then
  3310. aData^ := 0;
  3311. d := LuminanceWeight(aPixel) and Range.r;
  3312. aData^ := aData^ or (d shl (4 - {%H-}PtrUInt(aMapData)));
  3313. inc(PByte(aMapData), 4);
  3314. if ({%H-}PtrUInt(aMapData) >= 8) then begin
  3315. inc(aData);
  3316. aMapData := nil;
  3317. end;
  3318. end;
  3319. tfLuminance8: begin
  3320. aData^ := LuminanceWeight(aPixel) and Range.r;
  3321. inc(aData);
  3322. end;
  3323. tfR3G3B2: begin
  3324. aData^ := Round(
  3325. ((aPixel.Data.r and Range.r) shl Shift.r) or
  3326. ((aPixel.Data.g and Range.g) shl Shift.g) or
  3327. ((aPixel.Data.b and Range.b) shl Shift.b));
  3328. inc(aData);
  3329. end;
  3330. end;
  3331. end;
  3332. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3333. procedure TbmpColorTableFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  3334. var
  3335. idx: QWord;
  3336. s: Integer;
  3337. bits: Byte;
  3338. f: Single;
  3339. begin
  3340. s := Trunc(fPixelSize);
  3341. f := fPixelSize - s;
  3342. bits := Round(8 * f);
  3343. case s of
  3344. 0: idx := (aData^ shr (8 - bits - {%H-}PtrInt(aMapData))) and ((1 shl bits) - 1);
  3345. 1: idx := aData^;
  3346. 2: idx := PWord(aData)^;
  3347. 4: idx := PCardinal(aData)^;
  3348. 8: idx := PQWord(aData)^;
  3349. else
  3350. raise EglBitmap.CreateFmt('invalid pixel size: %.3f', [fPixelSize]);
  3351. end;
  3352. if (idx >= Length(fColorTable)) then
  3353. raise EglBitmap.CreateFmt('invalid color index: %d', [idx]);
  3354. with fColorTable[idx] do begin
  3355. aPixel.Data.r := r;
  3356. aPixel.Data.g := g;
  3357. aPixel.Data.b := b;
  3358. aPixel.Data.a := a;
  3359. end;
  3360. inc(PByte(aMapData), bits);
  3361. if ({%H-}PtrUInt(aMapData) >= 8) then begin
  3362. inc(aData, 1);
  3363. dec(PByte(aMapData), 8);
  3364. end;
  3365. inc(aData, s);
  3366. end;
  3367. destructor TbmpColorTableFormat.Destroy;
  3368. begin
  3369. SetLength(fColorTable, 0);
  3370. inherited Destroy;
  3371. end;
  3372. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3373. //TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3374. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3375. procedure glBitmapConvertPixel(var aPixel: TglBitmapPixelData; const aSourceFD, aDestFD: TFormatDescriptor);
  3376. var
  3377. i: Integer;
  3378. begin
  3379. for i := 0 to 3 do begin
  3380. if (aSourceFD.Range.arr[i] <> aDestFD.Range.arr[i]) then begin
  3381. if (aSourceFD.Range.arr[i] > 0) then
  3382. aPixel.Data.arr[i] := Round(aPixel.Data.arr[i] / aSourceFD.Range.arr[i] * aDestFD.Range.arr[i])
  3383. else
  3384. aPixel.Data.arr[i] := aDestFD.Range.arr[i];
  3385. end;
  3386. end;
  3387. end;
  3388. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3389. procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
  3390. begin
  3391. with aFuncRec do begin
  3392. if (Source.Range.r > 0) then
  3393. Dest.Data.r := Source.Data.r;
  3394. if (Source.Range.g > 0) then
  3395. Dest.Data.g := Source.Data.g;
  3396. if (Source.Range.b > 0) then
  3397. Dest.Data.b := Source.Data.b;
  3398. if (Source.Range.a > 0) then
  3399. Dest.Data.a := Source.Data.a;
  3400. end;
  3401. end;
  3402. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3403. procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
  3404. var
  3405. i: Integer;
  3406. begin
  3407. with aFuncRec do begin
  3408. for i := 0 to 3 do
  3409. if (Source.Range.arr[i] > 0) then
  3410. Dest.Data.arr[i] := Round(Dest.Range.arr[i] * Source.Data.arr[i] / Source.Range.arr[i]);
  3411. end;
  3412. end;
  3413. type
  3414. TShiftData = packed record
  3415. case Integer of
  3416. 0: (r, g, b, a: SmallInt);
  3417. 1: (arr: array[0..3] of SmallInt);
  3418. end;
  3419. PShiftData = ^TShiftData;
  3420. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3421. procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
  3422. var
  3423. i: Integer;
  3424. begin
  3425. with aFuncRec do
  3426. for i := 0 to 3 do
  3427. if (Source.Range.arr[i] > 0) then
  3428. Dest.Data.arr[i] := Source.Data.arr[i] shr PShiftData(Args)^.arr[i];
  3429. end;
  3430. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3431. procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
  3432. begin
  3433. with aFuncRec do begin
  3434. Dest.Data := Source.Data;
  3435. if ({%H-}PtrUInt(Args) and $1 > 0) then begin
  3436. Dest.Data.r := Dest.Data.r xor Dest.Range.r;
  3437. Dest.Data.g := Dest.Data.g xor Dest.Range.g;
  3438. Dest.Data.b := Dest.Data.b xor Dest.Range.b;
  3439. end;
  3440. if ({%H-}PtrUInt(Args) and $2 > 0) then begin
  3441. Dest.Data.a := Dest.Data.a xor Dest.Range.a;
  3442. end;
  3443. end;
  3444. end;
  3445. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3446. procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
  3447. var
  3448. i: Integer;
  3449. begin
  3450. with aFuncRec do begin
  3451. for i := 0 to 3 do
  3452. Dest.Data.arr[i] := PglBitmapPixelData(Args)^.Data.arr[i];
  3453. end;
  3454. end;
  3455. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3456. procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
  3457. var
  3458. Temp: Single;
  3459. begin
  3460. with FuncRec do begin
  3461. if (FuncRec.Args = nil) then begin //source has no alpha
  3462. Temp :=
  3463. Source.Data.r / Source.Range.r * ALPHA_WEIGHT_R +
  3464. Source.Data.g / Source.Range.g * ALPHA_WEIGHT_G +
  3465. Source.Data.b / Source.Range.b * ALPHA_WEIGHT_B;
  3466. Dest.Data.a := Round(Dest.Range.a * Temp);
  3467. end else
  3468. Dest.Data.a := Round(Source.Data.a / Source.Range.a * Dest.Range.a);
  3469. end;
  3470. end;
  3471. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3472. procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
  3473. type
  3474. PglBitmapPixelData = ^TglBitmapPixelData;
  3475. begin
  3476. with FuncRec do begin
  3477. Dest.Data.r := Source.Data.r;
  3478. Dest.Data.g := Source.Data.g;
  3479. Dest.Data.b := Source.Data.b;
  3480. with PglBitmapPixelData(Args)^ do
  3481. if ((Dest.Data.r <= Data.r) and (Dest.Data.r >= Range.r) and
  3482. (Dest.Data.g <= Data.g) and (Dest.Data.g >= Range.g) and
  3483. (Dest.Data.b <= Data.b) and (Dest.Data.b >= Range.b)) then
  3484. Dest.Data.a := 0
  3485. else
  3486. Dest.Data.a := Dest.Range.a;
  3487. end;
  3488. end;
  3489. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3490. procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
  3491. begin
  3492. with FuncRec do begin
  3493. Dest.Data.r := Source.Data.r;
  3494. Dest.Data.g := Source.Data.g;
  3495. Dest.Data.b := Source.Data.b;
  3496. Dest.Data.a := PCardinal(Args)^;
  3497. end;
  3498. end;
  3499. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3500. procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
  3501. type
  3502. PRGBPix = ^TRGBPix;
  3503. TRGBPix = array [0..2] of byte;
  3504. var
  3505. Temp: Byte;
  3506. begin
  3507. while aWidth > 0 do begin
  3508. Temp := PRGBPix(aData)^[0];
  3509. PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
  3510. PRGBPix(aData)^[2] := Temp;
  3511. if aHasAlpha then
  3512. Inc(aData, 4)
  3513. else
  3514. Inc(aData, 3);
  3515. dec(aWidth);
  3516. end;
  3517. end;
  3518. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3519. //TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3520. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3521. function TglBitmap.GetFormatDesc: TglBitmapFormatDescriptor;
  3522. begin
  3523. result := TFormatDescriptor.Get(Format);
  3524. end;
  3525. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3526. function TglBitmap.GetWidth: Integer;
  3527. begin
  3528. if (ffX in fDimension.Fields) then
  3529. result := fDimension.X
  3530. else
  3531. result := -1;
  3532. end;
  3533. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3534. function TglBitmap.GetHeight: Integer;
  3535. begin
  3536. if (ffY in fDimension.Fields) then
  3537. result := fDimension.Y
  3538. else
  3539. result := -1;
  3540. end;
  3541. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3542. function TglBitmap.GetFileWidth: Integer;
  3543. begin
  3544. result := Max(1, Width);
  3545. end;
  3546. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3547. function TglBitmap.GetFileHeight: Integer;
  3548. begin
  3549. result := Max(1, Height);
  3550. end;
  3551. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3552. procedure TglBitmap.SetCustomData(const aValue: Pointer);
  3553. begin
  3554. if fCustomData = aValue then
  3555. exit;
  3556. fCustomData := aValue;
  3557. end;
  3558. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3559. procedure TglBitmap.SetCustomName(const aValue: String);
  3560. begin
  3561. if fCustomName = aValue then
  3562. exit;
  3563. fCustomName := aValue;
  3564. end;
  3565. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3566. procedure TglBitmap.SetCustomNameW(const aValue: WideString);
  3567. begin
  3568. if fCustomNameW = aValue then
  3569. exit;
  3570. fCustomNameW := aValue;
  3571. end;
  3572. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3573. procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
  3574. begin
  3575. if fDeleteTextureOnFree = aValue then
  3576. exit;
  3577. fDeleteTextureOnFree := aValue;
  3578. end;
  3579. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3580. procedure TglBitmap.SetFormat(const aValue: TglBitmapFormat);
  3581. begin
  3582. if fFormat = aValue then
  3583. exit;
  3584. if TFormatDescriptor.Get(Format).PixelSize <> TFormatDescriptor.Get(aValue).PixelSize then
  3585. raise EglBitmapUnsupportedFormat.Create(Format);
  3586. SetDataPointer(fData, aValue, Width, Height); //be careful, Data could be freed by this method
  3587. end;
  3588. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3589. procedure TglBitmap.SetFreeDataAfterGenTexture(const aValue: Boolean);
  3590. begin
  3591. if fFreeDataAfterGenTexture = aValue then
  3592. exit;
  3593. fFreeDataAfterGenTexture := aValue;
  3594. end;
  3595. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3596. procedure TglBitmap.SetID(const aValue: Cardinal);
  3597. begin
  3598. if fID = aValue then
  3599. exit;
  3600. fID := aValue;
  3601. end;
  3602. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3603. procedure TglBitmap.SetMipMap(const aValue: TglBitmapMipMap);
  3604. begin
  3605. if fMipMap = aValue then
  3606. exit;
  3607. fMipMap := aValue;
  3608. end;
  3609. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3610. procedure TglBitmap.SetTarget(const aValue: Cardinal);
  3611. begin
  3612. if fTarget = aValue then
  3613. exit;
  3614. fTarget := aValue;
  3615. end;
  3616. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3617. procedure TglBitmap.SetAnisotropic(const aValue: Integer);
  3618. var
  3619. MaxAnisotropic: Integer;
  3620. begin
  3621. fAnisotropic := aValue;
  3622. if (ID > 0) then begin
  3623. if GL_EXT_texture_filter_anisotropic then begin
  3624. if fAnisotropic > 0 then begin
  3625. Bind(false);
  3626. glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
  3627. if aValue > MaxAnisotropic then
  3628. fAnisotropic := MaxAnisotropic;
  3629. glTexParameteri(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, fAnisotropic);
  3630. end;
  3631. end else begin
  3632. fAnisotropic := 0;
  3633. end;
  3634. end;
  3635. end;
  3636. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3637. procedure TglBitmap.CreateID;
  3638. begin
  3639. if (ID <> 0) then
  3640. glDeleteTextures(1, @fID);
  3641. glGenTextures(1, @fID);
  3642. Bind(false);
  3643. end;
  3644. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3645. procedure TglBitmap.SetupParameters(out aBuildWithGlu: Boolean);
  3646. begin
  3647. // Set Up Parameters
  3648. SetWrap(fWrapS, fWrapT, fWrapR);
  3649. SetFilter(fFilterMin, fFilterMag);
  3650. SetAnisotropic(fAnisotropic);
  3651. SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
  3652. if (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
  3653. SetSwizzle(fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
  3654. // Mip Maps Generation Mode
  3655. aBuildWithGlu := false;
  3656. if (MipMap = mmMipmap) then begin
  3657. if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
  3658. glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
  3659. else
  3660. aBuildWithGlu := true;
  3661. end else if (MipMap = mmMipmapGlu) then
  3662. aBuildWithGlu := true;
  3663. end;
  3664. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3665. procedure TglBitmap.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
  3666. const aWidth: Integer; const aHeight: Integer);
  3667. var
  3668. s: Single;
  3669. begin
  3670. if (Data <> aData) then begin
  3671. if (Assigned(Data)) then
  3672. FreeMem(Data);
  3673. fData := aData;
  3674. end;
  3675. FillChar(fDimension, SizeOf(fDimension), 0);
  3676. if not Assigned(fData) then begin
  3677. fFormat := tfEmpty;
  3678. fPixelSize := 0;
  3679. fRowSize := 0;
  3680. end else begin
  3681. if aWidth <> -1 then begin
  3682. fDimension.Fields := fDimension.Fields + [ffX];
  3683. fDimension.X := aWidth;
  3684. end;
  3685. if aHeight <> -1 then begin
  3686. fDimension.Fields := fDimension.Fields + [ffY];
  3687. fDimension.Y := aHeight;
  3688. end;
  3689. s := TFormatDescriptor.Get(aFormat).PixelSize;
  3690. fFormat := aFormat;
  3691. fPixelSize := Ceil(s);
  3692. fRowSize := Ceil(s * aWidth);
  3693. end;
  3694. end;
  3695. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3696. function TglBitmap.FlipHorz: Boolean;
  3697. begin
  3698. result := false;
  3699. end;
  3700. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3701. function TglBitmap.FlipVert: Boolean;
  3702. begin
  3703. result := false;
  3704. end;
  3705. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3706. //TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3707. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3708. procedure TglBitmap.AfterConstruction;
  3709. begin
  3710. inherited AfterConstruction;
  3711. fID := 0;
  3712. fTarget := 0;
  3713. fIsResident := false;
  3714. fFormat := glBitmapGetDefaultFormat;
  3715. fMipMap := glBitmapDefaultMipmap;
  3716. fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
  3717. fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
  3718. glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
  3719. glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
  3720. glBitmapGetDefaultSwizzle (fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
  3721. end;
  3722. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3723. procedure TglBitmap.BeforeDestruction;
  3724. var
  3725. NewData: PByte;
  3726. begin
  3727. NewData := nil;
  3728. SetDataPointer(NewData, tfEmpty); //be careful, Data could be freed by this method
  3729. if (fID > 0) and fDeleteTextureOnFree then
  3730. glDeleteTextures(1, @fID);
  3731. inherited BeforeDestruction;
  3732. end;
  3733. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3734. procedure TglBitmap.PrepareResType(var aResource: String; var aResType: PChar);
  3735. var
  3736. TempPos: Integer;
  3737. begin
  3738. if not Assigned(aResType) then begin
  3739. TempPos := Pos('.', aResource);
  3740. aResType := PChar(UpperCase(Copy(aResource, TempPos + 1, Length(aResource) - TempPos)));
  3741. aResource := UpperCase(Copy(aResource, 0, TempPos -1));
  3742. end;
  3743. end;
  3744. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3745. procedure TglBitmap.LoadFromFile(const aFilename: String);
  3746. var
  3747. fs: TFileStream;
  3748. begin
  3749. if not FileExists(aFilename) then
  3750. raise EglBitmap.Create('file does not exist: ' + aFilename);
  3751. fFilename := aFilename;
  3752. fs := TFileStream.Create(fFilename, fmOpenRead);
  3753. try
  3754. fs.Position := 0;
  3755. LoadFromStream(fs);
  3756. finally
  3757. fs.Free;
  3758. end;
  3759. end;
  3760. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3761. procedure TglBitmap.LoadFromStream(const aStream: TStream);
  3762. begin
  3763. {$IFDEF GLB_SUPPORT_PNG_READ}
  3764. if not LoadPNG(aStream) then
  3765. {$ENDIF}
  3766. {$IFDEF GLB_SUPPORT_JPEG_READ}
  3767. if not LoadJPEG(aStream) then
  3768. {$ENDIF}
  3769. if not LoadDDS(aStream) then
  3770. if not LoadTGA(aStream) then
  3771. if not LoadBMP(aStream) then
  3772. raise EglBitmap.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
  3773. end;
  3774. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3775. procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
  3776. const aFormat: TglBitmapFormat; const aArgs: Pointer);
  3777. var
  3778. tmpData: PByte;
  3779. size: Integer;
  3780. begin
  3781. size := TFormatDescriptor.Get(aFormat).GetSize(aSize);
  3782. GetMem(tmpData, size);
  3783. try
  3784. FillChar(tmpData^, size, #$FF);
  3785. SetDataPointer(tmpData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
  3786. except
  3787. if Assigned(tmpData) then
  3788. FreeMem(tmpData);
  3789. raise;
  3790. end;
  3791. AddFunc(Self, aFunc, false, Format, aArgs);
  3792. end;
  3793. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3794. procedure TglBitmap.LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar);
  3795. var
  3796. rs: TResourceStream;
  3797. begin
  3798. PrepareResType(aResource, aResType);
  3799. rs := TResourceStream.Create(aInstance, aResource, aResType);
  3800. try
  3801. LoadFromStream(rs);
  3802. finally
  3803. rs.Free;
  3804. end;
  3805. end;
  3806. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3807. procedure TglBitmap.LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
  3808. var
  3809. rs: TResourceStream;
  3810. begin
  3811. rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
  3812. try
  3813. LoadFromStream(rs);
  3814. finally
  3815. rs.Free;
  3816. end;
  3817. end;
  3818. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3819. procedure TglBitmap.SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
  3820. var
  3821. fs: TFileStream;
  3822. begin
  3823. fs := TFileStream.Create(aFileName, fmCreate);
  3824. try
  3825. fs.Position := 0;
  3826. SaveToStream(fs, aFileType);
  3827. finally
  3828. fs.Free;
  3829. end;
  3830. end;
  3831. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3832. procedure TglBitmap.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
  3833. begin
  3834. case aFileType of
  3835. {$IFDEF GLB_SUPPORT_PNG_WRITE}
  3836. ftPNG: SavePNG(aStream);
  3837. {$ENDIF}
  3838. {$IFDEF GLB_SUPPORT_JPEG_WRITE}
  3839. ftJPEG: SaveJPEG(aStream);
  3840. {$ENDIF}
  3841. ftDDS: SaveDDS(aStream);
  3842. ftTGA: SaveTGA(aStream);
  3843. ftBMP: SaveBMP(aStream);
  3844. end;
  3845. end;
  3846. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3847. function TglBitmap.AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer): Boolean;
  3848. begin
  3849. result := AddFunc(Self, aFunc, aCreateTemp, Format, aArgs);
  3850. end;
  3851. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3852. function TglBitmap.AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
  3853. const aFormat: TglBitmapFormat; const aArgs: Pointer): Boolean;
  3854. var
  3855. DestData, TmpData, SourceData: pByte;
  3856. TempHeight, TempWidth: Integer;
  3857. SourceFD, DestFD: TFormatDescriptor;
  3858. SourceMD, DestMD: Pointer;
  3859. FuncRec: TglBitmapFunctionRec;
  3860. begin
  3861. Assert(Assigned(Data));
  3862. Assert(Assigned(aSource));
  3863. Assert(Assigned(aSource.Data));
  3864. result := false;
  3865. if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
  3866. SourceFD := TFormatDescriptor.Get(aSource.Format);
  3867. DestFD := TFormatDescriptor.Get(aFormat);
  3868. if (SourceFD.IsCompressed) then
  3869. raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', SourceFD.Format);
  3870. if (DestFD.IsCompressed) then
  3871. raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', DestFD.Format);
  3872. // inkompatible Formats so CreateTemp
  3873. if (SourceFD.PixelSize <> DestFD.PixelSize) then
  3874. aCreateTemp := true;
  3875. // Values
  3876. TempHeight := Max(1, aSource.Height);
  3877. TempWidth := Max(1, aSource.Width);
  3878. FuncRec.Sender := Self;
  3879. FuncRec.Args := aArgs;
  3880. TmpData := nil;
  3881. if aCreateTemp then begin
  3882. GetMem(TmpData, DestFD.GetSize(TempWidth, TempHeight));
  3883. DestData := TmpData;
  3884. end else
  3885. DestData := Data;
  3886. try
  3887. SourceFD.PreparePixel(FuncRec.Source);
  3888. DestFD.PreparePixel (FuncRec.Dest);
  3889. SourceMD := SourceFD.CreateMappingData;
  3890. DestMD := DestFD.CreateMappingData;
  3891. FuncRec.Size := aSource.Dimension;
  3892. FuncRec.Position.Fields := FuncRec.Size.Fields;
  3893. try
  3894. SourceData := aSource.Data;
  3895. FuncRec.Position.Y := 0;
  3896. while FuncRec.Position.Y < TempHeight do begin
  3897. FuncRec.Position.X := 0;
  3898. while FuncRec.Position.X < TempWidth do begin
  3899. SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
  3900. aFunc(FuncRec);
  3901. DestFD.Map(FuncRec.Dest, DestData, DestMD);
  3902. inc(FuncRec.Position.X);
  3903. end;
  3904. inc(FuncRec.Position.Y);
  3905. end;
  3906. // Updating Image or InternalFormat
  3907. if aCreateTemp then
  3908. SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height) //be careful, Data could be freed by this method
  3909. else if (aFormat <> fFormat) then
  3910. Format := aFormat;
  3911. result := true;
  3912. finally
  3913. SourceFD.FreeMappingData(SourceMD);
  3914. DestFD.FreeMappingData(DestMD);
  3915. end;
  3916. except
  3917. if aCreateTemp and Assigned(TmpData) then
  3918. FreeMem(TmpData);
  3919. raise;
  3920. end;
  3921. end;
  3922. end;
  3923. {$IFDEF GLB_SDL}
  3924. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3925. function TglBitmap.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
  3926. var
  3927. Row, RowSize: Integer;
  3928. SourceData, TmpData: PByte;
  3929. TempDepth: Integer;
  3930. FormatDesc: TFormatDescriptor;
  3931. function GetRowPointer(Row: Integer): pByte;
  3932. begin
  3933. result := aSurface.pixels;
  3934. Inc(result, Row * RowSize);
  3935. end;
  3936. begin
  3937. result := false;
  3938. FormatDesc := TFormatDescriptor.Get(Format);
  3939. if FormatDesc.IsCompressed then
  3940. raise EglBitmapUnsupportedFormat.Create(Format);
  3941. if Assigned(Data) then begin
  3942. case Trunc(FormatDesc.PixelSize) of
  3943. 1: TempDepth := 8;
  3944. 2: TempDepth := 16;
  3945. 3: TempDepth := 24;
  3946. 4: TempDepth := 32;
  3947. else
  3948. raise EglBitmapUnsupportedFormat.Create(Format);
  3949. end;
  3950. aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
  3951. FormatDesc.RedMask, FormatDesc.GreenMask, FormatDesc.BlueMask, FormatDesc.AlphaMask);
  3952. SourceData := Data;
  3953. RowSize := FormatDesc.GetSize(FileWidth, 1);
  3954. for Row := 0 to FileHeight-1 do begin
  3955. TmpData := GetRowPointer(Row);
  3956. if Assigned(TmpData) then begin
  3957. Move(SourceData^, TmpData^, RowSize);
  3958. inc(SourceData, RowSize);
  3959. end;
  3960. end;
  3961. result := true;
  3962. end;
  3963. end;
  3964. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3965. function TglBitmap.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
  3966. var
  3967. pSource, pData, pTempData: PByte;
  3968. Row, RowSize, TempWidth, TempHeight: Integer;
  3969. IntFormat: TglBitmapFormat;
  3970. FormatDesc: TFormatDescriptor;
  3971. function GetRowPointer(Row: Integer): pByte;
  3972. begin
  3973. result := aSurface^.pixels;
  3974. Inc(result, Row * RowSize);
  3975. end;
  3976. begin
  3977. result := false;
  3978. if (Assigned(aSurface)) then begin
  3979. with aSurface^.format^ do begin
  3980. for IntFormat := High(TglBitmapFormat) to Low(TglBitmapFormat) do begin
  3981. FormatDesc := TFormatDescriptor.Get(IntFormat);
  3982. if (FormatDesc.MaskMatch(RMask, GMask, BMask, AMask)) then
  3983. break;
  3984. end;
  3985. if (IntFormat = tfEmpty) then
  3986. raise EglBitmapException.Create('AssignFromSurface - Invalid Pixelformat.');
  3987. end;
  3988. TempWidth := aSurface^.w;
  3989. TempHeight := aSurface^.h;
  3990. RowSize := FormatDesc.GetSize(TempWidth, 1);
  3991. GetMem(pData, TempHeight * RowSize);
  3992. try
  3993. pTempData := pData;
  3994. for Row := 0 to TempHeight -1 do begin
  3995. pSource := GetRowPointer(Row);
  3996. if (Assigned(pSource)) then begin
  3997. Move(pSource^, pTempData^, RowSize);
  3998. Inc(pTempData, RowSize);
  3999. end;
  4000. end;
  4001. SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
  4002. result := true;
  4003. except
  4004. if Assigned(pData) then
  4005. FreeMem(pData);
  4006. raise;
  4007. end;
  4008. end;
  4009. end;
  4010. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4011. function TglBitmap.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
  4012. var
  4013. Row, Col, AlphaInterleave: Integer;
  4014. pSource, pDest: PByte;
  4015. function GetRowPointer(Row: Integer): pByte;
  4016. begin
  4017. result := aSurface.pixels;
  4018. Inc(result, Row * Width);
  4019. end;
  4020. begin
  4021. result := false;
  4022. if Assigned(Data) then begin
  4023. if Format in [tfAlpha8, tfLuminance8Alpha8, tfBGRA8, tfRGBA8] then begin
  4024. aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
  4025. AlphaInterleave := 0;
  4026. case Format of
  4027. tfLuminance8Alpha8:
  4028. AlphaInterleave := 1;
  4029. tfBGRA8, tfRGBA8:
  4030. AlphaInterleave := 3;
  4031. end;
  4032. pSource := Data;
  4033. for Row := 0 to Height -1 do begin
  4034. pDest := GetRowPointer(Row);
  4035. if Assigned(pDest) then begin
  4036. for Col := 0 to Width -1 do begin
  4037. Inc(pSource, AlphaInterleave);
  4038. pDest^ := pSource^;
  4039. Inc(pDest);
  4040. Inc(pSource);
  4041. end;
  4042. end;
  4043. end;
  4044. result := true;
  4045. end;
  4046. end;
  4047. end;
  4048. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4049. function TglBitmap.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  4050. var
  4051. bmp: TglBitmap2D;
  4052. begin
  4053. bmp := TglBitmap2D.Create;
  4054. try
  4055. bmp.AssignFromSurface(aSurface);
  4056. result := AddAlphaFromGlBitmap(bmp, aFunc, aArgs);
  4057. finally
  4058. bmp.Free;
  4059. end;
  4060. end;
  4061. {$ENDIF}
  4062. {$IFDEF GLB_DELPHI}
  4063. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4064. function CreateGrayPalette: HPALETTE;
  4065. var
  4066. Idx: Integer;
  4067. Pal: PLogPalette;
  4068. begin
  4069. GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
  4070. Pal.palVersion := $300;
  4071. Pal.palNumEntries := 256;
  4072. for Idx := 0 to Pal.palNumEntries - 1 do begin
  4073. Pal.palPalEntry[Idx].peRed := Idx;
  4074. Pal.palPalEntry[Idx].peGreen := Idx;
  4075. Pal.palPalEntry[Idx].peBlue := Idx;
  4076. Pal.palPalEntry[Idx].peFlags := 0;
  4077. end;
  4078. Result := CreatePalette(Pal^);
  4079. FreeMem(Pal);
  4080. end;
  4081. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4082. function TglBitmap.AssignToBitmap(const aBitmap: TBitmap): Boolean;
  4083. var
  4084. Row: Integer;
  4085. pSource, pData: PByte;
  4086. begin
  4087. result := false;
  4088. if Assigned(Data) then begin
  4089. if Assigned(aBitmap) then begin
  4090. aBitmap.Width := Width;
  4091. aBitmap.Height := Height;
  4092. case Format of
  4093. tfAlpha8, tfLuminance8: begin
  4094. aBitmap.PixelFormat := pf8bit;
  4095. aBitmap.Palette := CreateGrayPalette;
  4096. end;
  4097. tfRGB5A1:
  4098. aBitmap.PixelFormat := pf15bit;
  4099. tfR5G6B5:
  4100. aBitmap.PixelFormat := pf16bit;
  4101. tfRGB8, tfBGR8:
  4102. aBitmap.PixelFormat := pf24bit;
  4103. tfRGBA8, tfBGRA8:
  4104. aBitmap.PixelFormat := pf32bit;
  4105. else
  4106. raise EglBitmapException.Create('AssignToBitmap - Invalid Pixelformat.');
  4107. end;
  4108. pSource := Data;
  4109. for Row := 0 to FileHeight -1 do begin
  4110. pData := aBitmap.Scanline[Row];
  4111. Move(pSource^, pData^, fRowSize);
  4112. Inc(pSource, fRowSize);
  4113. if (Format in [tfRGB8, tfRGBA8]) then // swap RGB(A) to BGR(A)
  4114. SwapRGB(pData, FileWidth, Format = tfRGBA8);
  4115. end;
  4116. result := true;
  4117. end;
  4118. end;
  4119. end;
  4120. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4121. function TglBitmap.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
  4122. var
  4123. pSource, pData, pTempData: PByte;
  4124. Row, RowSize, TempWidth, TempHeight: Integer;
  4125. IntFormat: TglBitmapFormat;
  4126. begin
  4127. result := false;
  4128. if (Assigned(aBitmap)) then begin
  4129. case aBitmap.PixelFormat of
  4130. pf8bit:
  4131. IntFormat := tfLuminance8;
  4132. pf15bit:
  4133. IntFormat := tfRGB5A1;
  4134. pf16bit:
  4135. IntFormat := tfR5G6B5;
  4136. pf24bit:
  4137. IntFormat := tfBGR8;
  4138. pf32bit:
  4139. IntFormat := tfBGRA8;
  4140. else
  4141. raise EglBitmapException.Create('AssignFromBitmap - Invalid Pixelformat.');
  4142. end;
  4143. TempWidth := aBitmap.Width;
  4144. TempHeight := aBitmap.Height;
  4145. RowSize := TFormatDescriptor.Get(IntFormat).GetSize(TempWidth, 1);
  4146. GetMem(pData, TempHeight * RowSize);
  4147. try
  4148. pTempData := pData;
  4149. for Row := 0 to TempHeight -1 do begin
  4150. pSource := aBitmap.Scanline[Row];
  4151. if (Assigned(pSource)) then begin
  4152. Move(pSource^, pTempData^, RowSize);
  4153. Inc(pTempData, RowSize);
  4154. end;
  4155. end;
  4156. SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
  4157. result := true;
  4158. except
  4159. if Assigned(pData) then
  4160. FreeMem(pData);
  4161. raise;
  4162. end;
  4163. end;
  4164. end;
  4165. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4166. function TglBitmap.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
  4167. var
  4168. Row, Col, AlphaInterleave: Integer;
  4169. pSource, pDest: PByte;
  4170. begin
  4171. result := false;
  4172. if Assigned(Data) then begin
  4173. if (Format in [tfAlpha8, tfLuminance8Alpha8, tfRGBA8, tfBGRA8]) then begin
  4174. if Assigned(aBitmap) then begin
  4175. aBitmap.PixelFormat := pf8bit;
  4176. aBitmap.Palette := CreateGrayPalette;
  4177. aBitmap.Width := Width;
  4178. aBitmap.Height := Height;
  4179. case Format of
  4180. tfLuminance8Alpha8:
  4181. AlphaInterleave := 1;
  4182. tfRGBA8, tfBGRA8:
  4183. AlphaInterleave := 3;
  4184. else
  4185. AlphaInterleave := 0;
  4186. end;
  4187. // Copy Data
  4188. pSource := Data;
  4189. for Row := 0 to Height -1 do begin
  4190. pDest := aBitmap.Scanline[Row];
  4191. if Assigned(pDest) then begin
  4192. for Col := 0 to Width -1 do begin
  4193. Inc(pSource, AlphaInterleave);
  4194. pDest^ := pSource^;
  4195. Inc(pDest);
  4196. Inc(pSource);
  4197. end;
  4198. end;
  4199. end;
  4200. result := true;
  4201. end;
  4202. end;
  4203. end;
  4204. end;
  4205. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4206. function TglBitmap.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  4207. var
  4208. tex: TglBitmap2D;
  4209. begin
  4210. tex := TglBitmap2D.Create;
  4211. try
  4212. tex.AssignFromBitmap(ABitmap);
  4213. result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
  4214. finally
  4215. tex.Free;
  4216. end;
  4217. end;
  4218. {$ENDIF}
  4219. {$IFDEF GLB_LAZARUS}
  4220. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4221. function TglBitmap.AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
  4222. var
  4223. rid: TRawImageDescription;
  4224. FormatDesc: TFormatDescriptor;
  4225. begin
  4226. result := false;
  4227. if not Assigned(aImage) or (Format = tfEmpty) then
  4228. exit;
  4229. FormatDesc := TFormatDescriptor.Get(Format);
  4230. if FormatDesc.IsCompressed then
  4231. exit;
  4232. FillChar(rid{%H-}, SizeOf(rid), 0);
  4233. if (Format in [
  4234. tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16,
  4235. tfLuminance4, tfLuminance8, tfLuminance12, tfLuminance16,
  4236. tfLuminance4Alpha4, tfLuminance8Alpha8, tfLuminance12Alpha4, tfLuminance12Alpha12, tfLuminance16Alpha16]) then
  4237. rid.Format := ricfGray
  4238. else
  4239. rid.Format := ricfRGBA;
  4240. rid.Width := Width;
  4241. rid.Height := Height;
  4242. rid.Depth := CountSetBits(FormatDesc.Range.r or FormatDesc.Range.g or FormatDesc.Range.b or FormatDesc.Range.a);
  4243. rid.BitOrder := riboBitsInOrder;
  4244. rid.ByteOrder := riboLSBFirst;
  4245. rid.LineOrder := riloTopToBottom;
  4246. rid.LineEnd := rileTight;
  4247. rid.BitsPerPixel := Round(8 * FormatDesc.PixelSize);
  4248. rid.RedPrec := CountSetBits(FormatDesc.Range.r);
  4249. rid.GreenPrec := CountSetBits(FormatDesc.Range.g);
  4250. rid.BluePrec := CountSetBits(FormatDesc.Range.b);
  4251. rid.AlphaPrec := CountSetBits(FormatDesc.Range.a);
  4252. rid.RedShift := FormatDesc.Shift.r;
  4253. rid.GreenShift := FormatDesc.Shift.g;
  4254. rid.BlueShift := FormatDesc.Shift.b;
  4255. rid.AlphaShift := FormatDesc.Shift.a;
  4256. rid.MaskBitsPerPixel := 0;
  4257. rid.PaletteColorCount := 0;
  4258. aImage.DataDescription := rid;
  4259. aImage.CreateData;
  4260. Move(Data^, aImage.PixelData^, FormatDesc.GetSize(Dimension));
  4261. result := true;
  4262. end;
  4263. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4264. function TglBitmap.AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
  4265. var
  4266. f: TglBitmapFormat;
  4267. FormatDesc: TFormatDescriptor;
  4268. ImageData: PByte;
  4269. ImageSize: Integer;
  4270. begin
  4271. result := false;
  4272. if not Assigned(aImage) then
  4273. exit;
  4274. for f := High(f) downto Low(f) do begin
  4275. FormatDesc := TFormatDescriptor.Get(f);
  4276. with aImage.DataDescription do
  4277. if FormatDesc.MaskMatch(
  4278. (QWord(1 shl RedPrec )-1) shl RedShift,
  4279. (QWord(1 shl GreenPrec)-1) shl GreenShift,
  4280. (QWord(1 shl BluePrec )-1) shl BlueShift,
  4281. (QWord(1 shl AlphaPrec)-1) shl AlphaShift) then
  4282. break;
  4283. end;
  4284. if (f = tfEmpty) then
  4285. exit;
  4286. ImageSize := FormatDesc.GetSize(aImage.Width, aImage.Height);
  4287. ImageData := GetMem(ImageSize);
  4288. try
  4289. Move(aImage.PixelData^, ImageData^, (aImage.Width * aImage.Height * aImage.DataDescription.BitsPerPixel) shr 3);
  4290. SetDataPointer(ImageData, f, aImage.Width, aImage.Height); //be careful, Data could be freed by this method
  4291. except
  4292. if Assigned(ImageData) then
  4293. FreeMem(ImageData);
  4294. raise;
  4295. end;
  4296. result := true;
  4297. end;
  4298. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4299. function TglBitmap.AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
  4300. var
  4301. rid: TRawImageDescription;
  4302. FormatDesc: TFormatDescriptor;
  4303. Pixel: TglBitmapPixelData;
  4304. x, y: Integer;
  4305. srcMD: Pointer;
  4306. src, dst: PByte;
  4307. begin
  4308. result := false;
  4309. if not Assigned(aImage) or (Format = tfEmpty) then
  4310. exit;
  4311. FormatDesc := TFormatDescriptor.Get(Format);
  4312. if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
  4313. exit;
  4314. FillChar(rid{%H-}, SizeOf(rid), 0);
  4315. rid.Format := ricfGray;
  4316. rid.Width := Width;
  4317. rid.Height := Height;
  4318. rid.Depth := CountSetBits(FormatDesc.Range.a);
  4319. rid.BitOrder := riboBitsInOrder;
  4320. rid.ByteOrder := riboLSBFirst;
  4321. rid.LineOrder := riloTopToBottom;
  4322. rid.LineEnd := rileTight;
  4323. rid.BitsPerPixel := 8 * Ceil(rid.Depth / 8);
  4324. rid.RedPrec := CountSetBits(FormatDesc.Range.a);
  4325. rid.GreenPrec := 0;
  4326. rid.BluePrec := 0;
  4327. rid.AlphaPrec := 0;
  4328. rid.RedShift := 0;
  4329. rid.GreenShift := 0;
  4330. rid.BlueShift := 0;
  4331. rid.AlphaShift := 0;
  4332. rid.MaskBitsPerPixel := 0;
  4333. rid.PaletteColorCount := 0;
  4334. aImage.DataDescription := rid;
  4335. aImage.CreateData;
  4336. srcMD := FormatDesc.CreateMappingData;
  4337. try
  4338. FormatDesc.PreparePixel(Pixel);
  4339. src := Data;
  4340. dst := aImage.PixelData;
  4341. for y := 0 to Height-1 do
  4342. for x := 0 to Width-1 do begin
  4343. FormatDesc.Unmap(src, Pixel, srcMD);
  4344. case rid.BitsPerPixel of
  4345. 8: begin
  4346. dst^ := Pixel.Data.a;
  4347. inc(dst);
  4348. end;
  4349. 16: begin
  4350. PWord(dst)^ := Pixel.Data.a;
  4351. inc(dst, 2);
  4352. end;
  4353. 24: begin
  4354. PByteArray(dst)^[0] := PByteArray(@Pixel.Data.a)^[0];
  4355. PByteArray(dst)^[1] := PByteArray(@Pixel.Data.a)^[1];
  4356. PByteArray(dst)^[2] := PByteArray(@Pixel.Data.a)^[2];
  4357. inc(dst, 3);
  4358. end;
  4359. 32: begin
  4360. PCardinal(dst)^ := Pixel.Data.a;
  4361. inc(dst, 4);
  4362. end;
  4363. else
  4364. raise EglBitmapUnsupportedFormat.Create(Format);
  4365. end;
  4366. end;
  4367. finally
  4368. FormatDesc.FreeMappingData(srcMD);
  4369. end;
  4370. result := true;
  4371. end;
  4372. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4373. function TglBitmap.AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  4374. var
  4375. tex: TglBitmap2D;
  4376. begin
  4377. tex := TglBitmap2D.Create;
  4378. try
  4379. tex.AssignFromLazIntfImage(aImage);
  4380. result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
  4381. finally
  4382. tex.Free;
  4383. end;
  4384. end;
  4385. {$ENDIF}
  4386. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4387. function TglBitmap.AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar;
  4388. const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  4389. var
  4390. rs: TResourceStream;
  4391. begin
  4392. PrepareResType(aResource, aResType);
  4393. rs := TResourceStream.Create(aInstance, aResource, aResType);
  4394. try
  4395. result := AddAlphaFromStream(rs, aFunc, aArgs);
  4396. finally
  4397. rs.Free;
  4398. end;
  4399. end;
  4400. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4401. function TglBitmap.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
  4402. const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  4403. var
  4404. rs: TResourceStream;
  4405. begin
  4406. rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
  4407. try
  4408. result := AddAlphaFromStream(rs, aFunc, aArgs);
  4409. finally
  4410. rs.Free;
  4411. end;
  4412. end;
  4413. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4414. function TglBitmap.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  4415. begin
  4416. if TFormatDescriptor.Get(Format).IsCompressed then
  4417. raise EglBitmapUnsupportedFormat.Create(Format);
  4418. result := AddFunc(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs);
  4419. end;
  4420. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4421. function TglBitmap.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  4422. var
  4423. FS: TFileStream;
  4424. begin
  4425. FS := TFileStream.Create(aFileName, fmOpenRead);
  4426. try
  4427. result := AddAlphaFromStream(FS, aFunc, aArgs);
  4428. finally
  4429. FS.Free;
  4430. end;
  4431. end;
  4432. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4433. function TglBitmap.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  4434. var
  4435. tex: TglBitmap2D;
  4436. begin
  4437. tex := TglBitmap2D.Create(aStream);
  4438. try
  4439. result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
  4440. finally
  4441. tex.Free;
  4442. end;
  4443. end;
  4444. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4445. function TglBitmap.AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  4446. var
  4447. DestData, DestData2, SourceData: pByte;
  4448. TempHeight, TempWidth: Integer;
  4449. SourceFD, DestFD: TFormatDescriptor;
  4450. SourceMD, DestMD, DestMD2: Pointer;
  4451. FuncRec: TglBitmapFunctionRec;
  4452. begin
  4453. result := false;
  4454. Assert(Assigned(Data));
  4455. Assert(Assigned(aBitmap));
  4456. Assert(Assigned(aBitmap.Data));
  4457. if ((aBitmap.Width = Width) and (aBitmap.Height = Height)) then begin
  4458. result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
  4459. SourceFD := TFormatDescriptor.Get(aBitmap.Format);
  4460. DestFD := TFormatDescriptor.Get(Format);
  4461. if not Assigned(aFunc) then begin
  4462. aFunc := glBitmapAlphaFunc;
  4463. FuncRec.Args := {%H-}Pointer(SourceFD.HasAlpha);
  4464. end else
  4465. FuncRec.Args := aArgs;
  4466. // Values
  4467. TempHeight := aBitmap.FileHeight;
  4468. TempWidth := aBitmap.FileWidth;
  4469. FuncRec.Sender := Self;
  4470. FuncRec.Size := Dimension;
  4471. FuncRec.Position.Fields := FuncRec.Size.Fields;
  4472. DestData := Data;
  4473. DestData2 := Data;
  4474. SourceData := aBitmap.Data;
  4475. // Mapping
  4476. SourceFD.PreparePixel(FuncRec.Source);
  4477. DestFD.PreparePixel (FuncRec.Dest);
  4478. SourceMD := SourceFD.CreateMappingData;
  4479. DestMD := DestFD.CreateMappingData;
  4480. DestMD2 := DestFD.CreateMappingData;
  4481. try
  4482. FuncRec.Position.Y := 0;
  4483. while FuncRec.Position.Y < TempHeight do begin
  4484. FuncRec.Position.X := 0;
  4485. while FuncRec.Position.X < TempWidth do begin
  4486. SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
  4487. DestFD.Unmap (DestData, FuncRec.Dest, DestMD);
  4488. aFunc(FuncRec);
  4489. DestFD.Map(FuncRec.Dest, DestData2, DestMD2);
  4490. inc(FuncRec.Position.X);
  4491. end;
  4492. inc(FuncRec.Position.Y);
  4493. end;
  4494. finally
  4495. SourceFD.FreeMappingData(SourceMD);
  4496. DestFD.FreeMappingData(DestMD);
  4497. DestFD.FreeMappingData(DestMD2);
  4498. end;
  4499. end;
  4500. end;
  4501. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4502. function TglBitmap.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
  4503. begin
  4504. result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
  4505. end;
  4506. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4507. function TglBitmap.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
  4508. var
  4509. PixelData: TglBitmapPixelData;
  4510. begin
  4511. TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
  4512. result := AddAlphaFromColorKeyFloat(
  4513. aRed / PixelData.Range.r,
  4514. aGreen / PixelData.Range.g,
  4515. aBlue / PixelData.Range.b,
  4516. aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b)));
  4517. end;
  4518. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4519. function TglBitmap.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
  4520. var
  4521. values: array[0..2] of Single;
  4522. tmp: Cardinal;
  4523. i: Integer;
  4524. PixelData: TglBitmapPixelData;
  4525. begin
  4526. TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
  4527. with PixelData do begin
  4528. values[0] := aRed;
  4529. values[1] := aGreen;
  4530. values[2] := aBlue;
  4531. for i := 0 to 2 do begin
  4532. tmp := Trunc(Range.arr[i] * aDeviation);
  4533. Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp));
  4534. Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp));
  4535. end;
  4536. Data.a := 0;
  4537. Range.a := 0;
  4538. end;
  4539. result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, @PixelData);
  4540. end;
  4541. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4542. function TglBitmap.AddAlphaFromValue(const aAlpha: Byte): Boolean;
  4543. begin
  4544. result := AddAlphaFromValueFloat(aAlpha / $FF);
  4545. end;
  4546. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4547. function TglBitmap.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
  4548. var
  4549. PixelData: TglBitmapPixelData;
  4550. begin
  4551. TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
  4552. result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
  4553. end;
  4554. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4555. function TglBitmap.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
  4556. var
  4557. PixelData: TglBitmapPixelData;
  4558. begin
  4559. TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
  4560. with PixelData do
  4561. Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
  4562. result := AddAlphaFromFunc(glBitmapValueAlphaFunc, @PixelData.Data.a);
  4563. end;
  4564. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4565. function TglBitmap.RemoveAlpha: Boolean;
  4566. var
  4567. FormatDesc: TFormatDescriptor;
  4568. begin
  4569. result := false;
  4570. FormatDesc := TFormatDescriptor.Get(Format);
  4571. if Assigned(Data) then begin
  4572. if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
  4573. raise EglBitmapUnsupportedFormat.Create(Format);
  4574. result := ConvertTo(FormatDesc.WithoutAlpha);
  4575. end;
  4576. end;
  4577. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4578. function TglBitmap.Clone: TglBitmap;
  4579. var
  4580. Temp: TglBitmap;
  4581. TempPtr: PByte;
  4582. Size: Integer;
  4583. begin
  4584. result := nil;
  4585. Temp := (ClassType.Create as TglBitmap);
  4586. try
  4587. // copy texture data if assigned
  4588. if Assigned(Data) then begin
  4589. Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
  4590. GetMem(TempPtr, Size);
  4591. try
  4592. Move(Data^, TempPtr^, Size);
  4593. Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
  4594. except
  4595. if Assigned(TempPtr) then
  4596. FreeMem(TempPtr);
  4597. raise;
  4598. end;
  4599. end else begin
  4600. TempPtr := nil;
  4601. Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
  4602. end;
  4603. // copy properties
  4604. Temp.fID := ID;
  4605. Temp.fTarget := Target;
  4606. Temp.fFormat := Format;
  4607. Temp.fMipMap := MipMap;
  4608. Temp.fAnisotropic := Anisotropic;
  4609. Temp.fBorderColor := fBorderColor;
  4610. Temp.fDeleteTextureOnFree := DeleteTextureOnFree;
  4611. Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
  4612. Temp.fFilterMin := fFilterMin;
  4613. Temp.fFilterMag := fFilterMag;
  4614. Temp.fWrapS := fWrapS;
  4615. Temp.fWrapT := fWrapT;
  4616. Temp.fWrapR := fWrapR;
  4617. Temp.fFilename := fFilename;
  4618. Temp.fCustomName := fCustomName;
  4619. Temp.fCustomNameW := fCustomNameW;
  4620. Temp.fCustomData := fCustomData;
  4621. result := Temp;
  4622. except
  4623. FreeAndNil(Temp);
  4624. raise;
  4625. end;
  4626. end;
  4627. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4628. function TglBitmap.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
  4629. var
  4630. SourceFD, DestFD: TFormatDescriptor;
  4631. SourcePD, DestPD: TglBitmapPixelData;
  4632. ShiftData: TShiftData;
  4633. function CanCopyDirect: Boolean;
  4634. begin
  4635. result :=
  4636. ((SourcePD.Range.r = DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
  4637. ((SourcePD.Range.g = DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
  4638. ((SourcePD.Range.b = DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
  4639. ((SourcePD.Range.a = DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
  4640. end;
  4641. function CanShift: Boolean;
  4642. begin
  4643. result :=
  4644. ((SourcePD.Range.r >= DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
  4645. ((SourcePD.Range.g >= DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
  4646. ((SourcePD.Range.b >= DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
  4647. ((SourcePD.Range.a >= DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
  4648. end;
  4649. function GetShift(aSource, aDest: Cardinal) : ShortInt;
  4650. begin
  4651. result := 0;
  4652. while (aSource > aDest) and (aSource > 0) do begin
  4653. inc(result);
  4654. aSource := aSource shr 1;
  4655. end;
  4656. end;
  4657. begin
  4658. if (aFormat <> fFormat) and (aFormat <> tfEmpty) then begin
  4659. SourceFD := TFormatDescriptor.Get(Format);
  4660. DestFD := TFormatDescriptor.Get(aFormat);
  4661. SourceFD.PreparePixel(SourcePD);
  4662. DestFD.PreparePixel (DestPD);
  4663. if CanCopyDirect then
  4664. result := AddFunc(Self, glBitmapConvertCopyFunc, false, aFormat)
  4665. else if CanShift then begin
  4666. ShiftData.r := GetShift(SourcePD.Range.r, DestPD.Range.r);
  4667. ShiftData.g := GetShift(SourcePD.Range.g, DestPD.Range.g);
  4668. ShiftData.b := GetShift(SourcePD.Range.b, DestPD.Range.b);
  4669. ShiftData.a := GetShift(SourcePD.Range.a, DestPD.Range.a);
  4670. result := AddFunc(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, @ShiftData);
  4671. end else
  4672. result := AddFunc(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
  4673. end else
  4674. result := true;
  4675. end;
  4676. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4677. procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
  4678. begin
  4679. if aUseRGB or aUseAlpha then
  4680. AddFunc(glBitmapInvertFunc, false, {%H-}Pointer(
  4681. ((PtrInt(aUseAlpha) and 1) shl 1) or
  4682. (PtrInt(aUseRGB) and 1) ));
  4683. end;
  4684. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4685. procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
  4686. begin
  4687. fBorderColor[0] := aRed;
  4688. fBorderColor[1] := aGreen;
  4689. fBorderColor[2] := aBlue;
  4690. fBorderColor[3] := aAlpha;
  4691. if (ID > 0) then begin
  4692. Bind(false);
  4693. glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
  4694. end;
  4695. end;
  4696. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4697. procedure TglBitmap.FreeData;
  4698. var
  4699. TempPtr: PByte;
  4700. begin
  4701. TempPtr := nil;
  4702. SetDataPointer(TempPtr, tfEmpty); //be careful, Data could be freed by this method
  4703. end;
  4704. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4705. procedure TglBitmap.FillWithColor(const aRed, aGreen, aBlue: Byte;
  4706. const aAlpha: Byte);
  4707. begin
  4708. FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
  4709. end;
  4710. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4711. procedure TglBitmap.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
  4712. var
  4713. PixelData: TglBitmapPixelData;
  4714. begin
  4715. TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
  4716. FillWithColorFloat(
  4717. aRed / PixelData.Range.r,
  4718. aGreen / PixelData.Range.g,
  4719. aBlue / PixelData.Range.b,
  4720. aAlpha / PixelData.Range.a);
  4721. end;
  4722. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4723. procedure TglBitmap.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
  4724. var
  4725. PixelData: TglBitmapPixelData;
  4726. begin
  4727. TFormatDescriptor.Get(Format).PreparePixel(PixelData);
  4728. with PixelData do begin
  4729. Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed)));
  4730. Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen)));
  4731. Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue)));
  4732. Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha)));
  4733. end;
  4734. AddFunc(glBitmapFillWithColorFunc, false, @PixelData);
  4735. end;
  4736. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4737. procedure TglBitmap.SetFilter(const aMin, aMag: GLenum);
  4738. begin
  4739. //check MIN filter
  4740. case aMin of
  4741. GL_NEAREST:
  4742. fFilterMin := GL_NEAREST;
  4743. GL_LINEAR:
  4744. fFilterMin := GL_LINEAR;
  4745. GL_NEAREST_MIPMAP_NEAREST:
  4746. fFilterMin := GL_NEAREST_MIPMAP_NEAREST;
  4747. GL_LINEAR_MIPMAP_NEAREST:
  4748. fFilterMin := GL_LINEAR_MIPMAP_NEAREST;
  4749. GL_NEAREST_MIPMAP_LINEAR:
  4750. fFilterMin := GL_NEAREST_MIPMAP_LINEAR;
  4751. GL_LINEAR_MIPMAP_LINEAR:
  4752. fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
  4753. else
  4754. raise EglBitmap.Create('SetFilter - Unknow MIN filter.');
  4755. end;
  4756. //check MAG filter
  4757. case aMag of
  4758. GL_NEAREST:
  4759. fFilterMag := GL_NEAREST;
  4760. GL_LINEAR:
  4761. fFilterMag := GL_LINEAR;
  4762. else
  4763. raise EglBitmap.Create('SetFilter - Unknow MAG filter.');
  4764. end;
  4765. //apply filter
  4766. if (ID > 0) then begin
  4767. Bind(false);
  4768. glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
  4769. if (MipMap = mmNone) or (Target = GL_TEXTURE_RECTANGLE) then begin
  4770. case fFilterMin of
  4771. GL_NEAREST, GL_LINEAR:
  4772. glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
  4773. GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR:
  4774. glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  4775. GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR:
  4776. glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  4777. end;
  4778. end else
  4779. glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
  4780. end;
  4781. end;
  4782. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4783. procedure TglBitmap.SetWrap(const S: GLenum; const T: GLenum; const R: GLenum);
  4784. procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
  4785. begin
  4786. case aValue of
  4787. GL_CLAMP:
  4788. aTarget := GL_CLAMP;
  4789. GL_REPEAT:
  4790. aTarget := GL_REPEAT;
  4791. GL_CLAMP_TO_EDGE: begin
  4792. if GL_VERSION_1_2 or GL_EXT_texture_edge_clamp then
  4793. aTarget := GL_CLAMP_TO_EDGE
  4794. else
  4795. aTarget := GL_CLAMP;
  4796. end;
  4797. GL_CLAMP_TO_BORDER: begin
  4798. if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
  4799. aTarget := GL_CLAMP_TO_BORDER
  4800. else
  4801. aTarget := GL_CLAMP;
  4802. end;
  4803. GL_MIRRORED_REPEAT: begin
  4804. if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
  4805. aTarget := GL_MIRRORED_REPEAT
  4806. else
  4807. raise EglBitmap.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
  4808. end;
  4809. else
  4810. raise EglBitmap.Create('SetWrap - Unknow Texturewrap');
  4811. end;
  4812. end;
  4813. begin
  4814. CheckAndSetWrap(S, fWrapS);
  4815. CheckAndSetWrap(T, fWrapT);
  4816. CheckAndSetWrap(R, fWrapR);
  4817. if (ID > 0) then begin
  4818. Bind(false);
  4819. glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
  4820. glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
  4821. glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
  4822. end;
  4823. end;
  4824. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4825. procedure TglBitmap.SetSwizzle(const r, g, b, a: GLenum);
  4826. procedure CheckAndSetValue(const aValue: GLenum; const aIndex: Integer);
  4827. begin
  4828. if (aValue = GL_ZERO) or (aValue = GL_ONE) or (aValue = GL_ALPHA) or
  4829. (aValue = GL_RED) or (aValue = GL_GREEN) or (aValue = GL_BLUE) then
  4830. fSwizzle[aIndex] := aValue
  4831. else
  4832. raise EglBitmap.Create('SetSwizzle - Unknow Swizle Value');
  4833. end;
  4834. begin
  4835. if not (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
  4836. raise EglBitmapNotSupported.Create('texture swizzle is not supported');
  4837. CheckAndSetValue(r, 0);
  4838. CheckAndSetValue(g, 1);
  4839. CheckAndSetValue(b, 2);
  4840. CheckAndSetValue(a, 3);
  4841. if (ID > 0) then begin
  4842. Bind(false);
  4843. glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_RGBA, @fSwizzle[0]);
  4844. end;
  4845. end;
  4846. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4847. procedure TglBitmap.Bind(const aEnableTextureUnit: Boolean);
  4848. begin
  4849. if aEnableTextureUnit then
  4850. glEnable(Target);
  4851. if (ID > 0) then
  4852. glBindTexture(Target, ID);
  4853. end;
  4854. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4855. procedure TglBitmap.Unbind(const aDisableTextureUnit: Boolean);
  4856. begin
  4857. if aDisableTextureUnit then
  4858. glDisable(Target);
  4859. glBindTexture(Target, 0);
  4860. end;
  4861. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4862. constructor TglBitmap.Create;
  4863. begin
  4864. if (ClassType = TglBitmap) then
  4865. raise EglBitmap.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
  4866. {$IFDEF GLB_NATIVE_OGL}
  4867. glbReadOpenGLExtensions;
  4868. {$ENDIF}
  4869. inherited Create;
  4870. end;
  4871. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4872. constructor TglBitmap.Create(const aFileName: String);
  4873. begin
  4874. Create;
  4875. LoadFromFile(aFileName);
  4876. end;
  4877. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4878. constructor TglBitmap.Create(const aStream: TStream);
  4879. begin
  4880. Create;
  4881. LoadFromStream(aStream);
  4882. end;
  4883. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4884. constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat);
  4885. var
  4886. Image: PByte;
  4887. ImageSize: Integer;
  4888. begin
  4889. Create;
  4890. ImageSize := TFormatDescriptor.Get(aFormat).GetSize(aSize);
  4891. GetMem(Image, ImageSize);
  4892. try
  4893. FillChar(Image^, ImageSize, #$FF);
  4894. SetDataPointer(Image, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
  4895. except
  4896. if Assigned(Image) then
  4897. FreeMem(Image);
  4898. raise;
  4899. end;
  4900. end;
  4901. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4902. constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat;
  4903. const aFunc: TglBitmapFunction; const aArgs: Pointer);
  4904. begin
  4905. Create;
  4906. LoadFromFunc(aSize, aFunc, aFormat, aArgs);
  4907. end;
  4908. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4909. constructor TglBitmap.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
  4910. begin
  4911. Create;
  4912. LoadFromResource(aInstance, aResource, aResType);
  4913. end;
  4914. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4915. constructor TglBitmap.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
  4916. begin
  4917. Create;
  4918. LoadFromResourceID(aInstance, aResourceID, aResType);
  4919. end;
  4920. {$IFDEF GLB_SUPPORT_PNG_READ}
  4921. {$IF DEFINED(GLB_SDL_IMAGE)}
  4922. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4923. //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4924. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4925. function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
  4926. var
  4927. Surface: PSDL_Surface;
  4928. RWops: PSDL_RWops;
  4929. begin
  4930. result := false;
  4931. RWops := glBitmapCreateRWops(aStream);
  4932. try
  4933. if IMG_isPNG(RWops) > 0 then begin
  4934. Surface := IMG_LoadPNG_RW(RWops);
  4935. try
  4936. AssignFromSurface(Surface);
  4937. result := true;
  4938. finally
  4939. SDL_FreeSurface(Surface);
  4940. end;
  4941. end;
  4942. finally
  4943. SDL_FreeRW(RWops);
  4944. end;
  4945. end;
  4946. {$ELSEIF DEFINED(GLB_LIB_PNG)}
  4947. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4948. procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
  4949. begin
  4950. TStream(png_get_io_ptr(png)).Read(buffer^, size);
  4951. end;
  4952. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4953. function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
  4954. var
  4955. StreamPos: Int64;
  4956. signature: array [0..7] of byte;
  4957. png: png_structp;
  4958. png_info: png_infop;
  4959. TempHeight, TempWidth: Integer;
  4960. Format: TglBitmapFormat;
  4961. png_data: pByte;
  4962. png_rows: array of pByte;
  4963. Row, LineSize: Integer;
  4964. begin
  4965. result := false;
  4966. if not init_libPNG then
  4967. raise Exception.Create('LoadPNG - unable to initialize libPNG.');
  4968. try
  4969. // signature
  4970. StreamPos := aStream.Position;
  4971. aStream.Read(signature{%H-}, 8);
  4972. aStream.Position := StreamPos;
  4973. if png_check_sig(@signature, 8) <> 0 then begin
  4974. // png read struct
  4975. png := png_create_read_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
  4976. if png = nil then
  4977. raise EglBitmapException.Create('LoadPng - couldn''t create read struct.');
  4978. // png info
  4979. png_info := png_create_info_struct(png);
  4980. if png_info = nil then begin
  4981. png_destroy_read_struct(@png, nil, nil);
  4982. raise EglBitmapException.Create('LoadPng - couldn''t create info struct.');
  4983. end;
  4984. // set read callback
  4985. png_set_read_fn(png, aStream, glBitmap_libPNG_read_func);
  4986. // read informations
  4987. png_read_info(png, png_info);
  4988. // size
  4989. TempHeight := png_get_image_height(png, png_info);
  4990. TempWidth := png_get_image_width(png, png_info);
  4991. // format
  4992. case png_get_color_type(png, png_info) of
  4993. PNG_COLOR_TYPE_GRAY:
  4994. Format := tfLuminance8;
  4995. PNG_COLOR_TYPE_GRAY_ALPHA:
  4996. Format := tfLuminance8Alpha8;
  4997. PNG_COLOR_TYPE_RGB:
  4998. Format := tfRGB8;
  4999. PNG_COLOR_TYPE_RGB_ALPHA:
  5000. Format := tfRGBA8;
  5001. else
  5002. raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
  5003. end;
  5004. // cut upper 8 bit from 16 bit formats
  5005. if png_get_bit_depth(png, png_info) > 8 then
  5006. png_set_strip_16(png);
  5007. // expand bitdepth smaller than 8
  5008. if png_get_bit_depth(png, png_info) < 8 then
  5009. png_set_expand(png);
  5010. // allocating mem for scanlines
  5011. LineSize := png_get_rowbytes(png, png_info);
  5012. GetMem(png_data, TempHeight * LineSize);
  5013. try
  5014. SetLength(png_rows, TempHeight);
  5015. for Row := Low(png_rows) to High(png_rows) do begin
  5016. png_rows[Row] := png_data;
  5017. Inc(png_rows[Row], Row * LineSize);
  5018. end;
  5019. // read complete image into scanlines
  5020. png_read_image(png, @png_rows[0]);
  5021. // read end
  5022. png_read_end(png, png_info);
  5023. // destroy read struct
  5024. png_destroy_read_struct(@png, @png_info, nil);
  5025. SetLength(png_rows, 0);
  5026. // set new data
  5027. SetDataPointer(png_data, Format, TempWidth, TempHeight); //be careful, Data could be freed by this method
  5028. result := true;
  5029. except
  5030. if Assigned(png_data) then
  5031. FreeMem(png_data);
  5032. raise;
  5033. end;
  5034. end;
  5035. finally
  5036. quit_libPNG;
  5037. end;
  5038. end;
  5039. {$ELSEIF DEFINED(GLB_PNGIMAGE)}
  5040. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5041. function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
  5042. var
  5043. StreamPos: Int64;
  5044. Png: TPNGObject;
  5045. Header: String[8];
  5046. Row, Col, PixSize, LineSize: Integer;
  5047. NewImage, pSource, pDest, pAlpha: pByte;
  5048. PngFormat: TglBitmapFormat;
  5049. FormatDesc: TFormatDescriptor;
  5050. const
  5051. PngHeader: String[8] = #137#80#78#71#13#10#26#10;
  5052. begin
  5053. result := false;
  5054. StreamPos := aStream.Position;
  5055. aStream.Read(Header[0], SizeOf(Header));
  5056. aStream.Position := StreamPos;
  5057. {Test if the header matches}
  5058. if Header = PngHeader then begin
  5059. Png := TPNGObject.Create;
  5060. try
  5061. Png.LoadFromStream(aStream);
  5062. case Png.Header.ColorType of
  5063. COLOR_GRAYSCALE:
  5064. PngFormat := tfLuminance8;
  5065. COLOR_GRAYSCALEALPHA:
  5066. PngFormat := tfLuminance8Alpha8;
  5067. COLOR_RGB:
  5068. PngFormat := tfBGR8;
  5069. COLOR_RGBALPHA:
  5070. PngFormat := tfBGRA8;
  5071. else
  5072. raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
  5073. end;
  5074. FormatDesc := TFormatDescriptor.Get(PngFormat);
  5075. PixSize := Round(FormatDesc.PixelSize);
  5076. LineSize := FormatDesc.GetSize(Png.Header.Width, 1);
  5077. GetMem(NewImage, LineSize * Integer(Png.Header.Height));
  5078. try
  5079. pDest := NewImage;
  5080. case Png.Header.ColorType of
  5081. COLOR_RGB, COLOR_GRAYSCALE:
  5082. begin
  5083. for Row := 0 to Png.Height -1 do begin
  5084. Move (Png.Scanline[Row]^, pDest^, LineSize);
  5085. Inc(pDest, LineSize);
  5086. end;
  5087. end;
  5088. COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA:
  5089. begin
  5090. PixSize := PixSize -1;
  5091. for Row := 0 to Png.Height -1 do begin
  5092. pSource := Png.Scanline[Row];
  5093. pAlpha := pByte(Png.AlphaScanline[Row]);
  5094. for Col := 0 to Png.Width -1 do begin
  5095. Move (pSource^, pDest^, PixSize);
  5096. Inc(pSource, PixSize);
  5097. Inc(pDest, PixSize);
  5098. pDest^ := pAlpha^;
  5099. inc(pAlpha);
  5100. Inc(pDest);
  5101. end;
  5102. end;
  5103. end;
  5104. else
  5105. raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
  5106. end;
  5107. SetDataPointer(NewImage, PngFormat, Png.Header.Width, Png.Header.Height); //be careful, Data could be freed by this method
  5108. result := true;
  5109. except
  5110. if Assigned(NewImage) then
  5111. FreeMem(NewImage);
  5112. raise;
  5113. end;
  5114. finally
  5115. Png.Free;
  5116. end;
  5117. end;
  5118. end;
  5119. {$IFEND}
  5120. {$ENDIF}
  5121. {$IFDEF GLB_SUPPORT_PNG_WRITE}
  5122. {$IFDEF GLB_LIB_PNG}
  5123. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5124. procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
  5125. begin
  5126. TStream(png_get_io_ptr(png)).Write(buffer^, size);
  5127. end;
  5128. {$ENDIF}
  5129. {$IF DEFINED(GLB_LIB_PNG)}
  5130. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5131. procedure TglBitmap.SavePNG(const aStream: TStream);
  5132. var
  5133. png: png_structp;
  5134. png_info: png_infop;
  5135. png_rows: array of pByte;
  5136. LineSize: Integer;
  5137. ColorType: Integer;
  5138. Row: Integer;
  5139. FormatDesc: TFormatDescriptor;
  5140. begin
  5141. if not (ftPNG in FormatGetSupportedFiles(Format)) then
  5142. raise EglBitmapUnsupportedFormat.Create(Format);
  5143. if not init_libPNG then
  5144. raise Exception.Create('unable to initialize libPNG.');
  5145. try
  5146. case Format of
  5147. tfAlpha8, tfLuminance8:
  5148. ColorType := PNG_COLOR_TYPE_GRAY;
  5149. tfLuminance8Alpha8:
  5150. ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
  5151. tfBGR8, tfRGB8:
  5152. ColorType := PNG_COLOR_TYPE_RGB;
  5153. tfBGRA8, tfRGBA8:
  5154. ColorType := PNG_COLOR_TYPE_RGBA;
  5155. else
  5156. raise EglBitmapUnsupportedFormat.Create(Format);
  5157. end;
  5158. FormatDesc := TFormatDescriptor.Get(Format);
  5159. LineSize := FormatDesc.GetSize(Width, 1);
  5160. // creating array for scanline
  5161. SetLength(png_rows, Height);
  5162. try
  5163. for Row := 0 to Height - 1 do begin
  5164. png_rows[Row] := Data;
  5165. Inc(png_rows[Row], Row * LineSize)
  5166. end;
  5167. // write struct
  5168. png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
  5169. if png = nil then
  5170. raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
  5171. // create png info
  5172. png_info := png_create_info_struct(png);
  5173. if png_info = nil then begin
  5174. png_destroy_write_struct(@png, nil);
  5175. raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
  5176. end;
  5177. // set read callback
  5178. png_set_write_fn(png, aStream, glBitmap_libPNG_write_func, nil);
  5179. // set compression
  5180. png_set_compression_level(png, 6);
  5181. if Format in [tfBGR8, tfBGRA8] then
  5182. png_set_bgr(png);
  5183. png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
  5184. png_write_info(png, png_info);
  5185. png_write_image(png, @png_rows[0]);
  5186. png_write_end(png, png_info);
  5187. png_destroy_write_struct(@png, @png_info);
  5188. finally
  5189. SetLength(png_rows, 0);
  5190. end;
  5191. finally
  5192. quit_libPNG;
  5193. end;
  5194. end;
  5195. {$ELSEIF DEFINED(GLB_PNGIMAGE)}
  5196. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5197. procedure TglBitmap.SavePNG(const aStream: TStream);
  5198. var
  5199. Png: TPNGObject;
  5200. pSource, pDest: pByte;
  5201. X, Y, PixSize: Integer;
  5202. ColorType: Cardinal;
  5203. Alpha: Boolean;
  5204. pTemp: pByte;
  5205. Temp: Byte;
  5206. begin
  5207. if not (ftPNG in FormatGetSupportedFiles (Format)) then
  5208. raise EglBitmapUnsupportedFormat.Create(Format);
  5209. case Format of
  5210. tfAlpha8, tfLuminance8: begin
  5211. ColorType := COLOR_GRAYSCALE;
  5212. PixSize := 1;
  5213. Alpha := false;
  5214. end;
  5215. tfLuminance8Alpha8: begin
  5216. ColorType := COLOR_GRAYSCALEALPHA;
  5217. PixSize := 1;
  5218. Alpha := true;
  5219. end;
  5220. tfBGR8, tfRGB8: begin
  5221. ColorType := COLOR_RGB;
  5222. PixSize := 3;
  5223. Alpha := false;
  5224. end;
  5225. tfBGRA8, tfRGBA8: begin
  5226. ColorType := COLOR_RGBALPHA;
  5227. PixSize := 3;
  5228. Alpha := true
  5229. end;
  5230. else
  5231. raise EglBitmapUnsupportedFormat.Create(Format);
  5232. end;
  5233. Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
  5234. try
  5235. // Copy ImageData
  5236. pSource := Data;
  5237. for Y := 0 to Height -1 do begin
  5238. pDest := png.ScanLine[Y];
  5239. for X := 0 to Width -1 do begin
  5240. Move(pSource^, pDest^, PixSize);
  5241. Inc(pDest, PixSize);
  5242. Inc(pSource, PixSize);
  5243. if Alpha then begin
  5244. png.AlphaScanline[Y]^[X] := pSource^;
  5245. Inc(pSource);
  5246. end;
  5247. end;
  5248. // convert RGB line to BGR
  5249. if Format in [tfRGB8, tfRGBA8] then begin
  5250. pTemp := png.ScanLine[Y];
  5251. for X := 0 to Width -1 do begin
  5252. Temp := pByteArray(pTemp)^[0];
  5253. pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
  5254. pByteArray(pTemp)^[2] := Temp;
  5255. Inc(pTemp, 3);
  5256. end;
  5257. end;
  5258. end;
  5259. // Save to Stream
  5260. Png.CompressionLevel := 6;
  5261. Png.SaveToStream(aStream);
  5262. finally
  5263. FreeAndNil(Png);
  5264. end;
  5265. end;
  5266. {$IFEND}
  5267. {$ENDIF}
  5268. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5269. //JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5270. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5271. {$IFDEF GLB_LIB_JPEG}
  5272. type
  5273. glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
  5274. glBitmap_libJPEG_source_mgr = record
  5275. pub: jpeg_source_mgr;
  5276. SrcStream: TStream;
  5277. SrcBuffer: array [1..4096] of byte;
  5278. end;
  5279. glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
  5280. glBitmap_libJPEG_dest_mgr = record
  5281. pub: jpeg_destination_mgr;
  5282. DestStream: TStream;
  5283. DestBuffer: array [1..4096] of byte;
  5284. end;
  5285. procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
  5286. begin
  5287. //DUMMY
  5288. end;
  5289. procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
  5290. begin
  5291. //DUMMY
  5292. end;
  5293. procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
  5294. begin
  5295. //DUMMY
  5296. end;
  5297. procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
  5298. begin
  5299. //DUMMY
  5300. end;
  5301. procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
  5302. begin
  5303. //DUMMY
  5304. end;
  5305. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5306. function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
  5307. var
  5308. src: glBitmap_libJPEG_source_mgr_ptr;
  5309. bytes: integer;
  5310. begin
  5311. src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
  5312. bytes := src^.SrcStream.Read(src^.SrcBuffer[1], 4096);
  5313. if (bytes <= 0) then begin
  5314. src^.SrcBuffer[1] := $FF;
  5315. src^.SrcBuffer[2] := JPEG_EOI;
  5316. bytes := 2;
  5317. end;
  5318. src^.pub.next_input_byte := @(src^.SrcBuffer[1]);
  5319. src^.pub.bytes_in_buffer := bytes;
  5320. result := true;
  5321. end;
  5322. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5323. procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
  5324. var
  5325. src: glBitmap_libJPEG_source_mgr_ptr;
  5326. begin
  5327. src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
  5328. if num_bytes > 0 then begin
  5329. // wanted byte isn't in buffer so set stream position and read buffer
  5330. if num_bytes > src^.pub.bytes_in_buffer then begin
  5331. src^.SrcStream.Position := src^.SrcStream.Position + num_bytes - src^.pub.bytes_in_buffer;
  5332. src^.pub.fill_input_buffer(cinfo);
  5333. end else begin
  5334. // wanted byte is in buffer so only skip
  5335. inc(src^.pub.next_input_byte, num_bytes);
  5336. dec(src^.pub.bytes_in_buffer, num_bytes);
  5337. end;
  5338. end;
  5339. end;
  5340. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5341. function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
  5342. var
  5343. dest: glBitmap_libJPEG_dest_mgr_ptr;
  5344. begin
  5345. dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
  5346. if dest^.pub.free_in_buffer < Cardinal(Length(dest^.DestBuffer)) then begin
  5347. // write complete buffer
  5348. dest^.DestStream.Write(dest^.DestBuffer[1], SizeOf(dest^.DestBuffer));
  5349. // reset buffer
  5350. dest^.pub.next_output_byte := @dest^.DestBuffer[1];
  5351. dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
  5352. end;
  5353. result := true;
  5354. end;
  5355. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5356. procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
  5357. var
  5358. Idx: Integer;
  5359. dest: glBitmap_libJPEG_dest_mgr_ptr;
  5360. begin
  5361. dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
  5362. for Idx := Low(dest^.DestBuffer) to High(dest^.DestBuffer) do begin
  5363. // check for endblock
  5364. if (Idx < High(dest^.DestBuffer)) and (dest^.DestBuffer[Idx] = $FF) and (dest^.DestBuffer[Idx +1] = JPEG_EOI) then begin
  5365. // write endblock
  5366. dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
  5367. // leave
  5368. break;
  5369. end else
  5370. dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
  5371. end;
  5372. end;
  5373. {$ENDIF}
  5374. {$IFDEF GLB_SUPPORT_JPEG_READ}
  5375. {$IF DEFINED(GLB_SDL_IMAGE)}
  5376. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5377. function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
  5378. var
  5379. Surface: PSDL_Surface;
  5380. RWops: PSDL_RWops;
  5381. begin
  5382. result := false;
  5383. RWops := glBitmapCreateRWops(aStream);
  5384. try
  5385. if IMG_isJPG(RWops) > 0 then begin
  5386. Surface := IMG_LoadJPG_RW(RWops);
  5387. try
  5388. AssignFromSurface(Surface);
  5389. result := true;
  5390. finally
  5391. SDL_FreeSurface(Surface);
  5392. end;
  5393. end;
  5394. finally
  5395. SDL_FreeRW(RWops);
  5396. end;
  5397. end;
  5398. {$ELSEIF DEFINED(GLB_LIB_JPEG)}
  5399. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5400. function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
  5401. var
  5402. StreamPos: Int64;
  5403. Temp: array[0..1]of Byte;
  5404. jpeg: jpeg_decompress_struct;
  5405. jpeg_err: jpeg_error_mgr;
  5406. IntFormat: TglBitmapFormat;
  5407. pImage: pByte;
  5408. TempHeight, TempWidth: Integer;
  5409. pTemp: pByte;
  5410. Row: Integer;
  5411. FormatDesc: TFormatDescriptor;
  5412. begin
  5413. result := false;
  5414. if not init_libJPEG then
  5415. raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
  5416. try
  5417. // reading first two bytes to test file and set cursor back to begin
  5418. StreamPos := aStream.Position;
  5419. aStream.Read({%H-}Temp[0], 2);
  5420. aStream.Position := StreamPos;
  5421. // if Bitmap then read file.
  5422. if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
  5423. FillChar(jpeg{%H-}, SizeOf(jpeg_decompress_struct), $00);
  5424. FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
  5425. // error managment
  5426. jpeg.err := jpeg_std_error(@jpeg_err);
  5427. jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
  5428. jpeg_err.output_message := glBitmap_libJPEG_output_message;
  5429. // decompression struct
  5430. jpeg_create_decompress(@jpeg);
  5431. // allocation space for streaming methods
  5432. jpeg.src := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_source_mgr));
  5433. // seeting up custom functions
  5434. with glBitmap_libJPEG_source_mgr_ptr(jpeg.src)^ do begin
  5435. pub.init_source := glBitmap_libJPEG_init_source;
  5436. pub.fill_input_buffer := glBitmap_libJPEG_fill_input_buffer;
  5437. pub.skip_input_data := glBitmap_libJPEG_skip_input_data;
  5438. pub.resync_to_restart := jpeg_resync_to_restart; // use default method
  5439. pub.term_source := glBitmap_libJPEG_term_source;
  5440. pub.bytes_in_buffer := 0; // forces fill_input_buffer on first read
  5441. pub.next_input_byte := nil; // until buffer loaded
  5442. SrcStream := aStream;
  5443. end;
  5444. // set global decoding state
  5445. jpeg.global_state := DSTATE_START;
  5446. // read header of jpeg
  5447. jpeg_read_header(@jpeg, false);
  5448. // setting output parameter
  5449. case jpeg.jpeg_color_space of
  5450. JCS_GRAYSCALE:
  5451. begin
  5452. jpeg.out_color_space := JCS_GRAYSCALE;
  5453. IntFormat := tfLuminance8;
  5454. end;
  5455. else
  5456. jpeg.out_color_space := JCS_RGB;
  5457. IntFormat := tfRGB8;
  5458. end;
  5459. // reading image
  5460. jpeg_start_decompress(@jpeg);
  5461. TempHeight := jpeg.output_height;
  5462. TempWidth := jpeg.output_width;
  5463. FormatDesc := TFormatDescriptor.Get(IntFormat);
  5464. // creating new image
  5465. GetMem(pImage, FormatDesc.GetSize(TempWidth, TempHeight));
  5466. try
  5467. pTemp := pImage;
  5468. for Row := 0 to TempHeight -1 do begin
  5469. jpeg_read_scanlines(@jpeg, @pTemp, 1);
  5470. Inc(pTemp, FormatDesc.GetSize(TempWidth, 1));
  5471. end;
  5472. // finish decompression
  5473. jpeg_finish_decompress(@jpeg);
  5474. // destroy decompression
  5475. jpeg_destroy_decompress(@jpeg);
  5476. SetDataPointer(pImage, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
  5477. result := true;
  5478. except
  5479. if Assigned(pImage) then
  5480. FreeMem(pImage);
  5481. raise;
  5482. end;
  5483. end;
  5484. finally
  5485. quit_libJPEG;
  5486. end;
  5487. end;
  5488. {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
  5489. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5490. function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
  5491. var
  5492. bmp: TBitmap;
  5493. jpg: TJPEGImage;
  5494. StreamPos: Int64;
  5495. Temp: array[0..1]of Byte;
  5496. begin
  5497. result := false;
  5498. // reading first two bytes to test file and set cursor back to begin
  5499. StreamPos := aStream.Position;
  5500. aStream.Read(Temp[0], 2);
  5501. aStream.Position := StreamPos;
  5502. // if Bitmap then read file.
  5503. if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
  5504. bmp := TBitmap.Create;
  5505. try
  5506. jpg := TJPEGImage.Create;
  5507. try
  5508. jpg.LoadFromStream(aStream);
  5509. bmp.Assign(jpg);
  5510. result := AssignFromBitmap(bmp);
  5511. finally
  5512. jpg.Free;
  5513. end;
  5514. finally
  5515. bmp.Free;
  5516. end;
  5517. end;
  5518. end;
  5519. {$IFEND}
  5520. {$ENDIF}
  5521. {$IFDEF GLB_SUPPORT_JPEG_WRITE}
  5522. {$IF DEFINED(GLB_LIB_JPEG)}
  5523. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5524. procedure TglBitmap.SaveJPEG(const aStream: TStream);
  5525. var
  5526. jpeg: jpeg_compress_struct;
  5527. jpeg_err: jpeg_error_mgr;
  5528. Row: Integer;
  5529. pTemp, pTemp2: pByte;
  5530. procedure CopyRow(pDest, pSource: pByte);
  5531. var
  5532. X: Integer;
  5533. begin
  5534. for X := 0 to Width - 1 do begin
  5535. pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
  5536. pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
  5537. pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
  5538. Inc(pDest, 3);
  5539. Inc(pSource, 3);
  5540. end;
  5541. end;
  5542. begin
  5543. if not (ftJPEG in FormatGetSupportedFiles(Format)) then
  5544. raise EglBitmapUnsupportedFormat.Create(Format);
  5545. if not init_libJPEG then
  5546. raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
  5547. try
  5548. FillChar(jpeg{%H-}, SizeOf(jpeg_compress_struct), $00);
  5549. FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
  5550. // error managment
  5551. jpeg.err := jpeg_std_error(@jpeg_err);
  5552. jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
  5553. jpeg_err.output_message := glBitmap_libJPEG_output_message;
  5554. // compression struct
  5555. jpeg_create_compress(@jpeg);
  5556. // allocation space for streaming methods
  5557. jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
  5558. // seeting up custom functions
  5559. with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
  5560. pub.init_destination := glBitmap_libJPEG_init_destination;
  5561. pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
  5562. pub.term_destination := glBitmap_libJPEG_term_destination;
  5563. pub.next_output_byte := @DestBuffer[1];
  5564. pub.free_in_buffer := Length(DestBuffer);
  5565. DestStream := aStream;
  5566. end;
  5567. // very important state
  5568. jpeg.global_state := CSTATE_START;
  5569. jpeg.image_width := Width;
  5570. jpeg.image_height := Height;
  5571. case Format of
  5572. tfAlpha8, tfLuminance8: begin
  5573. jpeg.input_components := 1;
  5574. jpeg.in_color_space := JCS_GRAYSCALE;
  5575. end;
  5576. tfRGB8, tfBGR8: begin
  5577. jpeg.input_components := 3;
  5578. jpeg.in_color_space := JCS_RGB;
  5579. end;
  5580. end;
  5581. jpeg_set_defaults(@jpeg);
  5582. jpeg_set_quality(@jpeg, 95, true);
  5583. jpeg_start_compress(@jpeg, true);
  5584. pTemp := Data;
  5585. if Format = tfBGR8 then
  5586. GetMem(pTemp2, fRowSize)
  5587. else
  5588. pTemp2 := pTemp;
  5589. try
  5590. for Row := 0 to jpeg.image_height -1 do begin
  5591. // prepare row
  5592. if Format = tfBGR8 then
  5593. CopyRow(pTemp2, pTemp)
  5594. else
  5595. pTemp2 := pTemp;
  5596. // write row
  5597. jpeg_write_scanlines(@jpeg, @pTemp2, 1);
  5598. inc(pTemp, fRowSize);
  5599. end;
  5600. finally
  5601. // free memory
  5602. if Format = tfBGR8 then
  5603. FreeMem(pTemp2);
  5604. end;
  5605. jpeg_finish_compress(@jpeg);
  5606. jpeg_destroy_compress(@jpeg);
  5607. finally
  5608. quit_libJPEG;
  5609. end;
  5610. end;
  5611. {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
  5612. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5613. procedure TglBitmap.SaveJPEG(const aStream: TStream);
  5614. var
  5615. Bmp: TBitmap;
  5616. Jpg: TJPEGImage;
  5617. begin
  5618. if not (ftJPEG in FormatGetSupportedFiles(Format)) then
  5619. raise EglBitmapUnsupportedFormat.Create(Format);
  5620. Bmp := TBitmap.Create;
  5621. try
  5622. Jpg := TJPEGImage.Create;
  5623. try
  5624. AssignToBitmap(Bmp);
  5625. if (Format in [tfAlpha8, tfLuminance8]) then begin
  5626. Jpg.Grayscale := true;
  5627. Jpg.PixelFormat := jf8Bit;
  5628. end;
  5629. Jpg.Assign(Bmp);
  5630. Jpg.SaveToStream(aStream);
  5631. finally
  5632. FreeAndNil(Jpg);
  5633. end;
  5634. finally
  5635. FreeAndNil(Bmp);
  5636. end;
  5637. end;
  5638. {$IFEND}
  5639. {$ENDIF}
  5640. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5641. //BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5642. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5643. const
  5644. BMP_MAGIC = $4D42;
  5645. BMP_COMP_RGB = 0;
  5646. BMP_COMP_RLE8 = 1;
  5647. BMP_COMP_RLE4 = 2;
  5648. BMP_COMP_BITFIELDS = 3;
  5649. type
  5650. TBMPHeader = packed record
  5651. bfType: Word;
  5652. bfSize: Cardinal;
  5653. bfReserved1: Word;
  5654. bfReserved2: Word;
  5655. bfOffBits: Cardinal;
  5656. end;
  5657. TBMPInfo = packed record
  5658. biSize: Cardinal;
  5659. biWidth: Longint;
  5660. biHeight: Longint;
  5661. biPlanes: Word;
  5662. biBitCount: Word;
  5663. biCompression: Cardinal;
  5664. biSizeImage: Cardinal;
  5665. biXPelsPerMeter: Longint;
  5666. biYPelsPerMeter: Longint;
  5667. biClrUsed: Cardinal;
  5668. biClrImportant: Cardinal;
  5669. end;
  5670. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5671. function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
  5672. //////////////////////////////////////////////////////////////////////////////////////////////////
  5673. function ReadInfo(out aInfo: TBMPInfo; out aMask: TglBitmapColorRec): TglBitmapFormat;
  5674. begin
  5675. result := tfEmpty;
  5676. aStream.Read(aInfo{%H-}, SizeOf(aInfo));
  5677. FillChar(aMask{%H-}, SizeOf(aMask), 0);
  5678. //Read Compression
  5679. case aInfo.biCompression of
  5680. BMP_COMP_RLE4,
  5681. BMP_COMP_RLE8: begin
  5682. raise EglBitmap.Create('RLE compression is not supported');
  5683. end;
  5684. BMP_COMP_BITFIELDS: begin
  5685. if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
  5686. aStream.Read(aMask.r, SizeOf(aMask.r));
  5687. aStream.Read(aMask.g, SizeOf(aMask.g));
  5688. aStream.Read(aMask.b, SizeOf(aMask.b));
  5689. aStream.Read(aMask.a, SizeOf(aMask.a));
  5690. end else
  5691. raise EglBitmap.Create('Bitfields are only supported for 16bit and 32bit formats');
  5692. end;
  5693. end;
  5694. //get suitable format
  5695. case aInfo.biBitCount of
  5696. 8: result := tfLuminance8;
  5697. 16: result := tfBGR5;
  5698. 24: result := tfBGR8;
  5699. 32: result := tfBGRA8;
  5700. end;
  5701. end;
  5702. function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TbmpColorTableFormat;
  5703. var
  5704. i, c: Integer;
  5705. ColorTable: TbmpColorTable;
  5706. begin
  5707. result := nil;
  5708. if (aInfo.biBitCount >= 16) then
  5709. exit;
  5710. aFormat := tfLuminance8;
  5711. c := aInfo.biClrUsed;
  5712. if (c = 0) then
  5713. c := 1 shl aInfo.biBitCount;
  5714. SetLength(ColorTable, c);
  5715. for i := 0 to c-1 do begin
  5716. aStream.Read(ColorTable[i], SizeOf(TbmpColorTableEnty));
  5717. if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then
  5718. aFormat := tfRGB8;
  5719. end;
  5720. result := TbmpColorTableFormat.Create;
  5721. result.PixelSize := aInfo.biBitCount / 8;
  5722. result.ColorTable := ColorTable;
  5723. result.Range := glBitmapColorRec($FF, $FF, $FF, $00);
  5724. end;
  5725. //////////////////////////////////////////////////////////////////////////////////////////////////
  5726. function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapColorRec;
  5727. const aInfo: TBMPInfo): TbmpBitfieldFormat;
  5728. var
  5729. TmpFormat: TglBitmapFormat;
  5730. FormatDesc: TFormatDescriptor;
  5731. begin
  5732. result := nil;
  5733. if (aMask.r <> 0) or (aMask.g <> 0) or (aMask.b <> 0) or (aMask.a <> 0) then begin
  5734. for TmpFormat := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
  5735. FormatDesc := TFormatDescriptor.Get(TmpFormat);
  5736. if FormatDesc.MaskMatch(aMask.r, aMask.g, aMask.b, aMask.a) then begin
  5737. aFormat := FormatDesc.Format;
  5738. exit;
  5739. end;
  5740. end;
  5741. if (aMask.a = 0) and TFormatDescriptor.Get(aFormat).HasAlpha then
  5742. aFormat := TFormatDescriptor.Get(aFormat).WithoutAlpha;
  5743. if (aMask.a <> 0) and not TFormatDescriptor.Get(aFormat).HasAlpha then
  5744. aFormat := TFormatDescriptor.Get(aFormat).WithAlpha;
  5745. result := TbmpBitfieldFormat.Create;
  5746. result.PixelSize := aInfo.biBitCount / 8;
  5747. result.RedMask := aMask.r;
  5748. result.GreenMask := aMask.g;
  5749. result.BlueMask := aMask.b;
  5750. result.AlphaMask := aMask.a;
  5751. end;
  5752. end;
  5753. var
  5754. //simple types
  5755. StartPos: Int64;
  5756. ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
  5757. PaddingBuff: Cardinal;
  5758. LineBuf, ImageData, TmpData: PByte;
  5759. SourceMD, DestMD: Pointer;
  5760. BmpFormat: TglBitmapFormat;
  5761. //records
  5762. Mask: TglBitmapColorRec;
  5763. Header: TBMPHeader;
  5764. Info: TBMPInfo;
  5765. //classes
  5766. SpecialFormat: TFormatDescriptor;
  5767. FormatDesc: TFormatDescriptor;
  5768. //////////////////////////////////////////////////////////////////////////////////////////////////
  5769. procedure SpecialFormatReadLine(aData: PByte; aLineBuf: PByte);
  5770. var
  5771. i: Integer;
  5772. Pixel: TglBitmapPixelData;
  5773. begin
  5774. aStream.Read(aLineBuf^, rbLineSize);
  5775. SpecialFormat.PreparePixel(Pixel);
  5776. for i := 0 to Info.biWidth-1 do begin
  5777. SpecialFormat.Unmap(aLineBuf, Pixel, SourceMD);
  5778. glBitmapConvertPixel(Pixel, SpecialFormat, FormatDesc);
  5779. FormatDesc.Map(Pixel, aData, DestMD);
  5780. end;
  5781. end;
  5782. begin
  5783. result := false;
  5784. BmpFormat := tfEmpty;
  5785. SpecialFormat := nil;
  5786. LineBuf := nil;
  5787. SourceMD := nil;
  5788. DestMD := nil;
  5789. // Header
  5790. StartPos := aStream.Position;
  5791. aStream.Read(Header{%H-}, SizeOf(Header));
  5792. if Header.bfType = BMP_MAGIC then begin
  5793. try try
  5794. BmpFormat := ReadInfo(Info, Mask);
  5795. SpecialFormat := ReadColorTable(BmpFormat, Info);
  5796. if not Assigned(SpecialFormat) then
  5797. SpecialFormat := CheckBitfields(BmpFormat, Mask, Info);
  5798. aStream.Position := StartPos + Header.bfOffBits;
  5799. if (BmpFormat <> tfEmpty) then begin
  5800. FormatDesc := TFormatDescriptor.Get(BmpFormat);
  5801. rbLineSize := Round(Info.biWidth * Info.biBitCount / 8); //ReadBuffer LineSize
  5802. wbLineSize := Trunc(Info.biWidth * FormatDesc.PixelSize);
  5803. Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
  5804. //get Memory
  5805. DestMD := FormatDesc.CreateMappingData;
  5806. ImageSize := FormatDesc.GetSize(Info.biWidth, abs(Info.biHeight));
  5807. GetMem(ImageData, ImageSize);
  5808. if Assigned(SpecialFormat) then begin
  5809. GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
  5810. SourceMD := SpecialFormat.CreateMappingData;
  5811. end;
  5812. //read Data
  5813. try try
  5814. FillChar(ImageData^, ImageSize, $FF);
  5815. TmpData := ImageData;
  5816. if (Info.biHeight > 0) then
  5817. Inc(TmpData, wbLineSize * (Info.biHeight-1));
  5818. for i := 0 to Abs(Info.biHeight)-1 do begin
  5819. if Assigned(SpecialFormat) then
  5820. SpecialFormatReadLine(TmpData, LineBuf) //if is special format read and convert data
  5821. else
  5822. aStream.Read(TmpData^, wbLineSize); //else only read data
  5823. if (Info.biHeight > 0) then
  5824. dec(TmpData, wbLineSize)
  5825. else
  5826. inc(TmpData, wbLineSize);
  5827. aStream.Read(PaddingBuff{%H-}, Padding);
  5828. end;
  5829. SetDataPointer(ImageData, BmpFormat, Info.biWidth, abs(Info.biHeight)); //be careful, Data could be freed by this method
  5830. result := true;
  5831. finally
  5832. if Assigned(LineBuf) then
  5833. FreeMem(LineBuf);
  5834. if Assigned(SourceMD) then
  5835. SpecialFormat.FreeMappingData(SourceMD);
  5836. FormatDesc.FreeMappingData(DestMD);
  5837. end;
  5838. except
  5839. if Assigned(ImageData) then
  5840. FreeMem(ImageData);
  5841. raise;
  5842. end;
  5843. end else
  5844. raise EglBitmap.Create('LoadBMP - No suitable format found');
  5845. except
  5846. aStream.Position := StartPos;
  5847. raise;
  5848. end;
  5849. finally
  5850. FreeAndNil(SpecialFormat);
  5851. end;
  5852. end
  5853. else aStream.Position := StartPos;
  5854. end;
  5855. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5856. procedure TglBitmap.SaveBMP(const aStream: TStream);
  5857. var
  5858. Header: TBMPHeader;
  5859. Info: TBMPInfo;
  5860. Converter: TbmpColorTableFormat;
  5861. FormatDesc: TFormatDescriptor;
  5862. SourceFD, DestFD: Pointer;
  5863. pData, srcData, dstData, ConvertBuffer: pByte;
  5864. Pixel: TglBitmapPixelData;
  5865. ImageSize, wbLineSize, rbLineSize, Padding, LineIdx, PixelIdx: Integer;
  5866. RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
  5867. PaddingBuff: Cardinal;
  5868. function GetLineWidth : Integer;
  5869. begin
  5870. result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
  5871. end;
  5872. begin
  5873. if not (ftBMP in FormatGetSupportedFiles(Format)) then
  5874. raise EglBitmapUnsupportedFormat.Create(Format);
  5875. Converter := nil;
  5876. FormatDesc := TFormatDescriptor.Get(Format);
  5877. ImageSize := FormatDesc.GetSize(Dimension);
  5878. FillChar(Header{%H-}, SizeOf(Header), 0);
  5879. Header.bfType := BMP_MAGIC;
  5880. Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
  5881. Header.bfReserved1 := 0;
  5882. Header.bfReserved2 := 0;
  5883. Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
  5884. FillChar(Info{%H-}, SizeOf(Info), 0);
  5885. Info.biSize := SizeOf(Info);
  5886. Info.biWidth := Width;
  5887. Info.biHeight := Height;
  5888. Info.biPlanes := 1;
  5889. Info.biCompression := BMP_COMP_RGB;
  5890. Info.biSizeImage := ImageSize;
  5891. try
  5892. case Format of
  5893. tfLuminance4: begin
  5894. Info.biBitCount := 4;
  5895. Header.bfSize := Header.bfSize + 16 * SizeOf(Cardinal);
  5896. Header.bfOffBits := Header.bfOffBits + 16 * SizeOf(Cardinal); //16 ColorTable entries
  5897. Converter := TbmpColorTableFormat.Create;
  5898. Converter.PixelSize := 0.5;
  5899. Converter.Format := Format;
  5900. Converter.Range := glBitmapColorRec($F, $F, $F, $0);
  5901. Converter.CreateColorTable;
  5902. end;
  5903. tfR3G3B2, tfLuminance8: begin
  5904. Info.biBitCount := 8;
  5905. Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
  5906. Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal); //256 ColorTable entries
  5907. Converter := TbmpColorTableFormat.Create;
  5908. Converter.PixelSize := 1;
  5909. Converter.Format := Format;
  5910. if (Format = tfR3G3B2) then begin
  5911. Converter.Range := glBitmapColorRec($7, $7, $3, $0);
  5912. Converter.Shift := glBitmapShiftRec(0, 3, 6, 0);
  5913. end else
  5914. Converter.Range := glBitmapColorRec($FF, $FF, $FF, $0);
  5915. Converter.CreateColorTable;
  5916. end;
  5917. tfRGB4, tfRGB5, tfR5G6B5, tfRGB5A1, tfRGBA4,
  5918. tfBGR4, tfBGR5, tfB5G6R5, tfBGR5A1, tfBGRA4: begin
  5919. Info.biBitCount := 16;
  5920. Info.biCompression := BMP_COMP_BITFIELDS;
  5921. end;
  5922. tfBGR8, tfRGB8: begin
  5923. Info.biBitCount := 24;
  5924. end;
  5925. tfRGB10, tfRGB10A2, tfRGBA8,
  5926. tfBGR10, tfBGR10A2, tfBGRA8: begin
  5927. Info.biBitCount := 32;
  5928. Info.biCompression := BMP_COMP_BITFIELDS;
  5929. end;
  5930. else
  5931. raise EglBitmapUnsupportedFormat.Create(Format);
  5932. end;
  5933. Info.biXPelsPerMeter := 2835;
  5934. Info.biYPelsPerMeter := 2835;
  5935. // prepare bitmasks
  5936. if Info.biCompression = BMP_COMP_BITFIELDS then begin
  5937. Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
  5938. Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
  5939. RedMask := FormatDesc.RedMask;
  5940. GreenMask := FormatDesc.GreenMask;
  5941. BlueMask := FormatDesc.BlueMask;
  5942. AlphaMask := FormatDesc.AlphaMask;
  5943. end;
  5944. // headers
  5945. aStream.Write(Header, SizeOf(Header));
  5946. aStream.Write(Info, SizeOf(Info));
  5947. // colortable
  5948. if Assigned(Converter) then
  5949. aStream.Write(Converter.ColorTable[0].b,
  5950. SizeOf(TbmpColorTableEnty) * Length(Converter.ColorTable));
  5951. // bitmasks
  5952. if Info.biCompression = BMP_COMP_BITFIELDS then begin
  5953. aStream.Write(RedMask, SizeOf(Cardinal));
  5954. aStream.Write(GreenMask, SizeOf(Cardinal));
  5955. aStream.Write(BlueMask, SizeOf(Cardinal));
  5956. aStream.Write(AlphaMask, SizeOf(Cardinal));
  5957. end;
  5958. // image data
  5959. rbLineSize := Round(Info.biWidth * FormatDesc.PixelSize);
  5960. wbLineSize := Round(Info.biWidth * Info.biBitCount / 8);
  5961. Padding := GetLineWidth - wbLineSize;
  5962. PaddingBuff := 0;
  5963. pData := Data;
  5964. inc(pData, (Height-1) * rbLineSize);
  5965. // prepare row buffer. But only for RGB because RGBA supports color masks
  5966. // so it's possible to change color within the image.
  5967. if Assigned(Converter) then begin
  5968. FormatDesc.PreparePixel(Pixel);
  5969. GetMem(ConvertBuffer, wbLineSize);
  5970. SourceFD := FormatDesc.CreateMappingData;
  5971. DestFD := Converter.CreateMappingData;
  5972. end else
  5973. ConvertBuffer := nil;
  5974. try
  5975. for LineIdx := 0 to Height - 1 do begin
  5976. // preparing row
  5977. if Assigned(Converter) then begin
  5978. srcData := pData;
  5979. dstData := ConvertBuffer;
  5980. for PixelIdx := 0 to Info.biWidth-1 do begin
  5981. FormatDesc.Unmap(srcData, Pixel, SourceFD);
  5982. glBitmapConvertPixel(Pixel, FormatDesc, Converter);
  5983. Converter.Map(Pixel, dstData, DestFD);
  5984. end;
  5985. aStream.Write(ConvertBuffer^, wbLineSize);
  5986. end else begin
  5987. aStream.Write(pData^, rbLineSize);
  5988. end;
  5989. dec(pData, rbLineSize);
  5990. if (Padding > 0) then
  5991. aStream.Write(PaddingBuff, Padding);
  5992. end;
  5993. finally
  5994. // destroy row buffer
  5995. if Assigned(ConvertBuffer) then begin
  5996. FormatDesc.FreeMappingData(SourceFD);
  5997. Converter.FreeMappingData(DestFD);
  5998. FreeMem(ConvertBuffer);
  5999. end;
  6000. end;
  6001. finally
  6002. if Assigned(Converter) then
  6003. Converter.Free;
  6004. end;
  6005. end;
  6006. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6007. //TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6008. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6009. type
  6010. TTGAHeader = packed record
  6011. ImageID: Byte;
  6012. ColorMapType: Byte;
  6013. ImageType: Byte;
  6014. //ColorMapSpec: Array[0..4] of Byte;
  6015. ColorMapStart: Word;
  6016. ColorMapLength: Word;
  6017. ColorMapEntrySize: Byte;
  6018. OrigX: Word;
  6019. OrigY: Word;
  6020. Width: Word;
  6021. Height: Word;
  6022. Bpp: Byte;
  6023. ImageDesc: Byte;
  6024. end;
  6025. const
  6026. TGA_UNCOMPRESSED_RGB = 2;
  6027. TGA_UNCOMPRESSED_GRAY = 3;
  6028. TGA_COMPRESSED_RGB = 10;
  6029. TGA_COMPRESSED_GRAY = 11;
  6030. TGA_NONE_COLOR_TABLE = 0;
  6031. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6032. function TglBitmap.LoadTGA(const aStream: TStream): Boolean;
  6033. var
  6034. Header: TTGAHeader;
  6035. ImageData: System.PByte;
  6036. StartPosition: Int64;
  6037. PixelSize, LineSize: Integer;
  6038. tgaFormat: TglBitmapFormat;
  6039. FormatDesc: TFormatDescriptor;
  6040. Counter: packed record
  6041. X, Y: packed record
  6042. low, high, dir: Integer;
  6043. end;
  6044. end;
  6045. const
  6046. CACHE_SIZE = $4000;
  6047. ////////////////////////////////////////////////////////////////////////////////////////
  6048. procedure ReadUncompressed;
  6049. var
  6050. i, j: Integer;
  6051. buf, tmp1, tmp2: System.PByte;
  6052. begin
  6053. buf := nil;
  6054. if (Counter.X.dir < 0) then
  6055. GetMem(buf, LineSize);
  6056. try
  6057. while (Counter.Y.low <> Counter.Y.high + counter.Y.dir) do begin
  6058. tmp1 := ImageData;
  6059. inc(tmp1, (Counter.Y.low * LineSize)); //pointer to LineStart
  6060. if (Counter.X.dir < 0) then begin //flip X
  6061. aStream.Read(buf^, LineSize);
  6062. tmp2 := buf;
  6063. inc(tmp2, LineSize - PixelSize); //pointer to last pixel in line
  6064. for i := 0 to Header.Width-1 do begin //for all pixels in line
  6065. for j := 0 to PixelSize-1 do begin //for all bytes in pixel
  6066. tmp1^ := tmp2^;
  6067. inc(tmp1);
  6068. inc(tmp2);
  6069. end;
  6070. dec(tmp2, 2*PixelSize); //move 2 backwards, because j-loop moved 1 forward
  6071. end;
  6072. end else
  6073. aStream.Read(tmp1^, LineSize);
  6074. inc(Counter.Y.low, Counter.Y.dir); //move to next line index
  6075. end;
  6076. finally
  6077. if Assigned(buf) then
  6078. FreeMem(buf);
  6079. end;
  6080. end;
  6081. ////////////////////////////////////////////////////////////////////////////////////////
  6082. procedure ReadCompressed;
  6083. /////////////////////////////////////////////////////////////////
  6084. var
  6085. TmpData: System.PByte;
  6086. LinePixelsRead: Integer;
  6087. procedure CheckLine;
  6088. begin
  6089. if (LinePixelsRead >= Header.Width) then begin
  6090. LinePixelsRead := 0;
  6091. inc(Counter.Y.low, Counter.Y.dir); //next line index
  6092. TmpData := ImageData;
  6093. inc(TmpData, Counter.Y.low * LineSize); //set line
  6094. if (Counter.X.dir < 0) then //if x flipped then
  6095. inc(TmpData, LineSize - PixelSize); //set last pixel
  6096. end;
  6097. end;
  6098. /////////////////////////////////////////////////////////////////
  6099. var
  6100. Cache: PByte;
  6101. CacheSize, CachePos: Integer;
  6102. procedure CachedRead(out Buffer; Count: Integer);
  6103. var
  6104. BytesRead: Integer;
  6105. begin
  6106. if (CachePos + Count > CacheSize) then begin
  6107. //if buffer overflow save non read bytes
  6108. BytesRead := 0;
  6109. if (CacheSize - CachePos > 0) then begin
  6110. BytesRead := CacheSize - CachePos;
  6111. Move(PByteArray(Cache)^[CachePos], Buffer{%H-}, BytesRead);
  6112. inc(CachePos, BytesRead);
  6113. end;
  6114. //load cache from file
  6115. CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
  6116. aStream.Read(Cache^, CacheSize);
  6117. CachePos := 0;
  6118. //read rest of requested bytes
  6119. if (Count - BytesRead > 0) then begin
  6120. Move(PByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
  6121. inc(CachePos, Count - BytesRead);
  6122. end;
  6123. end else begin
  6124. //if no buffer overflow just read the data
  6125. Move(PByteArray(Cache)^[CachePos], Buffer, Count);
  6126. inc(CachePos, Count);
  6127. end;
  6128. end;
  6129. procedure PixelToBuffer(const aData: PByte; var aBuffer: PByte);
  6130. begin
  6131. case PixelSize of
  6132. 1: begin
  6133. aBuffer^ := aData^;
  6134. inc(aBuffer, Counter.X.dir);
  6135. end;
  6136. 2: begin
  6137. PWord(aBuffer)^ := PWord(aData)^;
  6138. inc(aBuffer, 2 * Counter.X.dir);
  6139. end;
  6140. 3: begin
  6141. PByteArray(aBuffer)^[0] := PByteArray(aData)^[0];
  6142. PByteArray(aBuffer)^[1] := PByteArray(aData)^[1];
  6143. PByteArray(aBuffer)^[2] := PByteArray(aData)^[2];
  6144. inc(aBuffer, 3 * Counter.X.dir);
  6145. end;
  6146. 4: begin
  6147. PCardinal(aBuffer)^ := PCardinal(aData)^;
  6148. inc(aBuffer, 4 * Counter.X.dir);
  6149. end;
  6150. end;
  6151. end;
  6152. var
  6153. TotalPixelsToRead, TotalPixelsRead: Integer;
  6154. Temp: Byte;
  6155. buf: array [0..3] of Byte; //1 pixel is max 32bit long
  6156. PixelRepeat: Boolean;
  6157. PixelsToRead, PixelCount: Integer;
  6158. begin
  6159. CacheSize := 0;
  6160. CachePos := 0;
  6161. TotalPixelsToRead := Header.Width * Header.Height;
  6162. TotalPixelsRead := 0;
  6163. LinePixelsRead := 0;
  6164. GetMem(Cache, CACHE_SIZE);
  6165. try
  6166. TmpData := ImageData;
  6167. inc(TmpData, Counter.Y.low * LineSize); //set line
  6168. if (Counter.X.dir < 0) then //if x flipped then
  6169. inc(TmpData, LineSize - PixelSize); //set last pixel
  6170. repeat
  6171. //read CommandByte
  6172. CachedRead(Temp, 1);
  6173. PixelRepeat := (Temp and $80) > 0;
  6174. PixelsToRead := (Temp and $7F) + 1;
  6175. inc(TotalPixelsRead, PixelsToRead);
  6176. if PixelRepeat then
  6177. CachedRead(buf[0], PixelSize);
  6178. while (PixelsToRead > 0) do begin
  6179. CheckLine;
  6180. PixelCount := Min(Header.Width - LinePixelsRead, PixelsToRead); //max read to EOL or EOF
  6181. while (PixelCount > 0) do begin
  6182. if not PixelRepeat then
  6183. CachedRead(buf[0], PixelSize);
  6184. PixelToBuffer(@buf[0], TmpData);
  6185. inc(LinePixelsRead);
  6186. dec(PixelsToRead);
  6187. dec(PixelCount);
  6188. end;
  6189. end;
  6190. until (TotalPixelsRead >= TotalPixelsToRead);
  6191. finally
  6192. FreeMem(Cache);
  6193. end;
  6194. end;
  6195. function IsGrayFormat: Boolean;
  6196. begin
  6197. result := Header.ImageType in [TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_GRAY];
  6198. end;
  6199. begin
  6200. result := false;
  6201. // reading header to test file and set cursor back to begin
  6202. StartPosition := aStream.Position;
  6203. aStream.Read(Header{%H-}, SizeOf(Header));
  6204. // no colormapped files
  6205. if (Header.ColorMapType = TGA_NONE_COLOR_TABLE) and (Header.ImageType in [
  6206. TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY]) then
  6207. begin
  6208. try
  6209. if Header.ImageID <> 0 then // skip image ID
  6210. aStream.Position := aStream.Position + Header.ImageID;
  6211. tgaFormat := tfEmpty;
  6212. case Header.Bpp of
  6213. 8: if IsGrayFormat then case (Header.ImageDesc and $F) of
  6214. 0: tgaFormat := tfLuminance8;
  6215. 8: tgaFormat := tfAlpha8;
  6216. end;
  6217. 16: if IsGrayFormat then case (Header.ImageDesc and $F) of
  6218. 0: tgaFormat := tfLuminance16;
  6219. 8: tgaFormat := tfLuminance8Alpha8;
  6220. end else case (Header.ImageDesc and $F) of
  6221. 0: tgaFormat := tfBGR5;
  6222. 1: tgaFormat := tfBGR5A1;
  6223. 4: tgaFormat := tfBGRA4;
  6224. end;
  6225. 24: if not IsGrayFormat then case (Header.ImageDesc and $F) of
  6226. 0: tgaFormat := tfBGR8;
  6227. end;
  6228. 32: if not IsGrayFormat then case (Header.ImageDesc and $F) of
  6229. 2: tgaFormat := tfBGR10A2;
  6230. 8: tgaFormat := tfBGRA8;
  6231. end;
  6232. end;
  6233. if (tgaFormat = tfEmpty) then
  6234. raise EglBitmap.Create('LoadTga - unsupported format');
  6235. FormatDesc := TFormatDescriptor.Get(tgaFormat);
  6236. PixelSize := FormatDesc.GetSize(1, 1);
  6237. LineSize := FormatDesc.GetSize(Header.Width, 1);
  6238. GetMem(ImageData, LineSize * Header.Height);
  6239. try
  6240. //column direction
  6241. if ((Header.ImageDesc and (1 shl 4)) > 0) then begin
  6242. Counter.X.low := Header.Height-1;;
  6243. Counter.X.high := 0;
  6244. Counter.X.dir := -1;
  6245. end else begin
  6246. Counter.X.low := 0;
  6247. Counter.X.high := Header.Height-1;
  6248. Counter.X.dir := 1;
  6249. end;
  6250. // Row direction
  6251. if ((Header.ImageDesc and (1 shl 5)) > 0) then begin
  6252. Counter.Y.low := 0;
  6253. Counter.Y.high := Header.Height-1;
  6254. Counter.Y.dir := 1;
  6255. end else begin
  6256. Counter.Y.low := Header.Height-1;;
  6257. Counter.Y.high := 0;
  6258. Counter.Y.dir := -1;
  6259. end;
  6260. // Read Image
  6261. case Header.ImageType of
  6262. TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY:
  6263. ReadUncompressed;
  6264. TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY:
  6265. ReadCompressed;
  6266. end;
  6267. SetDataPointer(ImageData, tgaFormat, Header.Width, Header.Height); //be careful, Data could be freed by this method
  6268. result := true;
  6269. except
  6270. if Assigned(ImageData) then
  6271. FreeMem(ImageData);
  6272. raise;
  6273. end;
  6274. finally
  6275. aStream.Position := StartPosition;
  6276. end;
  6277. end
  6278. else aStream.Position := StartPosition;
  6279. end;
  6280. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6281. procedure TglBitmap.SaveTGA(const aStream: TStream);
  6282. var
  6283. Header: TTGAHeader;
  6284. LineSize, Size, x, y: Integer;
  6285. Pixel: TglBitmapPixelData;
  6286. LineBuf, SourceData, DestData: PByte;
  6287. SourceMD, DestMD: Pointer;
  6288. FormatDesc: TFormatDescriptor;
  6289. Converter: TFormatDescriptor;
  6290. begin
  6291. if not (ftTGA in FormatGetSupportedFiles(Format)) then
  6292. raise EglBitmapUnsupportedFormat.Create(Format);
  6293. //prepare header
  6294. FillChar(Header{%H-}, SizeOf(Header), 0);
  6295. //set ImageType
  6296. if (Format in [tfLuminance8, tfLuminance6Alpha2, tfLuminance4Alpha4, tfAlpha8,
  6297. tfLuminance16, tfLuminance12Alpha4, tfLuminance8Alpha8]) then
  6298. Header.ImageType := TGA_UNCOMPRESSED_GRAY
  6299. else
  6300. Header.ImageType := TGA_UNCOMPRESSED_RGB;
  6301. //set BitsPerPixel
  6302. if (Format in [tfLuminance8, tfLuminance6Alpha2, tfLuminance4Alpha4, tfAlpha8]) then
  6303. Header.Bpp := 8
  6304. else if (Format in [tfLuminance16, tfLuminance12Alpha4, tfLuminance8Alpha8,
  6305. tfRGB5, tfBGR5, tfRGB5A1, tfBGR5A1, tfRGBA4, tfBGRA4]) then
  6306. Header.Bpp := 16
  6307. else if (Format in [tfBGR8, tfRGB8]) then
  6308. Header.Bpp := 24
  6309. else
  6310. Header.Bpp := 32;
  6311. //set AlphaBitCount
  6312. case Format of
  6313. tfRGB5A1, tfBGR5A1:
  6314. Header.ImageDesc := 1 and $F;
  6315. tfRGB10A2, tfBGR10A2:
  6316. Header.ImageDesc := 2 and $F;
  6317. tfRGBA4, tfBGRA4:
  6318. Header.ImageDesc := 4 and $F;
  6319. tfAlpha8, tfLuminance8Alpha8, tfRGBA8, tfBGRA8:
  6320. Header.ImageDesc := 8 and $F;
  6321. end;
  6322. Header.Width := Width;
  6323. Header.Height := Height;
  6324. Header.ImageDesc := Header.ImageDesc or $20; //flip y
  6325. aStream.Write(Header, SizeOf(Header));
  6326. // convert RGB(A) to BGR(A)
  6327. Converter := nil;
  6328. FormatDesc := TFormatDescriptor.Get(Format);
  6329. Size := FormatDesc.GetSize(Dimension);
  6330. if Format in [tfRGB5, tfRGB5A1, tfRGBA4, tfRGB8, tfRGB10A2, tfRGBA8] then begin
  6331. if (FormatDesc.RGBInverted = tfEmpty) then
  6332. raise EglBitmap.Create('inverted RGB format is empty');
  6333. Converter := TFormatDescriptor.Get(FormatDesc.RGBInverted);
  6334. if not glBitmapColorRecCmp(Converter.Range, FormatDesc.Range) or
  6335. (Converter.PixelSize <> FormatDesc.PixelSize) then
  6336. raise EglBitmap.Create('invalid inverted RGB format');
  6337. end;
  6338. if Assigned(Converter) then begin
  6339. LineSize := FormatDesc.GetSize(Width, 1);
  6340. GetMem(LineBuf, LineSize);
  6341. SourceMD := FormatDesc.CreateMappingData;
  6342. DestMD := Converter.CreateMappingData;
  6343. try
  6344. SourceData := Data;
  6345. for y := 0 to Height-1 do begin
  6346. DestData := LineBuf;
  6347. for x := 0 to Width-1 do begin
  6348. FormatDesc.Unmap(SourceData, Pixel, SourceMD);
  6349. Converter.Map(Pixel, DestData, DestMD);
  6350. end;
  6351. aStream.Write(LineBuf^, LineSize);
  6352. end;
  6353. finally
  6354. FreeMem(LineBuf);
  6355. FormatDesc.FreeMappingData(SourceMD);
  6356. FormatDesc.FreeMappingData(DestMD);
  6357. end;
  6358. end else
  6359. aStream.Write(Data^, Size);
  6360. end;
  6361. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6362. //DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6363. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6364. const
  6365. DDS_MAGIC: Cardinal = $20534444;
  6366. // DDS_header.dwFlags
  6367. DDSD_CAPS = $00000001;
  6368. DDSD_HEIGHT = $00000002;
  6369. DDSD_WIDTH = $00000004;
  6370. DDSD_PIXELFORMAT = $00001000;
  6371. // DDS_header.sPixelFormat.dwFlags
  6372. DDPF_ALPHAPIXELS = $00000001;
  6373. DDPF_ALPHA = $00000002;
  6374. DDPF_FOURCC = $00000004;
  6375. DDPF_RGB = $00000040;
  6376. DDPF_LUMINANCE = $00020000;
  6377. // DDS_header.sCaps.dwCaps1
  6378. DDSCAPS_TEXTURE = $00001000;
  6379. // DDS_header.sCaps.dwCaps2
  6380. DDSCAPS2_CUBEMAP = $00000200;
  6381. D3DFMT_DXT1 = $31545844;
  6382. D3DFMT_DXT3 = $33545844;
  6383. D3DFMT_DXT5 = $35545844;
  6384. type
  6385. TDDSPixelFormat = packed record
  6386. dwSize: Cardinal;
  6387. dwFlags: Cardinal;
  6388. dwFourCC: Cardinal;
  6389. dwRGBBitCount: Cardinal;
  6390. dwRBitMask: Cardinal;
  6391. dwGBitMask: Cardinal;
  6392. dwBBitMask: Cardinal;
  6393. dwABitMask: Cardinal;
  6394. end;
  6395. TDDSCaps = packed record
  6396. dwCaps1: Cardinal;
  6397. dwCaps2: Cardinal;
  6398. dwDDSX: Cardinal;
  6399. dwReserved: Cardinal;
  6400. end;
  6401. TDDSHeader = packed record
  6402. dwSize: Cardinal;
  6403. dwFlags: Cardinal;
  6404. dwHeight: Cardinal;
  6405. dwWidth: Cardinal;
  6406. dwPitchOrLinearSize: Cardinal;
  6407. dwDepth: Cardinal;
  6408. dwMipMapCount: Cardinal;
  6409. dwReserved: array[0..10] of Cardinal;
  6410. PixelFormat: TDDSPixelFormat;
  6411. Caps: TDDSCaps;
  6412. dwReserved2: Cardinal;
  6413. end;
  6414. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6415. function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
  6416. var
  6417. Header: TDDSHeader;
  6418. Converter: TbmpBitfieldFormat;
  6419. function GetDDSFormat: TglBitmapFormat;
  6420. var
  6421. fd: TFormatDescriptor;
  6422. i: Integer;
  6423. Range: TglBitmapColorRec;
  6424. match: Boolean;
  6425. begin
  6426. result := tfEmpty;
  6427. with Header.PixelFormat do begin
  6428. // Compresses
  6429. if ((dwFlags and DDPF_FOURCC) > 0) then begin
  6430. case Header.PixelFormat.dwFourCC of
  6431. D3DFMT_DXT1: result := tfS3tcDtx1RGBA;
  6432. D3DFMT_DXT3: result := tfS3tcDtx3RGBA;
  6433. D3DFMT_DXT5: result := tfS3tcDtx5RGBA;
  6434. end;
  6435. end else if ((Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0) then begin
  6436. //find matching format
  6437. for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
  6438. fd := TFormatDescriptor.Get(result);
  6439. if fd.MaskMatch(dwRBitMask, dwGBitMask, dwBBitMask, dwABitMask) and
  6440. (8 * fd.PixelSize = dwRGBBitCount) then
  6441. exit;
  6442. end;
  6443. //find format with same Range
  6444. Range.r := dwRBitMask;
  6445. Range.g := dwGBitMask;
  6446. Range.b := dwBBitMask;
  6447. Range.a := dwABitMask;
  6448. for i := 0 to 3 do begin
  6449. while ((Range.arr[i] and 1) = 0) and (Range.arr[i] > 0) do
  6450. Range.arr[i] := Range.arr[i] shr 1;
  6451. end;
  6452. for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
  6453. fd := TFormatDescriptor.Get(result);
  6454. match := true;
  6455. for i := 0 to 3 do
  6456. if (fd.Range.arr[i] <> Range.arr[i]) then begin
  6457. match := false;
  6458. break;
  6459. end;
  6460. if match then
  6461. break;
  6462. end;
  6463. //no format with same range found -> use default
  6464. if (result = tfEmpty) then begin
  6465. if (dwABitMask > 0) then
  6466. result := tfBGRA8
  6467. else
  6468. result := tfBGR8;
  6469. end;
  6470. Converter := TbmpBitfieldFormat.Create;
  6471. Converter.RedMask := dwRBitMask;
  6472. Converter.GreenMask := dwGBitMask;
  6473. Converter.BlueMask := dwBBitMask;
  6474. Converter.AlphaMask := dwABitMask;
  6475. Converter.PixelSize := dwRGBBitCount / 8;
  6476. end;
  6477. end;
  6478. end;
  6479. var
  6480. StreamPos: Int64;
  6481. x, y, LineSize, RowSize, Magic: Cardinal;
  6482. NewImage, TmpData, RowData, SrcData: System.PByte;
  6483. SourceMD, DestMD: Pointer;
  6484. Pixel: TglBitmapPixelData;
  6485. ddsFormat: TglBitmapFormat;
  6486. FormatDesc: TFormatDescriptor;
  6487. begin
  6488. result := false;
  6489. Converter := nil;
  6490. StreamPos := aStream.Position;
  6491. // Magic
  6492. aStream.Read(Magic{%H-}, sizeof(Magic));
  6493. if (Magic <> DDS_MAGIC) then begin
  6494. aStream.Position := StreamPos;
  6495. exit;
  6496. end;
  6497. //Header
  6498. aStream.Read(Header{%H-}, sizeof(Header));
  6499. if (Header.dwSize <> SizeOf(Header)) or
  6500. ((Header.dwFlags and (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) <>
  6501. (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) then
  6502. begin
  6503. aStream.Position := StreamPos;
  6504. exit;
  6505. end;
  6506. if ((Header.Caps.dwCaps1 and DDSCAPS2_CUBEMAP) > 0) then
  6507. raise EglBitmap.Create('LoadDDS - CubeMaps are not supported');
  6508. ddsFormat := GetDDSFormat;
  6509. try
  6510. if (ddsFormat = tfEmpty) then
  6511. raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
  6512. FormatDesc := TFormatDescriptor.Get(ddsFormat);
  6513. LineSize := Trunc(Header.dwWidth * FormatDesc.PixelSize);
  6514. GetMem(NewImage, Header.dwHeight * LineSize);
  6515. try
  6516. TmpData := NewImage;
  6517. //Converter needed
  6518. if Assigned(Converter) then begin
  6519. RowSize := Round(Header.dwWidth * Header.PixelFormat.dwRGBBitCount / 8);
  6520. GetMem(RowData, RowSize);
  6521. SourceMD := Converter.CreateMappingData;
  6522. DestMD := FormatDesc.CreateMappingData;
  6523. try
  6524. for y := 0 to Header.dwHeight-1 do begin
  6525. TmpData := NewImage;
  6526. inc(TmpData, y * LineSize);
  6527. SrcData := RowData;
  6528. aStream.Read(SrcData^, RowSize);
  6529. for x := 0 to Header.dwWidth-1 do begin
  6530. Converter.Unmap(SrcData, Pixel, SourceMD);
  6531. glBitmapConvertPixel(Pixel, Converter, FormatDesc);
  6532. FormatDesc.Map(Pixel, TmpData, DestMD);
  6533. end;
  6534. end;
  6535. finally
  6536. Converter.FreeMappingData(SourceMD);
  6537. FormatDesc.FreeMappingData(DestMD);
  6538. FreeMem(RowData);
  6539. end;
  6540. end else
  6541. // Compressed
  6542. if ((Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0) then begin
  6543. RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
  6544. for Y := 0 to Header.dwHeight-1 do begin
  6545. aStream.Read(TmpData^, RowSize);
  6546. Inc(TmpData, LineSize);
  6547. end;
  6548. end else
  6549. // Uncompressed
  6550. if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0 then begin
  6551. RowSize := (Header.PixelFormat.dwRGBBitCount * Header.dwWidth) shr 3;
  6552. for Y := 0 to Header.dwHeight-1 do begin
  6553. aStream.Read(TmpData^, RowSize);
  6554. Inc(TmpData, LineSize);
  6555. end;
  6556. end else
  6557. raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
  6558. SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight); //be careful, Data could be freed by this method
  6559. result := true;
  6560. except
  6561. if Assigned(NewImage) then
  6562. FreeMem(NewImage);
  6563. raise;
  6564. end;
  6565. finally
  6566. FreeAndNil(Converter);
  6567. end;
  6568. end;
  6569. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6570. procedure TglBitmap.SaveDDS(const aStream: TStream);
  6571. var
  6572. Header: TDDSHeader;
  6573. FormatDesc: TFormatDescriptor;
  6574. begin
  6575. if not (ftDDS in FormatGetSupportedFiles(Format)) then
  6576. raise EglBitmapUnsupportedFormat.Create(Format);
  6577. FormatDesc := TFormatDescriptor.Get(Format);
  6578. // Generell
  6579. FillChar(Header{%H-}, SizeOf(Header), 0);
  6580. Header.dwSize := SizeOf(Header);
  6581. Header.dwFlags := DDSD_WIDTH or DDSD_HEIGHT or DDSD_CAPS or DDSD_PIXELFORMAT;
  6582. Header.dwWidth := Max(1, Width);
  6583. Header.dwHeight := Max(1, Height);
  6584. // Caps
  6585. Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
  6586. // Pixelformat
  6587. Header.PixelFormat.dwSize := sizeof(Header);
  6588. if (FormatDesc.IsCompressed) then begin
  6589. Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_FOURCC;
  6590. case Format of
  6591. tfS3tcDtx1RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT1;
  6592. tfS3tcDtx3RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT3;
  6593. tfS3tcDtx5RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT5;
  6594. end;
  6595. end else if (Format in [tfAlpha8, tfAlpha16]) then begin
  6596. Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHA;
  6597. Header.PixelFormat.dwRGBBitCount := Round(FormatDesc.PixelSize * 8);
  6598. Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
  6599. end else if (FormatDesc.RedMask = FormatDesc.GreenMask) and (FormatDesc.GreenMask = FormatDesc.BlueMask) then begin
  6600. Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_LUMINANCE;
  6601. Header.PixelFormat.dwRGBBitCount := Round(FormatDesc.PixelSize * 8);
  6602. Header.PixelFormat.dwRBitMask := FormatDesc.RedMask;
  6603. Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
  6604. end else begin
  6605. Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_RGB;
  6606. Header.PixelFormat.dwRGBBitCount := Round(FormatDesc.PixelSize * 8);
  6607. Header.PixelFormat.dwRBitMask := FormatDesc.RedMask;
  6608. Header.PixelFormat.dwGBitMask := FormatDesc.GreenMask;
  6609. Header.PixelFormat.dwBBitMask := FormatDesc.BlueMask;
  6610. Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
  6611. end;
  6612. if (FormatDesc.HasAlpha) then
  6613. Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
  6614. aStream.Write(DDS_MAGIC, sizeof(DDS_MAGIC));
  6615. aStream.Write(Header, SizeOf(Header));
  6616. aStream.Write(Data^, FormatDesc.GetSize(Dimension));
  6617. end;
  6618. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6619. //TglBitmap1D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6620. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6621. procedure TglBitmap1D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
  6622. const aWidth: Integer; const aHeight: Integer);
  6623. var
  6624. pTemp: pByte;
  6625. Size: Integer;
  6626. begin
  6627. if (aHeight > 1) then begin
  6628. Size := TFormatDescriptor.Get(aFormat).GetSize(aWidth, 1);
  6629. GetMem(pTemp, Size);
  6630. try
  6631. Move(aData^, pTemp^, Size);
  6632. FreeMem(aData);
  6633. aData := nil;
  6634. except
  6635. FreeMem(pTemp);
  6636. raise;
  6637. end;
  6638. end else
  6639. pTemp := aData;
  6640. inherited SetDataPointer(pTemp, aFormat, aWidth);
  6641. end;
  6642. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6643. function TglBitmap1D.FlipHorz: Boolean;
  6644. var
  6645. Col: Integer;
  6646. pTempDest, pDest, pSource: PByte;
  6647. begin
  6648. result := inherited FlipHorz;
  6649. if Assigned(Data) and not TFormatDescriptor.Get(Format).IsCompressed then begin
  6650. pSource := Data;
  6651. GetMem(pDest, fRowSize);
  6652. try
  6653. pTempDest := pDest;
  6654. Inc(pTempDest, fRowSize);
  6655. for Col := 0 to Width-1 do begin
  6656. dec(pTempDest, fPixelSize); //dec before, because ptr is behind last byte of data
  6657. Move(pSource^, pTempDest^, fPixelSize);
  6658. Inc(pSource, fPixelSize);
  6659. end;
  6660. SetDataPointer(pDest, Format, Width); //be careful, Data could be freed by this method
  6661. result := true;
  6662. except
  6663. if Assigned(pDest) then
  6664. FreeMem(pDest);
  6665. raise;
  6666. end;
  6667. end;
  6668. end;
  6669. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6670. procedure TglBitmap1D.UploadData(const aBuildWithGlu: Boolean);
  6671. var
  6672. FormatDesc: TFormatDescriptor;
  6673. begin
  6674. // Upload data
  6675. FormatDesc := TFormatDescriptor.Get(Format);
  6676. if FormatDesc.IsCompressed then
  6677. glCompressedTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.GetSize(Width, 1), Data)
  6678. else if aBuildWithGlu then
  6679. gluBuild1DMipmaps(Target, FormatDesc.glInternalFormat, Width, FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
  6680. else
  6681. glTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
  6682. // Free Data
  6683. if (FreeDataAfterGenTexture) then
  6684. FreeData;
  6685. end;
  6686. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6687. procedure TglBitmap1D.GenTexture(const aTestTextureSize: Boolean);
  6688. var
  6689. BuildWithGlu, TexRec: Boolean;
  6690. TexSize: Integer;
  6691. begin
  6692. if Assigned(Data) then begin
  6693. // Check Texture Size
  6694. if (aTestTextureSize) then begin
  6695. glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
  6696. if (Width > TexSize) then
  6697. raise EglBitmapSizeToLarge.Create('TglBitmap1D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
  6698. TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
  6699. (Target = GL_TEXTURE_RECTANGLE);
  6700. if not (IsPowerOfTwo(Width) or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
  6701. raise EglBitmapNonPowerOfTwo.Create('TglBitmap1D.GenTexture - Rendercontex dosn''t support non power of two texture.');
  6702. end;
  6703. CreateId;
  6704. SetupParameters(BuildWithGlu);
  6705. UploadData(BuildWithGlu);
  6706. glAreTexturesResident(1, @fID, @fIsResident);
  6707. end;
  6708. end;
  6709. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6710. procedure TglBitmap1D.AfterConstruction;
  6711. begin
  6712. inherited;
  6713. Target := GL_TEXTURE_1D;
  6714. end;
  6715. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6716. //TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6717. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6718. function TglBitmap2D.GetScanline(const aIndex: Integer): Pointer;
  6719. begin
  6720. if (aIndex >= Low(fLines)) and (aIndex <= High(fLines)) then
  6721. result := fLines[aIndex]
  6722. else
  6723. result := nil;
  6724. end;
  6725. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6726. procedure TglBitmap2D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
  6727. const aWidth: Integer; const aHeight: Integer);
  6728. var
  6729. Idx, LineWidth: Integer;
  6730. begin
  6731. inherited SetDataPointer(aData, aFormat, aWidth, aHeight);
  6732. if not TFormatDescriptor.Get(aFormat).IsCompressed then begin
  6733. // Assigning Data
  6734. if Assigned(Data) then begin
  6735. SetLength(fLines, GetHeight);
  6736. LineWidth := Trunc(GetWidth * TFormatDescriptor.Get(Format).PixelSize);
  6737. for Idx := 0 to GetHeight-1 do begin
  6738. fLines[Idx] := Data;
  6739. Inc(fLines[Idx], Idx * LineWidth);
  6740. end;
  6741. end
  6742. else SetLength(fLines, 0);
  6743. end else begin
  6744. SetLength(fLines, 0);
  6745. end;
  6746. end;
  6747. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6748. procedure TglBitmap2D.UploadData(const aTarget: GLenum; const aBuildWithGlu: Boolean);
  6749. var
  6750. FormatDesc: TFormatDescriptor;
  6751. begin
  6752. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  6753. FormatDesc := TFormatDescriptor.Get(Format);
  6754. if FormatDesc.IsCompressed then begin
  6755. glCompressedTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0, FormatDesc.GetSize(fDimension), Data)
  6756. end else if aBuildWithGlu then begin
  6757. gluBuild2DMipmaps(aTarget, FormatDesc.Components, Width, Height,
  6758. FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
  6759. end else begin
  6760. glTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0,
  6761. FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
  6762. end;
  6763. // Freigeben
  6764. if (FreeDataAfterGenTexture) then
  6765. FreeData;
  6766. end;
  6767. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6768. procedure TglBitmap2D.AfterConstruction;
  6769. begin
  6770. inherited;
  6771. Target := GL_TEXTURE_2D;
  6772. end;
  6773. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6774. procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
  6775. var
  6776. Temp: pByte;
  6777. Size, w, h: Integer;
  6778. FormatDesc: TFormatDescriptor;
  6779. begin
  6780. FormatDesc := TFormatDescriptor.Get(aFormat);
  6781. if FormatDesc.IsCompressed then
  6782. raise EglBitmapUnsupportedFormat.Create(aFormat);
  6783. w := aRight - aLeft;
  6784. h := aBottom - aTop;
  6785. Size := FormatDesc.GetSize(w, h);
  6786. GetMem(Temp, Size);
  6787. try
  6788. glPixelStorei(GL_PACK_ALIGNMENT, 1);
  6789. glReadPixels(aLeft, aTop, w, h, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
  6790. SetDataPointer(Temp, aFormat, w, h); //be careful, Data could be freed by this method
  6791. FlipVert;
  6792. except
  6793. if Assigned(Temp) then
  6794. FreeMem(Temp);
  6795. raise;
  6796. end;
  6797. end;
  6798. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6799. procedure TglBitmap2D.GetDataFromTexture;
  6800. var
  6801. Temp: PByte;
  6802. TempWidth, TempHeight: Integer;
  6803. TempIntFormat: Cardinal;
  6804. IntFormat, f: TglBitmapFormat;
  6805. FormatDesc: TFormatDescriptor;
  6806. begin
  6807. Bind;
  6808. // Request Data
  6809. glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
  6810. glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
  6811. glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
  6812. IntFormat := tfEmpty;
  6813. for f := Low(TglBitmapFormat) to High(TglBitmapFormat) do begin
  6814. FormatDesc := TFormatDescriptor.Get(f);
  6815. if (FormatDesc.glInternalFormat = TempIntFormat) then begin
  6816. IntFormat := FormatDesc.Format;
  6817. break;
  6818. end;
  6819. end;
  6820. // Getting data from OpenGL
  6821. FormatDesc := TFormatDescriptor.Get(IntFormat);
  6822. GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
  6823. try
  6824. if FormatDesc.IsCompressed then
  6825. glGetCompressedTexImage(Target, 0, Temp)
  6826. else
  6827. glGetTexImage(Target, 0, FormatDesc.glInternalFormat, FormatDesc.glDataFormat, Temp);
  6828. SetDataPointer(Temp, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
  6829. except
  6830. if Assigned(Temp) then
  6831. FreeMem(Temp);
  6832. raise;
  6833. end;
  6834. end;
  6835. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6836. procedure TglBitmap2D.GenTexture(const aTestTextureSize: Boolean);
  6837. var
  6838. BuildWithGlu, PotTex, TexRec: Boolean;
  6839. TexSize: Integer;
  6840. begin
  6841. if Assigned(Data) then begin
  6842. // Check Texture Size
  6843. if (aTestTextureSize) then begin
  6844. glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
  6845. if ((Height > TexSize) or (Width > TexSize)) then
  6846. raise EglBitmapSizeToLarge.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
  6847. PotTex := IsPowerOfTwo(Height) and IsPowerOfTwo(Width);
  6848. TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE);
  6849. if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
  6850. raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
  6851. end;
  6852. CreateId;
  6853. SetupParameters(BuildWithGlu);
  6854. UploadData(Target, BuildWithGlu);
  6855. glAreTexturesResident(1, @fID, @fIsResident);
  6856. end;
  6857. end;
  6858. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6859. function TglBitmap2D.FlipHorz: Boolean;
  6860. var
  6861. Col, Row: Integer;
  6862. TempDestData, DestData, SourceData: PByte;
  6863. ImgSize: Integer;
  6864. begin
  6865. result := inherited FlipHorz;
  6866. if Assigned(Data) then begin
  6867. SourceData := Data;
  6868. ImgSize := Height * fRowSize;
  6869. GetMem(DestData, ImgSize);
  6870. try
  6871. TempDestData := DestData;
  6872. Dec(TempDestData, fRowSize + fPixelSize);
  6873. for Row := 0 to Height -1 do begin
  6874. Inc(TempDestData, fRowSize * 2);
  6875. for Col := 0 to Width -1 do begin
  6876. Move(SourceData^, TempDestData^, fPixelSize);
  6877. Inc(SourceData, fPixelSize);
  6878. Dec(TempDestData, fPixelSize);
  6879. end;
  6880. end;
  6881. SetDataPointer(DestData, Format); //be careful, Data could be freed by this method
  6882. result := true;
  6883. except
  6884. if Assigned(DestData) then
  6885. FreeMem(DestData);
  6886. raise;
  6887. end;
  6888. end;
  6889. end;
  6890. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6891. function TglBitmap2D.FlipVert: Boolean;
  6892. var
  6893. Row: Integer;
  6894. TempDestData, DestData, SourceData: PByte;
  6895. begin
  6896. result := inherited FlipVert;
  6897. if Assigned(Data) then begin
  6898. SourceData := Data;
  6899. GetMem(DestData, Height * fRowSize);
  6900. try
  6901. TempDestData := DestData;
  6902. Inc(TempDestData, Width * (Height -1) * fPixelSize);
  6903. for Row := 0 to Height -1 do begin
  6904. Move(SourceData^, TempDestData^, fRowSize);
  6905. Dec(TempDestData, fRowSize);
  6906. Inc(SourceData, fRowSize);
  6907. end;
  6908. SetDataPointer(DestData, Format); //be careful, Data could be freed by this method
  6909. result := true;
  6910. except
  6911. if Assigned(DestData) then
  6912. FreeMem(DestData);
  6913. raise;
  6914. end;
  6915. end;
  6916. end;
  6917. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6918. //TglBitmap2D - ToNormalMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6919. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6920. type
  6921. TMatrixItem = record
  6922. X, Y: Integer;
  6923. W: Single;
  6924. end;
  6925. PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
  6926. TglBitmapToNormalMapRec = Record
  6927. Scale: Single;
  6928. Heights: array of Single;
  6929. MatrixU : array of TMatrixItem;
  6930. MatrixV : array of TMatrixItem;
  6931. end;
  6932. const
  6933. ONE_OVER_255 = 1 / 255;
  6934. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6935. procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
  6936. var
  6937. Val: Single;
  6938. begin
  6939. with FuncRec do begin
  6940. Val :=
  6941. Source.Data.r * LUMINANCE_WEIGHT_R +
  6942. Source.Data.g * LUMINANCE_WEIGHT_G +
  6943. Source.Data.b * LUMINANCE_WEIGHT_B;
  6944. PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255;
  6945. end;
  6946. end;
  6947. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6948. procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
  6949. begin
  6950. with FuncRec do
  6951. PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
  6952. end;
  6953. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6954. procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
  6955. type
  6956. TVec = Array[0..2] of Single;
  6957. var
  6958. Idx: Integer;
  6959. du, dv: Double;
  6960. Len: Single;
  6961. Vec: TVec;
  6962. function GetHeight(X, Y: Integer): Single;
  6963. begin
  6964. with FuncRec do begin
  6965. X := Max(0, Min(Size.X -1, X));
  6966. Y := Max(0, Min(Size.Y -1, Y));
  6967. result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
  6968. end;
  6969. end;
  6970. begin
  6971. with FuncRec do begin
  6972. with PglBitmapToNormalMapRec(Args)^ do begin
  6973. du := 0;
  6974. for Idx := Low(MatrixU) to High(MatrixU) do
  6975. du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
  6976. dv := 0;
  6977. for Idx := Low(MatrixU) to High(MatrixU) do
  6978. dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
  6979. Vec[0] := -du * Scale;
  6980. Vec[1] := -dv * Scale;
  6981. Vec[2] := 1;
  6982. end;
  6983. // Normalize
  6984. Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
  6985. if Len <> 0 then begin
  6986. Vec[0] := Vec[0] * Len;
  6987. Vec[1] := Vec[1] * Len;
  6988. Vec[2] := Vec[2] * Len;
  6989. end;
  6990. // Farbe zuweisem
  6991. Dest.Data.r := Trunc((Vec[0] + 1) * 127.5);
  6992. Dest.Data.g := Trunc((Vec[1] + 1) * 127.5);
  6993. Dest.Data.b := Trunc((Vec[2] + 1) * 127.5);
  6994. end;
  6995. end;
  6996. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6997. procedure TglBitmap2D.ToNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
  6998. var
  6999. Rec: TglBitmapToNormalMapRec;
  7000. procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
  7001. begin
  7002. if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
  7003. Matrix[Index].X := X;
  7004. Matrix[Index].Y := Y;
  7005. Matrix[Index].W := W;
  7006. end;
  7007. end;
  7008. begin
  7009. if TFormatDescriptor.Get(Format).IsCompressed then
  7010. raise EglBitmapUnsupportedFormat.Create(Format);
  7011. if aScale > 100 then
  7012. Rec.Scale := 100
  7013. else if aScale < -100 then
  7014. Rec.Scale := -100
  7015. else
  7016. Rec.Scale := aScale;
  7017. SetLength(Rec.Heights, Width * Height);
  7018. try
  7019. case aFunc of
  7020. nm4Samples: begin
  7021. SetLength(Rec.MatrixU, 2);
  7022. SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
  7023. SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
  7024. SetLength(Rec.MatrixV, 2);
  7025. SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
  7026. SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
  7027. end;
  7028. nmSobel: begin
  7029. SetLength(Rec.MatrixU, 6);
  7030. SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
  7031. SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
  7032. SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
  7033. SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
  7034. SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
  7035. SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
  7036. SetLength(Rec.MatrixV, 6);
  7037. SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
  7038. SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
  7039. SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
  7040. SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
  7041. SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
  7042. SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
  7043. end;
  7044. nm3x3: begin
  7045. SetLength(Rec.MatrixU, 6);
  7046. SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
  7047. SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
  7048. SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
  7049. SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
  7050. SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
  7051. SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
  7052. SetLength(Rec.MatrixV, 6);
  7053. SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
  7054. SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
  7055. SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
  7056. SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
  7057. SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
  7058. SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
  7059. end;
  7060. nm5x5: begin
  7061. SetLength(Rec.MatrixU, 20);
  7062. SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
  7063. SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
  7064. SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
  7065. SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
  7066. SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
  7067. SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
  7068. SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
  7069. SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
  7070. SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
  7071. SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
  7072. SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
  7073. SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
  7074. SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
  7075. SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
  7076. SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
  7077. SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
  7078. SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
  7079. SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
  7080. SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
  7081. SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
  7082. SetLength(Rec.MatrixV, 20);
  7083. SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
  7084. SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
  7085. SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
  7086. SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
  7087. SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
  7088. SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
  7089. SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
  7090. SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
  7091. SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
  7092. SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
  7093. SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
  7094. SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
  7095. SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
  7096. SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
  7097. SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
  7098. SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
  7099. SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
  7100. SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
  7101. SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
  7102. SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
  7103. end;
  7104. end;
  7105. // Daten Sammeln
  7106. if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
  7107. AddFunc(glBitmapToNormalMapPrepareAlphaFunc, false, @Rec)
  7108. else
  7109. AddFunc(glBitmapToNormalMapPrepareFunc, false, @Rec);
  7110. AddFunc(glBitmapToNormalMapFunc, false, @Rec);
  7111. finally
  7112. SetLength(Rec.Heights, 0);
  7113. end;
  7114. end;
  7115. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7116. //TglBitmapCubeMap////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7117. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7118. procedure TglBitmapCubeMap.GenTexture(const aTestTextureSize: Boolean);
  7119. begin
  7120. Assert(false, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
  7121. end;
  7122. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7123. procedure TglBitmapCubeMap.AfterConstruction;
  7124. begin
  7125. inherited;
  7126. if not (GL_VERSION_1_3 or GL_ARB_texture_cube_map or GL_EXT_texture_cube_map) then
  7127. raise EglBitmap.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
  7128. SetWrap;
  7129. Target := GL_TEXTURE_CUBE_MAP;
  7130. fGenMode := GL_REFLECTION_MAP;
  7131. end;
  7132. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7133. procedure TglBitmapCubeMap.GenerateCubeMap(const aCubeTarget: Cardinal; const aTestTextureSize: Boolean);
  7134. var
  7135. BuildWithGlu: Boolean;
  7136. TexSize: Integer;
  7137. begin
  7138. if (aTestTextureSize) then begin
  7139. glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @TexSize);
  7140. if (Height > TexSize) or (Width > TexSize) then
  7141. raise EglBitmapSizeToLarge.Create('TglBitmapCubeMap.GenTexture - The size for the Cubemap is to large. It''s may be not conform with the Hardware.');
  7142. if not ((IsPowerOfTwo(Height) and IsPowerOfTwo(Width)) or GL_VERSION_2_0 or GL_ARB_texture_non_power_of_two) then
  7143. raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenTexture - Cubemaps dosn''t support non power of two texture.');
  7144. end;
  7145. if (ID = 0) then
  7146. CreateID;
  7147. SetupParameters(BuildWithGlu);
  7148. UploadData(aCubeTarget, BuildWithGlu);
  7149. end;
  7150. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7151. procedure TglBitmapCubeMap.Bind(const aEnableTexCoordsGen: Boolean; const aEnableTextureUnit: Boolean);
  7152. begin
  7153. inherited Bind (aEnableTextureUnit);
  7154. if aEnableTexCoordsGen then begin
  7155. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, fGenMode);
  7156. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, fGenMode);
  7157. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, fGenMode);
  7158. glEnable(GL_TEXTURE_GEN_S);
  7159. glEnable(GL_TEXTURE_GEN_T);
  7160. glEnable(GL_TEXTURE_GEN_R);
  7161. end;
  7162. end;
  7163. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7164. procedure TglBitmapCubeMap.Unbind(const aDisableTexCoordsGen: Boolean; const aDisableTextureUnit: Boolean);
  7165. begin
  7166. inherited Unbind(aDisableTextureUnit);
  7167. if aDisableTexCoordsGen then begin
  7168. glDisable(GL_TEXTURE_GEN_S);
  7169. glDisable(GL_TEXTURE_GEN_T);
  7170. glDisable(GL_TEXTURE_GEN_R);
  7171. end;
  7172. end;
  7173. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7174. //TglBitmapNormalMap//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7175. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7176. type
  7177. TVec = Array[0..2] of Single;
  7178. TglBitmapNormalMapGetVectorFunc = procedure (out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
  7179. PglBitmapNormalMapRec = ^TglBitmapNormalMapRec;
  7180. TglBitmapNormalMapRec = record
  7181. HalfSize : Integer;
  7182. Func: TglBitmapNormalMapGetVectorFunc;
  7183. end;
  7184. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7185. procedure glBitmapNormalMapPosX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
  7186. begin
  7187. aVec[0] := aHalfSize;
  7188. aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
  7189. aVec[2] := - (aPosition.X + 0.5 - aHalfSize);
  7190. end;
  7191. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7192. procedure glBitmapNormalMapNegX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
  7193. begin
  7194. aVec[0] := - aHalfSize;
  7195. aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
  7196. aVec[2] := aPosition.X + 0.5 - aHalfSize;
  7197. end;
  7198. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7199. procedure glBitmapNormalMapPosY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
  7200. begin
  7201. aVec[0] := aPosition.X + 0.5 - aHalfSize;
  7202. aVec[1] := aHalfSize;
  7203. aVec[2] := aPosition.Y + 0.5 - aHalfSize;
  7204. end;
  7205. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7206. procedure glBitmapNormalMapNegY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
  7207. begin
  7208. aVec[0] := aPosition.X + 0.5 - aHalfSize;
  7209. aVec[1] := - aHalfSize;
  7210. aVec[2] := - (aPosition.Y + 0.5 - aHalfSize);
  7211. end;
  7212. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7213. procedure glBitmapNormalMapPosZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
  7214. begin
  7215. aVec[0] := aPosition.X + 0.5 - aHalfSize;
  7216. aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
  7217. aVec[2] := aHalfSize;
  7218. end;
  7219. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7220. procedure glBitmapNormalMapNegZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
  7221. begin
  7222. aVec[0] := - (aPosition.X + 0.5 - aHalfSize);
  7223. aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
  7224. aVec[2] := - aHalfSize;
  7225. end;
  7226. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7227. procedure glBitmapNormalMapFunc(var FuncRec: TglBitmapFunctionRec);
  7228. var
  7229. i: Integer;
  7230. Vec: TVec;
  7231. Len: Single;
  7232. begin
  7233. with FuncRec do begin
  7234. with PglBitmapNormalMapRec(Args)^ do begin
  7235. Func(Vec, Position, HalfSize);
  7236. // Normalize
  7237. Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
  7238. if Len <> 0 then begin
  7239. Vec[0] := Vec[0] * Len;
  7240. Vec[1] := Vec[1] * Len;
  7241. Vec[2] := Vec[2] * Len;
  7242. end;
  7243. // Scale Vector and AddVectro
  7244. Vec[0] := Vec[0] * 0.5 + 0.5;
  7245. Vec[1] := Vec[1] * 0.5 + 0.5;
  7246. Vec[2] := Vec[2] * 0.5 + 0.5;
  7247. end;
  7248. // Set Color
  7249. for i := 0 to 2 do
  7250. Dest.Data.arr[i] := Round(Vec[i] * 255);
  7251. end;
  7252. end;
  7253. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7254. procedure TglBitmapNormalMap.AfterConstruction;
  7255. begin
  7256. inherited;
  7257. fGenMode := GL_NORMAL_MAP;
  7258. end;
  7259. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7260. procedure TglBitmapNormalMap.GenerateNormalMap(const aSize: Integer; const aTestTextureSize: Boolean);
  7261. var
  7262. Rec: TglBitmapNormalMapRec;
  7263. SizeRec: TglBitmapPixelPosition;
  7264. begin
  7265. Rec.HalfSize := aSize div 2;
  7266. FreeDataAfterGenTexture := false;
  7267. SizeRec.Fields := [ffX, ffY];
  7268. SizeRec.X := aSize;
  7269. SizeRec.Y := aSize;
  7270. // Positive X
  7271. Rec.Func := glBitmapNormalMapPosX;
  7272. LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8, @Rec);
  7273. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X, aTestTextureSize);
  7274. // Negative X
  7275. Rec.Func := glBitmapNormalMapNegX;
  7276. LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8, @Rec);
  7277. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, aTestTextureSize);
  7278. // Positive Y
  7279. Rec.Func := glBitmapNormalMapPosY;
  7280. LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8, @Rec);
  7281. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, aTestTextureSize);
  7282. // Negative Y
  7283. Rec.Func := glBitmapNormalMapNegY;
  7284. LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8, @Rec);
  7285. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, aTestTextureSize);
  7286. // Positive Z
  7287. Rec.Func := glBitmapNormalMapPosZ;
  7288. LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8, @Rec);
  7289. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, aTestTextureSize);
  7290. // Negative Z
  7291. Rec.Func := glBitmapNormalMapNegZ;
  7292. LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8, @Rec);
  7293. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, aTestTextureSize);
  7294. end;
  7295. initialization
  7296. glBitmapSetDefaultFormat (tfEmpty);
  7297. glBitmapSetDefaultMipmap (mmMipmap);
  7298. glBitmapSetDefaultFilter (GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
  7299. glBitmapSetDefaultWrap (GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
  7300. glBitmapSetDefaultSwizzle(GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA);
  7301. glBitmapSetDefaultFreeDataAfterGenTexture(true);
  7302. glBitmapSetDefaultDeleteTextureOnFree (true);
  7303. TFormatDescriptor.Init;
  7304. {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
  7305. OpenGLInitialized := false;
  7306. InitOpenGLCS := TCriticalSection.Create;
  7307. {$ENDIF}
  7308. finalization
  7309. TFormatDescriptor.Finalize;
  7310. {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
  7311. FreeAndNil(InitOpenGLCS);
  7312. {$ENDIF}
  7313. end.