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

8915 lines
318 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.1
  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 error '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 Delphi (including support for Delphi's (not Lazarus') TBitmap)
  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 Lazarus TPortableNetworkGraphic support
  241. // if you enable this pngImage and libPNG will be ignored
  242. {.$DEFINE GLB_LAZ_PNG}
  243. // activate to enable png support with the unit pngimage -> http://pngdelphi.sourceforge.net/
  244. // if you enable pngimage the libPNG will be ignored
  245. {.$DEFINE GLB_PNGIMAGE}
  246. // activate to use the libPNG -> http://www.libpng.org/
  247. // You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libpng
  248. {.$DEFINE GLB_LIB_PNG}
  249. // activate to enable Lazarus TJPEGImage support
  250. // if you enable this delphi jpegs and libJPEG will be ignored
  251. {.$DEFINE GLB_LAZ_JPEG}
  252. // if you enable delphi jpegs the libJPEG will be ignored
  253. {.$DEFINE GLB_DELPHI_JPEG}
  254. // activate to use the libJPEG -> http://www.ijg.org/
  255. // You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libjpeg
  256. {.$DEFINE GLB_LIB_JPEG}
  257. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  258. // PRIVATE: do not change anything! //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  259. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  260. // Delphi Versions
  261. {$IFDEF fpc}
  262. {$MODE Delphi}
  263. {$IFDEF CPUI386}
  264. {$DEFINE CPU386}
  265. {$ASMMODE INTEL}
  266. {$ENDIF}
  267. {$IFNDEF WINDOWS}
  268. {$linklib c}
  269. {$ENDIF}
  270. {$ENDIF}
  271. // Operation System
  272. {$IF DEFINED(WIN32) or DEFINED(WIN64) or DEFINED(WINDOWS)}
  273. {$DEFINE GLB_WIN}
  274. {$ELSEIF DEFINED(LINUX)}
  275. {$DEFINE GLB_LINUX}
  276. {$IFEND}
  277. // native OpenGL Support
  278. {$IF DEFINED(GLB_NATIVE_OGL_STATIC) OR DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
  279. {$DEFINE GLB_NATIVE_OGL}
  280. {$IFEND}
  281. // checking define combinations
  282. //SDL Image
  283. {$IFDEF GLB_SDL_IMAGE}
  284. {$IFNDEF GLB_SDL}
  285. {$MESSAGE warn 'SDL_image won''t work without SDL. SDL will be activated.'}
  286. {$DEFINE GLB_SDL}
  287. {$ENDIF}
  288. {$IFDEF GLB_LAZ_PNG}
  289. {$MESSAGE warn 'The Lazarus TPortableNetworkGraphics will be ignored because you are using SDL_image.'}
  290. {$undef GLB_LAZ_PNG}
  291. {$ENDIF}
  292. {$IFDEF GLB_PNGIMAGE}
  293. {$MESSAGE warn 'The unit pngimage will be ignored because you are using SDL_image.'}
  294. {$undef GLB_PNGIMAGE}
  295. {$ENDIF}
  296. {$IFDEF GLB_LAZ_JPEG}
  297. {$MESSAGE warn 'The Lazarus TJPEGImage will be ignored because you are using SDL_image.'}
  298. {$undef GLB_LAZ_JPEG}
  299. {$ENDIF}
  300. {$IFDEF GLB_DELPHI_JPEG}
  301. {$MESSAGE warn 'The unit JPEG will be ignored because you are using SDL_image.'}
  302. {$undef GLB_DELPHI_JPEG}
  303. {$ENDIF}
  304. {$IFDEF GLB_LIB_PNG}
  305. {$MESSAGE warn 'The library libPNG will be ignored because you are using SDL_image.'}
  306. {$undef GLB_LIB_PNG}
  307. {$ENDIF}
  308. {$IFDEF GLB_LIB_JPEG}
  309. {$MESSAGE warn 'The library libJPEG will be ignored because you are using SDL_image.'}
  310. {$undef GLB_LIB_JPEG}
  311. {$ENDIF}
  312. {$DEFINE GLB_SUPPORT_PNG_READ}
  313. {$DEFINE GLB_SUPPORT_JPEG_READ}
  314. {$ENDIF}
  315. // Lazarus TPortableNetworkGraphic
  316. {$IFDEF GLB_LAZ_PNG}
  317. {$IFNDEF GLB_LAZARUS}
  318. {$MESSAGE warn 'Lazarus TPortableNetworkGraphic won''t work without Lazarus. Lazarus will be activated.'}
  319. {$DEFINE GLB_LAZARUS}
  320. {$ENDIF}
  321. {$IFDEF GLB_PNGIMAGE}
  322. {$MESSAGE warn 'The pngimage will be ignored if you are using Lazarus TPortableNetworkGraphic.'}
  323. {$undef GLB_PNGIMAGE}
  324. {$ENDIF}
  325. {$IFDEF GLB_LIB_PNG}
  326. {$MESSAGE warn 'The library libPNG will be ignored if you are using Lazarus TPortableNetworkGraphic.'}
  327. {$undef GLB_LIB_PNG}
  328. {$ENDIF}
  329. {$DEFINE GLB_SUPPORT_PNG_READ}
  330. {$DEFINE GLB_SUPPORT_PNG_WRITE}
  331. {$ENDIF}
  332. // PNG Image
  333. {$IFDEF GLB_PNGIMAGE}
  334. {$IFDEF GLB_LIB_PNG}
  335. {$MESSAGE warn 'The library libPNG will be ignored if you are using pngimage.'}
  336. {$undef GLB_LIB_PNG}
  337. {$ENDIF}
  338. {$DEFINE GLB_SUPPORT_PNG_READ}
  339. {$DEFINE GLB_SUPPORT_PNG_WRITE}
  340. {$ENDIF}
  341. // libPNG
  342. {$IFDEF GLB_LIB_PNG}
  343. {$DEFINE GLB_SUPPORT_PNG_READ}
  344. {$DEFINE GLB_SUPPORT_PNG_WRITE}
  345. {$ENDIF}
  346. // Lazarus TJPEGImage
  347. {$IFDEF GLB_LAZ_JPEG}
  348. {$IFNDEF GLB_LAZARUS}
  349. {$MESSAGE warn 'Lazarus TJPEGImage won''t work without Lazarus. Lazarus will be activated.'}
  350. {$DEFINE GLB_LAZARUS}
  351. {$ENDIF}
  352. {$IFDEF GLB_DELPHI_JPEG}
  353. {$MESSAGE warn 'The Delphi JPEGImage will be ignored if you are using the Lazarus TJPEGImage.'}
  354. {$undef GLB_DELPHI_JPEG}
  355. {$ENDIF}
  356. {$IFDEF GLB_LIB_JPEG}
  357. {$MESSAGE warn 'The library libJPEG will be ignored if you are using the Lazarus TJPEGImage.'}
  358. {$undef GLB_LIB_JPEG}
  359. {$ENDIF}
  360. {$DEFINE GLB_SUPPORT_JPEG_READ}
  361. {$DEFINE GLB_SUPPORT_JPEG_WRITE}
  362. {$ENDIF}
  363. // JPEG Image
  364. {$IFDEF GLB_DELPHI_JPEG}
  365. {$IFDEF GLB_LIB_JPEG}
  366. {$MESSAGE warn 'The library libJPEG will be ignored if you are using the unit JPEG.'}
  367. {$undef GLB_LIB_JPEG}
  368. {$ENDIF}
  369. {$DEFINE GLB_SUPPORT_JPEG_READ}
  370. {$DEFINE GLB_SUPPORT_JPEG_WRITE}
  371. {$ENDIF}
  372. // libJPEG
  373. {$IFDEF GLB_LIB_JPEG}
  374. {$DEFINE GLB_SUPPORT_JPEG_READ}
  375. {$DEFINE GLB_SUPPORT_JPEG_WRITE}
  376. {$ENDIF}
  377. // native OpenGL
  378. {$IF DEFINED(GLB_NATIVE_OGL_STATIC) AND DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
  379. {$MESSAGE warn 'GLB_NATIVE_OGL_STATIC will be ignored because you enabled GLB_NATIVE_OGL_DYNAMIC'}
  380. {$IFEND}
  381. // general options
  382. {$EXTENDEDSYNTAX ON}
  383. {$LONGSTRINGS ON}
  384. {$ALIGN ON}
  385. {$IFNDEF FPC}
  386. {$OPTIMIZATION ON}
  387. {$ENDIF}
  388. interface
  389. uses
  390. {$IFNDEF GLB_NATIVE_OGL} dglOpenGL, {$ENDIF}
  391. {$IF DEFINED(GLB_WIN) AND
  392. (DEFINED(GLB_NATIVE_OGL) OR
  393. DEFINED(GLB_DELPHI))} windows, {$IFEND}
  394. {$IFDEF GLB_SDL} SDL, {$ENDIF}
  395. {$IFDEF GLB_LAZARUS} IntfGraphics, GraphType, Graphics, {$ENDIF}
  396. {$IFDEF GLB_DELPHI} Dialogs, Graphics, Types, {$ENDIF}
  397. {$IFDEF GLB_SDL_IMAGE} SDL_image, {$ENDIF}
  398. {$IFDEF GLB_PNGIMAGE} pngimage, {$ENDIF}
  399. {$IFDEF GLB_LIB_PNG} libPNG, {$ENDIF}
  400. {$IFDEF GLB_DELPHI_JPEG} JPEG, {$ENDIF}
  401. {$IFDEF GLB_LIB_JPEG} libJPEG, {$ENDIF}
  402. Classes, SysUtils;
  403. {$IFDEF GLB_NATIVE_OGL}
  404. const
  405. GL_TRUE = 1;
  406. GL_FALSE = 0;
  407. GL_ZERO = 0;
  408. GL_ONE = 1;
  409. GL_VERSION = $1F02;
  410. GL_EXTENSIONS = $1F03;
  411. GL_TEXTURE_1D = $0DE0;
  412. GL_TEXTURE_2D = $0DE1;
  413. GL_TEXTURE_RECTANGLE = $84F5;
  414. GL_NORMAL_MAP = $8511;
  415. GL_TEXTURE_CUBE_MAP = $8513;
  416. GL_REFLECTION_MAP = $8512;
  417. GL_TEXTURE_CUBE_MAP_POSITIVE_X = $8515;
  418. GL_TEXTURE_CUBE_MAP_NEGATIVE_X = $8516;
  419. GL_TEXTURE_CUBE_MAP_POSITIVE_Y = $8517;
  420. GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = $8518;
  421. GL_TEXTURE_CUBE_MAP_POSITIVE_Z = $8519;
  422. GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = $851A;
  423. GL_TEXTURE_WIDTH = $1000;
  424. GL_TEXTURE_HEIGHT = $1001;
  425. GL_TEXTURE_INTERNAL_FORMAT = $1003;
  426. GL_TEXTURE_SWIZZLE_RGBA = $8E46;
  427. GL_S = $2000;
  428. GL_T = $2001;
  429. GL_R = $2002;
  430. GL_Q = $2003;
  431. GL_TEXTURE_GEN_S = $0C60;
  432. GL_TEXTURE_GEN_T = $0C61;
  433. GL_TEXTURE_GEN_R = $0C62;
  434. GL_TEXTURE_GEN_Q = $0C63;
  435. GL_RED = $1903;
  436. GL_GREEN = $1904;
  437. GL_BLUE = $1905;
  438. GL_ALPHA = $1906;
  439. GL_ALPHA4 = $803B;
  440. GL_ALPHA8 = $803C;
  441. GL_ALPHA12 = $803D;
  442. GL_ALPHA16 = $803E;
  443. GL_LUMINANCE = $1909;
  444. GL_LUMINANCE4 = $803F;
  445. GL_LUMINANCE8 = $8040;
  446. GL_LUMINANCE12 = $8041;
  447. GL_LUMINANCE16 = $8042;
  448. GL_LUMINANCE_ALPHA = $190A;
  449. GL_LUMINANCE4_ALPHA4 = $8043;
  450. GL_LUMINANCE6_ALPHA2 = $8044;
  451. GL_LUMINANCE8_ALPHA8 = $8045;
  452. GL_LUMINANCE12_ALPHA4 = $8046;
  453. GL_LUMINANCE12_ALPHA12 = $8047;
  454. GL_LUMINANCE16_ALPHA16 = $8048;
  455. GL_RGB = $1907;
  456. GL_BGR = $80E0;
  457. GL_R3_G3_B2 = $2A10;
  458. GL_RGB4 = $804F;
  459. GL_RGB5 = $8050;
  460. GL_RGB565 = $8D62;
  461. GL_RGB8 = $8051;
  462. GL_RGB10 = $8052;
  463. GL_RGB12 = $8053;
  464. GL_RGB16 = $8054;
  465. GL_RGBA = $1908;
  466. GL_BGRA = $80E1;
  467. GL_RGBA2 = $8055;
  468. GL_RGBA4 = $8056;
  469. GL_RGB5_A1 = $8057;
  470. GL_RGBA8 = $8058;
  471. GL_RGB10_A2 = $8059;
  472. GL_RGBA12 = $805A;
  473. GL_RGBA16 = $805B;
  474. GL_DEPTH_COMPONENT = $1902;
  475. GL_DEPTH_COMPONENT16 = $81A5;
  476. GL_DEPTH_COMPONENT24 = $81A6;
  477. GL_DEPTH_COMPONENT32 = $81A7;
  478. GL_COMPRESSED_RGB = $84ED;
  479. GL_COMPRESSED_RGBA = $84EE;
  480. GL_COMPRESSED_RGB_S3TC_DXT1_EXT = $83F0;
  481. GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = $83F1;
  482. GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = $83F2;
  483. GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = $83F3;
  484. GL_UNSIGNED_BYTE = $1401;
  485. GL_UNSIGNED_BYTE_3_3_2 = $8032;
  486. GL_UNSIGNED_BYTE_2_3_3_REV = $8362;
  487. GL_UNSIGNED_SHORT = $1403;
  488. GL_UNSIGNED_SHORT_5_6_5 = $8363;
  489. GL_UNSIGNED_SHORT_4_4_4_4 = $8033;
  490. GL_UNSIGNED_SHORT_5_5_5_1 = $8034;
  491. GL_UNSIGNED_SHORT_5_6_5_REV = $8364;
  492. GL_UNSIGNED_SHORT_4_4_4_4_REV = $8365;
  493. GL_UNSIGNED_SHORT_1_5_5_5_REV = $8366;
  494. GL_UNSIGNED_INT = $1405;
  495. GL_UNSIGNED_INT_8_8_8_8 = $8035;
  496. GL_UNSIGNED_INT_10_10_10_2 = $8036;
  497. GL_UNSIGNED_INT_8_8_8_8_REV = $8367;
  498. GL_UNSIGNED_INT_2_10_10_10_REV = $8368;
  499. { Texture Filter }
  500. GL_TEXTURE_MAG_FILTER = $2800;
  501. GL_TEXTURE_MIN_FILTER = $2801;
  502. GL_NEAREST = $2600;
  503. GL_NEAREST_MIPMAP_NEAREST = $2700;
  504. GL_NEAREST_MIPMAP_LINEAR = $2702;
  505. GL_LINEAR = $2601;
  506. GL_LINEAR_MIPMAP_NEAREST = $2701;
  507. GL_LINEAR_MIPMAP_LINEAR = $2703;
  508. { Texture Wrap }
  509. GL_TEXTURE_WRAP_S = $2802;
  510. GL_TEXTURE_WRAP_T = $2803;
  511. GL_TEXTURE_WRAP_R = $8072;
  512. GL_CLAMP = $2900;
  513. GL_REPEAT = $2901;
  514. GL_CLAMP_TO_EDGE = $812F;
  515. GL_CLAMP_TO_BORDER = $812D;
  516. GL_MIRRORED_REPEAT = $8370;
  517. { Other }
  518. GL_GENERATE_MIPMAP = $8191;
  519. GL_TEXTURE_BORDER_COLOR = $1004;
  520. GL_MAX_TEXTURE_SIZE = $0D33;
  521. GL_PACK_ALIGNMENT = $0D05;
  522. GL_UNPACK_ALIGNMENT = $0CF5;
  523. GL_TEXTURE_MAX_ANISOTROPY_EXT = $84FE;
  524. GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = $84FF;
  525. GL_MAX_CUBE_MAP_TEXTURE_SIZE = $851C;
  526. GL_TEXTURE_GEN_MODE = $2500;
  527. {$IF DEFINED(GLB_WIN)}
  528. libglu = 'glu32.dll';
  529. libopengl = 'opengl32.dll';
  530. {$ELSEIF DEFINED(GLB_LINUX)}
  531. libglu = 'libGLU.so.1';
  532. libopengl = 'libGL.so.1';
  533. {$IFEND}
  534. type
  535. GLboolean = BYTEBOOL;
  536. GLint = Integer;
  537. GLsizei = Integer;
  538. GLuint = Cardinal;
  539. GLfloat = Single;
  540. GLenum = Cardinal;
  541. PGLvoid = Pointer;
  542. PGLboolean = ^GLboolean;
  543. PGLint = ^GLint;
  544. PGLuint = ^GLuint;
  545. PGLfloat = ^GLfloat;
  546. TglCompressedTexImage1D = procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  547. 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}
  548. TglGetCompressedTexImage = procedure(target: GLenum; level: GLint; img: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  549. {$IF DEFINED(GLB_WIN)}
  550. TwglGetProcAddress = function (ProcName: PAnsiChar): Pointer; stdcall;
  551. {$ELSEIF DEFINED(GLB_LINUX)}
  552. TglXGetProcAddress = function(ProcName: PAnsiChar): Pointer; cdecl;
  553. TglXGetProcAddressARB = function(const name: PAnsiChar): pointer; cdecl;
  554. {$IFEND}
  555. {$IF DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
  556. TglEnable = procedure(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  557. TglDisable = procedure(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  558. TglGetString = function(name: GLenum): PAnsiChar; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  559. TglGetIntegerv = procedure(pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  560. TglTexParameteri = procedure(target: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  561. TglTexParameteriv = procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  562. TglTexParameterfv = procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  563. TglGetTexParameteriv = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  564. TglGetTexParameterfv = procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  565. TglGetTexLevelParameteriv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  566. TglGetTexLevelParameterfv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  567. TglTexGeni = procedure(coord: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  568. TglGenTextures = procedure(n: GLsizei; textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  569. TglBindTexture = procedure(target: GLenum; texture: GLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  570. TglDeleteTextures = procedure(n: GLsizei; const textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  571. TglAreTexturesResident = function(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  572. TglReadPixels = procedure(x: GLint; y: GLint; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  573. TglPixelStorei = procedure(pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  574. 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}
  575. 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}
  576. TglGetTexImage = procedure(target: GLenum; level: GLint; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  577. TgluBuild1DMipmaps = function(target: GLEnum; components, width: GLint; format, atype: GLEnum; const data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  578. TgluBuild2DMipmaps = function(target: GLEnum; components, width, height: GLint; format, atype: GLEnum; const Data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  579. {$ELSEIF DEFINED(GLB_NATIVE_OGL_STATIC)}
  580. procedure glEnable(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  581. procedure glDisable(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  582. function glGetString(name: GLenum): PAnsiChar; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  583. procedure glGetIntegerv(pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  584. procedure glTexParameteri(target: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  585. procedure glTexParameteriv(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  586. procedure glTexParameterfv(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  587. procedure glGetTexParameteriv(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  588. procedure glGetTexParameterfv(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  589. procedure glGetTexLevelParameteriv(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  590. procedure glGetTexLevelParameterfv(target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  591. procedure glTexGeni(coord: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  592. procedure glGenTextures(n: GLsizei; textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  593. procedure glBindTexture(target: GLenum; texture: GLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  594. procedure glDeleteTextures(n: GLsizei; const textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  595. function glAreTexturesResident(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  596. 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;
  597. procedure glPixelStorei(pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  598. 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;
  599. 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;
  600. procedure glGetTexImage(target: GLenum; level: GLint; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  601. function gluBuild1DMipmaps(target: GLEnum; components, width: GLint; format, atype: GLEnum; const data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libglu;
  602. function gluBuild2DMipmaps(target: GLEnum; components, width, height: GLint; format, atype: GLEnum; const Data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libglu;
  603. {$IFEND}
  604. var
  605. GL_VERSION_1_2,
  606. GL_VERSION_1_3,
  607. GL_VERSION_1_4,
  608. GL_VERSION_2_0,
  609. GL_VERSION_3_3,
  610. GL_SGIS_generate_mipmap,
  611. GL_ARB_texture_border_clamp,
  612. GL_ARB_texture_mirrored_repeat,
  613. GL_ARB_texture_rectangle,
  614. GL_ARB_texture_non_power_of_two,
  615. GL_ARB_texture_swizzle,
  616. GL_ARB_texture_cube_map,
  617. GL_IBM_texture_mirrored_repeat,
  618. GL_NV_texture_rectangle,
  619. GL_EXT_texture_edge_clamp,
  620. GL_EXT_texture_rectangle,
  621. GL_EXT_texture_swizzle,
  622. GL_EXT_texture_cube_map,
  623. GL_EXT_texture_filter_anisotropic: Boolean;
  624. glCompressedTexImage1D: TglCompressedTexImage1D;
  625. glCompressedTexImage2D: TglCompressedTexImage2D;
  626. glGetCompressedTexImage: TglGetCompressedTexImage;
  627. {$IF DEFINED(GLB_WIN)}
  628. wglGetProcAddress: TwglGetProcAddress;
  629. {$ELSEIF DEFINED(GLB_LINUX)}
  630. glXGetProcAddress: TglXGetProcAddress;
  631. glXGetProcAddressARB: TglXGetProcAddress;
  632. {$IFEND}
  633. {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
  634. glEnable: TglEnable;
  635. glDisable: TglDisable;
  636. glGetString: TglGetString;
  637. glGetIntegerv: TglGetIntegerv;
  638. glTexParameteri: TglTexParameteri;
  639. glTexParameteriv: TglTexParameteriv;
  640. glTexParameterfv: TglTexParameterfv;
  641. glGetTexParameteriv: TglGetTexParameteriv;
  642. glGetTexParameterfv: TglGetTexParameterfv;
  643. glGetTexLevelParameteriv: TglGetTexLevelParameteriv;
  644. glGetTexLevelParameterfv: TglGetTexLevelParameterfv;
  645. glTexGeni: TglTexGeni;
  646. glGenTextures: TglGenTextures;
  647. glBindTexture: TglBindTexture;
  648. glDeleteTextures: TglDeleteTextures;
  649. glAreTexturesResident: TglAreTexturesResident;
  650. glReadPixels: TglReadPixels;
  651. glPixelStorei: TglPixelStorei;
  652. glTexImage1D: TglTexImage1D;
  653. glTexImage2D: TglTexImage2D;
  654. glGetTexImage: TglGetTexImage;
  655. gluBuild1DMipmaps: TgluBuild1DMipmaps;
  656. gluBuild2DMipmaps: TgluBuild2DMipmaps;
  657. {$ENDIF}
  658. {$ENDIF}
  659. type
  660. ////////////////////////////////////////////////////////////////////////////////////////////////////
  661. // the name of formats is composed of the following constituents:
  662. // - multiple chanals:
  663. // - channel (e.g. R, G, B, A or Alpha, Luminance or X (reserved)
  664. // - width of the chanel in bit (4, 8, 16, ...)
  665. // - data type (e.g. ub, us, ui)
  666. // - number of data types
  667. {$IFNDEF fpc}
  668. QWord = System.UInt64;
  669. PQWord = ^QWord;
  670. PtrInt = Longint;
  671. PtrUInt = DWord;
  672. {$ENDIF}
  673. TglBitmapFormat = (
  674. tfEmpty = 0, //must be smallest value!
  675. tfAlpha4ub1, // 1 x unsigned byte
  676. tfAlpha8ub1, // 1 x unsigned byte
  677. tfAlpha16us1, // 1 x unsigned short
  678. tfLuminance4ub1, // 1 x unsigned byte
  679. tfLuminance8ub1, // 1 x unsigned byte
  680. tfLuminance16us1, // 1 x unsigned short
  681. tfLuminance4Alpha4ub2, // 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
  682. tfLuminance6Alpha2ub2, // 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
  683. tfLuminance8Alpha8ub2, // 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
  684. tfLuminance12Alpha4us2, // 1 x unsigned short (lum), 1 x unsigned short (alpha)
  685. tfLuminance16Alpha16us2, // 1 x unsigned short (lum), 1 x unsigned short (alpha)
  686. tfR3G3B2ub1, // 1 x unsigned byte (3bit red, 3bit green, 2bit blue)
  687. tfRGBX4us1, // 1 x unsigned short (4bit red, 4bit green, 4bit blue, 4bit reserverd)
  688. tfXRGB4us1, // 1 x unsigned short (4bit reserved, 4bit red, 4bit green, 4bit blue)
  689. tfR5G6B5us1, // 1 x unsigned short (5bit red, 6bit green, 5bit blue)
  690. tfRGB5X1us1, // 1 x unsigned short (5bit red, 5bit green, 5bit blue, 1bit reserved)
  691. tfX1RGB5us1, // 1 x unsigned short (1bit reserved, 5bit red, 5bit green, 5bit blue)
  692. tfRGB8ub3, // 1 x unsigned byte (red), 1 x unsigned byte (green), 1 x unsigned byte (blue)
  693. tfRGBX8ui1, // 1 x unsigned int (8bit red, 8bit green, 8bit blue, 8bit reserved)
  694. tfXRGB8ui1, // 1 x unsigned int (8bit reserved, 8bit red, 8bit green, 8bit blue)
  695. tfRGB10X2ui1, // 1 x unsigned int (10bit red, 10bit green, 10bit blue, 2bit reserved)
  696. tfX2RGB10ui1, // 1 x unsigned int (2bit reserved, 10bit red, 10bit green, 10bit blue)
  697. tfRGB16us3, // 1 x unsigned short (red), 1 x unsigned short (green), 1 x unsigned short (blue)
  698. tfRGBA4us1, // 1 x unsigned short (4bit red, 4bit green, 4bit blue, 4bit alpha)
  699. tfARGB4us1, // 1 x unsigned short (4bit alpha, 4bit red, 4bit green, 4bit blue)
  700. tfRGB5A1us1, // 1 x unsigned short (5bit red, 5bit green, 5bit blue, 1bit alpha)
  701. tfA1RGB5us1, // 1 x unsigned short (1bit alpha, 5bit red, 5bit green, 5bit blue)
  702. tfRGBA8ui1, // 1 x unsigned int (8bit red, 8bit green, 8bit blue, 8 bit alpha)
  703. tfARGB8ui1, // 1 x unsigned int (8 bit alpha, 8bit red, 8bit green, 8bit blue)
  704. tfRGBA8ub4, // 1 x unsigned byte (red), 1 x unsigned byte (green), 1 x unsigned byte (blue), 1 x unsigned byte (alpha)
  705. tfRGB10A2ui1, // 1 x unsigned int (10bit red, 10bit green, 10bit blue, 2bit alpha)
  706. tfA2RGB10ui1, // 1 x unsigned int (2bit alpha, 10bit red, 10bit green, 10bit blue)
  707. tfRGBA16us4, // 1 x unsigned short (red), 1 x unsigned short (green), 1 x unsigned short (blue), 1 x unsigned short (alpha)
  708. tfBGRX4us1, // 1 x unsigned short (4bit blue, 4bit green, 4bit red, 4bit reserved)
  709. tfXBGR4us1, // 1 x unsigned short (4bit reserved, 4bit blue, 4bit green, 4bit red)
  710. tfB5G6R5us1, // 1 x unsigned short (5bit blue, 6bit green, 5bit red)
  711. tfBGR5X1us1, // 1 x unsigned short (5bit blue, 5bit green, 5bit red, 1bit reserved)
  712. tfX1BGR5us1, // 1 x unsigned short (1bit reserved, 5bit blue, 5bit green, 5bit red)
  713. tfBGR8ub3, // 1 x unsigned byte (blue), 1 x unsigned byte (green), 1 x unsigned byte (red)
  714. tfBGRX8ui1, // 1 x unsigned int (8bit blue, 8bit green, 8bit red, 8bit reserved)
  715. tfXBGR8ui1, // 1 x unsigned int (8bit reserved, 8bit blue, 8bit green, 8bit red)
  716. tfBGR10X2ui1, // 1 x unsigned int (10bit blue, 10bit green, 10bit red, 2bit reserved)
  717. tfX2BGR10ui1, // 1 x unsigned int (2bit reserved, 10bit blue, 10bit green, 10bit red)
  718. tfBGR16us3, // 1 x unsigned short (blue), 1 x unsigned short (green), 1 x unsigned short (red)
  719. tfBGRA4us1, // 1 x unsigned short (4bit blue, 4bit green, 4bit red, 4bit alpha)
  720. tfABGR4us1, // 1 x unsigned short (4bit alpha, 4bit blue, 4bit green, 4bit red)
  721. tfBGR5A1us1, // 1 x unsigned short (5bit blue, 5bit green, 5bit red, 1bit alpha)
  722. tfA1BGR5us1, // 1 x unsigned short (1bit alpha, 5bit blue, 5bit green, 5bit red)
  723. tfBGRA8ui1, // 1 x unsigned int (8bit blue, 8bit green, 8bit red, 8bit alpha)
  724. tfABGR8ui1, // 1 x unsigned int (8bit alpha, 8bit blue, 8bit green, 8bit red)
  725. tfBGRA8ub4, // 1 x unsigned byte (blue), 1 x unsigned byte (green), 1 x unsigned byte (red), 1 x unsigned byte (alpha)
  726. tfBGR10A2ui1, // 1 x unsigned int (10bit blue, 10bit green, 10bit red, 2bit alpha)
  727. tfA2BGR10ui1, // 1 x unsigned int (2bit alpha, 10bit blue, 10bit green, 10bit red)
  728. tfBGRA16us4, // 1 x unsigned short (blue), 1 x unsigned short (green), 1 x unsigned short (red), 1 x unsigned short (alpha)
  729. tfDepth16us1, // 1 x unsigned short (depth)
  730. tfDepth24ui1, // 1 x unsigned int (depth)
  731. tfDepth32ui1, // 1 x unsigned int (depth)
  732. tfS3tcDtx1RGBA,
  733. tfS3tcDtx3RGBA,
  734. tfS3tcDtx5RGBA
  735. );
  736. TglBitmapFileType = (
  737. {$IFDEF GLB_SUPPORT_PNG_WRITE} ftPNG, {$ENDIF}
  738. {$IFDEF GLB_SUPPORT_JPEG_WRITE}ftJPEG, {$ENDIF}
  739. ftDDS,
  740. ftTGA,
  741. ftBMP,
  742. ftRAW);
  743. TglBitmapFileTypes = set of TglBitmapFileType;
  744. TglBitmapMipMap = (
  745. mmNone,
  746. mmMipmap,
  747. mmMipmapGlu);
  748. TglBitmapNormalMapFunc = (
  749. nm4Samples,
  750. nmSobel,
  751. nm3x3,
  752. nm5x5);
  753. ////////////////////////////////////////////////////////////////////////////////////////////////////
  754. EglBitmap = class(Exception);
  755. EglBitmapNotSupported = class(Exception);
  756. EglBitmapSizeToLarge = class(EglBitmap);
  757. EglBitmapNonPowerOfTwo = class(EglBitmap);
  758. EglBitmapUnsupportedFormat = class(EglBitmap)
  759. public
  760. constructor Create(const aFormat: TglBitmapFormat); overload;
  761. constructor Create(const aMsg: String; const aFormat: TglBitmapFormat); overload;
  762. end;
  763. ////////////////////////////////////////////////////////////////////////////////////////////////////
  764. TglBitmapRec4ui = packed record
  765. case Integer of
  766. 0: (r, g, b, a: Cardinal);
  767. 1: (arr: array[0..3] of Cardinal);
  768. end;
  769. TglBitmapRec4ub = packed record
  770. case Integer of
  771. 0: (r, g, b, a: Byte);
  772. 1: (arr: array[0..3] of Byte);
  773. end;
  774. TglBitmapRec4ul = packed record
  775. case Integer of
  776. 0: (r, g, b, a: QWord);
  777. 1: (arr: array[0..3] of QWord);
  778. end;
  779. TglBitmapFormatDescriptor = class(TObject)
  780. private
  781. // cached properties
  782. fBytesPerPixel: Single;
  783. fChannelCount: Integer;
  784. fMask: TglBitmapRec4ul;
  785. fRange: TglBitmapRec4ui;
  786. function GetHasRed: Boolean;
  787. function GetHasGreen: Boolean;
  788. function GetHasBlue: Boolean;
  789. function GetHasAlpha: Boolean;
  790. function GetHasColor: Boolean;
  791. function GetIsGrayscale: Boolean;
  792. protected
  793. fFormat: TglBitmapFormat;
  794. fWithAlpha: TglBitmapFormat;
  795. fWithoutAlpha: TglBitmapFormat;
  796. fOpenGLFormat: TglBitmapFormat;
  797. fRGBInverted: TglBitmapFormat;
  798. fUncompressed: TglBitmapFormat;
  799. fBitsPerPixel: Integer;
  800. fIsCompressed: Boolean;
  801. fPrecision: TglBitmapRec4ub;
  802. fShift: TglBitmapRec4ub;
  803. fglFormat: GLenum;
  804. fglInternalFormat: GLenum;
  805. fglDataFormat: GLenum;
  806. procedure SetValues; virtual;
  807. procedure CalcValues;
  808. public
  809. property Format: TglBitmapFormat read fFormat;
  810. property ChannelCount: Integer read fChannelCount;
  811. property IsCompressed: Boolean read fIsCompressed;
  812. property BitsPerPixel: Integer read fBitsPerPixel;
  813. property BytesPerPixel: Single read fBytesPerPixel;
  814. property Precision: TglBitmapRec4ub read fPrecision;
  815. property Shift: TglBitmapRec4ub read fShift;
  816. property Range: TglBitmapRec4ui read fRange;
  817. property Mask: TglBitmapRec4ul read fMask;
  818. property RGBInverted: TglBitmapFormat read fRGBInverted;
  819. property WithAlpha: TglBitmapFormat read fWithAlpha;
  820. property WithoutAlpha: TglBitmapFormat read fWithAlpha;
  821. property OpenGLFormat: TglBitmapFormat read fOpenGLFormat;
  822. property Uncompressed: TglBitmapFormat read fUncompressed;
  823. property glFormat: GLenum read fglFormat;
  824. property glInternalFormat: GLenum read fglInternalFormat;
  825. property glDataFormat: GLenum read fglDataFormat;
  826. property HasRed: Boolean read GetHasRed;
  827. property HasGreen: Boolean read GetHasGreen;
  828. property HasBlue: Boolean read GetHasBlue;
  829. property HasAlpha: Boolean read GetHasAlpha;
  830. property HasColor: Boolean read GetHasColor;
  831. property IsGrayscale: Boolean read GetIsGrayscale;
  832. constructor Create;
  833. public
  834. class function GetByFormat(const aInternalFormat: GLenum): TglBitmapFormatDescriptor;
  835. end;
  836. ////////////////////////////////////////////////////////////////////////////////////////////////////
  837. TglBitmapPixelData = packed record
  838. Data: TglBitmapRec4ui;
  839. Range: TglBitmapRec4ui;
  840. Format: TglBitmapFormat;
  841. end;
  842. PglBitmapPixelData = ^TglBitmapPixelData;
  843. TglBitmapPixelPositionFields = set of (ffX, ffY);
  844. TglBitmapPixelPosition = record
  845. Fields : TglBitmapPixelPositionFields;
  846. X : Word;
  847. Y : Word;
  848. end;
  849. ////////////////////////////////////////////////////////////////////////////////////////////////////
  850. TglBitmap = class;
  851. TglBitmapFunctionRec = record
  852. Sender: TglBitmap;
  853. Size: TglBitmapPixelPosition;
  854. Position: TglBitmapPixelPosition;
  855. Source: TglBitmapPixelData;
  856. Dest: TglBitmapPixelData;
  857. Args: Pointer;
  858. end;
  859. TglBitmapFunction = procedure(var FuncRec: TglBitmapFunctionRec);
  860. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  861. TglBitmap = class
  862. private
  863. function GetFormatDesc: TglBitmapFormatDescriptor;
  864. protected
  865. fID: GLuint;
  866. fTarget: GLuint;
  867. fAnisotropic: Integer;
  868. fDeleteTextureOnFree: Boolean;
  869. fFreeDataOnDestroy: Boolean;
  870. fFreeDataAfterGenTexture: Boolean;
  871. fData: PByte;
  872. fIsResident: GLboolean;
  873. fBorderColor: array[0..3] of Single;
  874. fDimension: TglBitmapPixelPosition;
  875. fMipMap: TglBitmapMipMap;
  876. fFormat: TglBitmapFormat;
  877. // Mapping
  878. fPixelSize: Integer;
  879. fRowSize: Integer;
  880. // Filtering
  881. fFilterMin: GLenum;
  882. fFilterMag: GLenum;
  883. // TexturWarp
  884. fWrapS: GLenum;
  885. fWrapT: GLenum;
  886. fWrapR: GLenum;
  887. //Swizzle
  888. fSwizzle: array[0..3] of GLenum;
  889. // CustomData
  890. fFilename: String;
  891. fCustomName: String;
  892. fCustomNameW: WideString;
  893. fCustomData: Pointer;
  894. //Getter
  895. function GetWidth: Integer; virtual;
  896. function GetHeight: Integer; virtual;
  897. function GetFileWidth: Integer; virtual;
  898. function GetFileHeight: Integer; virtual;
  899. //Setter
  900. procedure SetCustomData(const aValue: Pointer);
  901. procedure SetCustomName(const aValue: String);
  902. procedure SetCustomNameW(const aValue: WideString);
  903. procedure SetFreeDataOnDestroy(const aValue: Boolean);
  904. procedure SetDeleteTextureOnFree(const aValue: Boolean);
  905. procedure SetFormat(const aValue: TglBitmapFormat);
  906. procedure SetFreeDataAfterGenTexture(const aValue: Boolean);
  907. procedure SetID(const aValue: Cardinal);
  908. procedure SetMipMap(const aValue: TglBitmapMipMap);
  909. procedure SetTarget(const aValue: Cardinal);
  910. procedure SetAnisotropic(const aValue: Integer);
  911. procedure CreateID;
  912. procedure SetupParameters(out aBuildWithGlu: Boolean);
  913. procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
  914. const aWidth: Integer = -1; const aHeight: Integer = -1); virtual; //be careful, aData could be freed by this method
  915. procedure GenTexture(const aTestTextureSize: Boolean = true); virtual; abstract;
  916. function FlipHorz: Boolean; virtual;
  917. function FlipVert: Boolean; virtual;
  918. property Width: Integer read GetWidth;
  919. property Height: Integer read GetHeight;
  920. property FileWidth: Integer read GetFileWidth;
  921. property FileHeight: Integer read GetFileHeight;
  922. public
  923. //Properties
  924. property ID: Cardinal read fID write SetID;
  925. property Target: Cardinal read fTarget write SetTarget;
  926. property Format: TglBitmapFormat read fFormat write SetFormat;
  927. property MipMap: TglBitmapMipMap read fMipMap write SetMipMap;
  928. property Anisotropic: Integer read fAnisotropic write SetAnisotropic;
  929. property FormatDesc: TglBitmapFormatDescriptor read GetFormatDesc;
  930. property Filename: String read fFilename;
  931. property CustomName: String read fCustomName write SetCustomName;
  932. property CustomNameW: WideString read fCustomNameW write SetCustomNameW;
  933. property CustomData: Pointer read fCustomData write SetCustomData;
  934. property DeleteTextureOnFree: Boolean read fDeleteTextureOnFree write SetDeleteTextureOnFree;
  935. property FreeDataOnDestroy: Boolean read fFreeDataOnDestroy write SetFreeDataOnDestroy;
  936. property FreeDataAfterGenTexture: Boolean read fFreeDataAfterGenTexture write SetFreeDataAfterGenTexture;
  937. property Dimension: TglBitmapPixelPosition read fDimension;
  938. property Data: PByte read fData;
  939. property IsResident: GLboolean read fIsResident;
  940. procedure AfterConstruction; override;
  941. procedure BeforeDestruction; override;
  942. procedure PrepareResType(var aResource: String; var aResType: PChar);
  943. //Load
  944. procedure LoadFromFile(const aFilename: String);
  945. procedure LoadFromStream(const aStream: TStream); virtual;
  946. procedure LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
  947. const aFormat: TglBitmapFormat; const aArgs: Pointer = nil);
  948. procedure LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil);
  949. procedure LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
  950. //Save
  951. procedure SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
  952. procedure SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType); virtual;
  953. //Convert
  954. function AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer = nil): Boolean; overload;
  955. function AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
  956. const aFormat: TglBitmapFormat; const aArgs: Pointer = nil): Boolean; overload;
  957. public
  958. //Alpha & Co
  959. {$IFDEF GLB_SDL}
  960. function AssignToSurface(out aSurface: PSDL_Surface): Boolean;
  961. function AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
  962. function AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
  963. function AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil;
  964. const aArgs: Pointer = nil): Boolean;
  965. {$ENDIF}
  966. {$IFDEF GLB_DELPHI}
  967. function AssignToBitmap(const aBitmap: TBitmap): Boolean;
  968. function AssignFromBitmap(const aBitmap: TBitmap): Boolean;
  969. function AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
  970. function AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction = nil;
  971. const aArgs: Pointer = nil): Boolean;
  972. {$ENDIF}
  973. {$IFDEF GLB_LAZARUS}
  974. function AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
  975. function AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
  976. function AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
  977. function AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction = nil;
  978. const aArgs: Pointer = nil): Boolean;
  979. {$ENDIF}
  980. function AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil;
  981. const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  982. function AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
  983. const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  984. function AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer = nil): Boolean; virtual;
  985. function AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  986. function AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  987. function AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  988. function AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte = 0): Boolean;
  989. function AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal = 0): Boolean;
  990. function AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single = 0): Boolean;
  991. function AddAlphaFromValue(const aAlpha: Byte): Boolean;
  992. function AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
  993. function AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
  994. function RemoveAlpha: Boolean; virtual;
  995. public
  996. //Common
  997. function Clone: TglBitmap;
  998. function ConvertTo(const aFormat: TglBitmapFormat): Boolean; virtual;
  999. procedure Invert(const aUseRGB: Boolean = true; const aUseAlpha: Boolean = false);
  1000. procedure SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
  1001. procedure FreeData;
  1002. //ColorFill
  1003. procedure FillWithColor(const aRed, aGreen, aBlue: Byte; const aAlpha: Byte = 255);
  1004. procedure FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal = $FFFFFFFF);
  1005. procedure FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha : Single = 1);
  1006. //TexParameters
  1007. procedure SetFilter(const aMin, aMag: GLenum);
  1008. procedure SetWrap(
  1009. const S: GLenum = GL_CLAMP_TO_EDGE;
  1010. const T: GLenum = GL_CLAMP_TO_EDGE;
  1011. const R: GLenum = GL_CLAMP_TO_EDGE);
  1012. procedure SetSwizzle(const r, g, b, a: GLenum);
  1013. procedure Bind(const aEnableTextureUnit: Boolean = true); virtual;
  1014. procedure Unbind(const aDisableTextureUnit: Boolean = true); virtual;
  1015. //Constructors
  1016. constructor Create; overload;
  1017. constructor Create(const aFileName: String); overload;
  1018. constructor Create(const aStream: TStream); overload;
  1019. constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; aData: PByte = nil); overload;
  1020. constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer = nil); overload;
  1021. constructor Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil); overload;
  1022. constructor Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar); overload;
  1023. private
  1024. {$IFDEF GLB_SUPPORT_PNG_READ} function LoadPNG(const aStream: TStream): Boolean; virtual; {$ENDIF}
  1025. {$ifdef GLB_SUPPORT_PNG_WRITE} procedure SavePNG(const aStream: TStream); virtual; {$ENDIF}
  1026. {$IFDEF GLB_SUPPORT_JPEG_READ} function LoadJPEG(const aStream: TStream): Boolean; virtual; {$ENDIF}
  1027. {$IFDEF GLB_SUPPORT_JPEG_WRITE} procedure SaveJPEG(const aStream: TStream); virtual; {$ENDIF}
  1028. function LoadRAW(const aStream: TStream): Boolean;
  1029. procedure SaveRAW(const aStream: TStream);
  1030. function LoadBMP(const aStream: TStream): Boolean;
  1031. procedure SaveBMP(const aStream: TStream);
  1032. function LoadTGA(const aStream: TStream): Boolean;
  1033. procedure SaveTGA(const aStream: TStream);
  1034. function LoadDDS(const aStream: TStream): Boolean;
  1035. procedure SaveDDS(const aStream: TStream);
  1036. end;
  1037. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1038. TglBitmap1D = class(TglBitmap)
  1039. protected
  1040. procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
  1041. const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
  1042. procedure UploadData(const aBuildWithGlu: Boolean);
  1043. public
  1044. property Width;
  1045. procedure AfterConstruction; override;
  1046. function FlipHorz: Boolean; override;
  1047. procedure GenTexture(const aTestTextureSize: Boolean = true); override;
  1048. end;
  1049. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1050. TglBitmap2D = class(TglBitmap)
  1051. protected
  1052. fLines: array of PByte;
  1053. function GetScanline(const aIndex: Integer): Pointer;
  1054. procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
  1055. const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
  1056. procedure UploadData(const aTarget: GLenum; const aBuildWithGlu: Boolean);
  1057. public
  1058. property Width;
  1059. property Height;
  1060. property Scanline[const aIndex: Integer]: Pointer read GetScanline;
  1061. procedure AfterConstruction; override;
  1062. procedure GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
  1063. procedure GetDataFromTexture;
  1064. procedure GenTexture(const aTestTextureSize: Boolean = true); override;
  1065. function FlipHorz: Boolean; override;
  1066. function FlipVert: Boolean; override;
  1067. procedure ToNormalMap(const aFunc: TglBitmapNormalMapFunc = nm3x3;
  1068. const aScale: Single = 2; const aUseAlpha: Boolean = false);
  1069. end;
  1070. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1071. TglBitmapCubeMap = class(TglBitmap2D)
  1072. protected
  1073. fGenMode: Integer;
  1074. procedure GenTexture(const aTestTextureSize: Boolean = true); reintroduce;
  1075. public
  1076. procedure AfterConstruction; override;
  1077. procedure GenerateCubeMap(const aCubeTarget: Cardinal; const aTestTextureSize: Boolean = true);
  1078. procedure Bind(const aEnableTexCoordsGen: Boolean = true; const aEnableTextureUnit: Boolean = true); reintroduce; virtual;
  1079. procedure Unbind(const aDisableTexCoordsGen: Boolean = true; const aDisableTextureUnit: Boolean = true); reintroduce; virtual;
  1080. end;
  1081. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1082. TglBitmapNormalMap = class(TglBitmapCubeMap)
  1083. public
  1084. procedure AfterConstruction; override;
  1085. procedure GenerateNormalMap(const aSize: Integer = 32; const aTestTextureSize: Boolean = true);
  1086. end;
  1087. const
  1088. NULL_SIZE: TglBitmapPixelPosition = (Fields: []; X: 0; Y: 0);
  1089. procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
  1090. procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
  1091. procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
  1092. procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
  1093. procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
  1094. procedure glBitmapSetDefaultWrap(
  1095. const S: Cardinal = GL_CLAMP_TO_EDGE;
  1096. const T: Cardinal = GL_CLAMP_TO_EDGE;
  1097. const R: Cardinal = GL_CLAMP_TO_EDGE);
  1098. function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
  1099. function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
  1100. function glBitmapGetDefaultMipmap: TglBitmapMipMap;
  1101. function glBitmapGetDefaultFormat: TglBitmapFormat;
  1102. procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
  1103. procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
  1104. function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
  1105. function glBitmapRec4ub(const r, g, b, a: Byte): TglBitmapRec4ub;
  1106. function glBitmapRec4ui(const r, g, b, a: Cardinal): TglBitmapRec4ui;
  1107. function glBitmapRec4ul(const r, g, b, a: QWord): TglBitmapRec4ul;
  1108. function glBitmapRec4ubCompare(const r1, r2: TglBitmapRec4ub): Boolean;
  1109. function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean;
  1110. function glBitmapCreateTestTexture(const aFormat: TglBitmapFormat): TglBitmap2D;
  1111. var
  1112. glBitmapDefaultDeleteTextureOnFree: Boolean;
  1113. glBitmapDefaultFreeDataAfterGenTextures: Boolean;
  1114. glBitmapDefaultFormat: TglBitmapFormat;
  1115. glBitmapDefaultMipmap: TglBitmapMipMap;
  1116. glBitmapDefaultFilterMin: Cardinal;
  1117. glBitmapDefaultFilterMag: Cardinal;
  1118. glBitmapDefaultWrapS: Cardinal;
  1119. glBitmapDefaultWrapT: Cardinal;
  1120. glBitmapDefaultWrapR: Cardinal;
  1121. glDefaultSwizzle: array[0..3] of GLenum;
  1122. {$IFDEF GLB_DELPHI}
  1123. function CreateGrayPalette: HPALETTE;
  1124. {$ENDIF}
  1125. implementation
  1126. uses
  1127. Math, syncobjs, typinfo
  1128. {$IF DEFINED(GLB_SUPPORT_JPEG_READ) AND DEFINED(GLB_LAZ_JPEG)}, FPReadJPEG{$IFEND};
  1129. ////////////////////////////////////////////////////////////////////////////////////////////////////
  1130. type
  1131. TFormatDescriptor = class(TglBitmapFormatDescriptor)
  1132. public
  1133. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); virtual; abstract;
  1134. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract;
  1135. function GetSize(const aSize: TglBitmapPixelPosition): Integer; overload; virtual;
  1136. function GetSize(const aWidth, aHeight: Integer): Integer; overload; virtual;
  1137. function CreateMappingData: Pointer; virtual;
  1138. procedure FreeMappingData(var aMappingData: Pointer); virtual;
  1139. function IsEmpty: Boolean; virtual;
  1140. function MaskMatch(const aMask: TglBitmapRec4ul): Boolean; virtual;
  1141. procedure PreparePixel(out aPixel: TglBitmapPixelData); virtual;
  1142. constructor Create; virtual;
  1143. public
  1144. class procedure Init;
  1145. class function Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
  1146. class function GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
  1147. class function GetFromMask(const aMask: TglBitmapRec4ul; const aBitCount: Integer = 0): TFormatDescriptor;
  1148. class function GetFromPrecShift(const aPrec, aShift: TglBitmapRec4ub; const aBitCount: Integer): TFormatDescriptor;
  1149. class procedure Clear;
  1150. class procedure Finalize;
  1151. end;
  1152. TFormatDescriptorClass = class of TFormatDescriptor;
  1153. TfdEmpty = class(TFormatDescriptor);
  1154. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1155. TfdAlphaUB1 = class(TFormatDescriptor) //1* unsigned byte
  1156. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1157. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1158. end;
  1159. TfdLuminanceUB1 = class(TFormatDescriptor) //1* unsigned byte
  1160. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1161. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1162. end;
  1163. TfdUniversalUB1 = class(TFormatDescriptor) //1* unsigned byte
  1164. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1165. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1166. end;
  1167. TfdLuminanceAlphaUB2 = class(TfdLuminanceUB1) //2* unsigned byte
  1168. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1169. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1170. end;
  1171. TfdRGBub3 = class(TFormatDescriptor) //3* unsigned byte
  1172. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1173. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1174. end;
  1175. TfdBGRub3 = class(TFormatDescriptor) //3* unsigned byte (inverse)
  1176. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1177. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1178. end;
  1179. TfdRGBAub4 = class(TfdRGBub3) //3* unsigned byte
  1180. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1181. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1182. end;
  1183. TfdBGRAub4 = class(TfdBGRub3) //3* unsigned byte (inverse)
  1184. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1185. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1186. end;
  1187. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1188. TfdAlphaUS1 = class(TFormatDescriptor) //1* unsigned short
  1189. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1190. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1191. end;
  1192. TfdLuminanceUS1 = class(TFormatDescriptor) //1* unsigned short
  1193. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1194. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1195. end;
  1196. TfdUniversalUS1 = class(TFormatDescriptor) //1* unsigned short
  1197. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1198. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1199. end;
  1200. TfdDepthUS1 = class(TFormatDescriptor) //1* unsigned short
  1201. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1202. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1203. end;
  1204. TfdLuminanceAlphaUS2 = class(TfdLuminanceUS1) //2* unsigned short
  1205. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1206. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1207. end;
  1208. TfdRGBus3 = class(TFormatDescriptor) //3* unsigned short
  1209. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1210. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1211. end;
  1212. TfdBGRus3 = class(TFormatDescriptor) //3* unsigned short (inverse)
  1213. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1214. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1215. end;
  1216. TfdRGBAus4 = class(TfdRGBus3) //4* unsigned short
  1217. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1218. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1219. end;
  1220. TfdARGBus4 = class(TfdRGBus3) //4* unsigned short
  1221. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1222. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1223. end;
  1224. TfdBGRAus4 = class(TfdBGRus3) //4* unsigned short (inverse)
  1225. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1226. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1227. end;
  1228. TfdABGRus4 = class(TfdBGRus3) //4* unsigned short (inverse)
  1229. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1230. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1231. end;
  1232. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1233. TfdUniversalUI1 = class(TFormatDescriptor) //1* unsigned int
  1234. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1235. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1236. end;
  1237. TfdDepthUI1 = class(TFormatDescriptor) //1* unsigned int
  1238. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1239. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1240. end;
  1241. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1242. TfdAlpha4ub1 = class(TfdAlphaUB1)
  1243. procedure SetValues; override;
  1244. end;
  1245. TfdAlpha8ub1 = class(TfdAlphaUB1)
  1246. procedure SetValues; override;
  1247. end;
  1248. TfdAlpha16us1 = class(TfdAlphaUS1)
  1249. procedure SetValues; override;
  1250. end;
  1251. TfdLuminance4ub1 = class(TfdLuminanceUB1)
  1252. procedure SetValues; override;
  1253. end;
  1254. TfdLuminance8ub1 = class(TfdLuminanceUB1)
  1255. procedure SetValues; override;
  1256. end;
  1257. TfdLuminance16us1 = class(TfdLuminanceUS1)
  1258. procedure SetValues; override;
  1259. end;
  1260. TfdLuminance4Alpha4ub2 = class(TfdLuminanceAlphaUB2)
  1261. procedure SetValues; override;
  1262. end;
  1263. TfdLuminance6Alpha2ub2 = class(TfdLuminanceAlphaUB2)
  1264. procedure SetValues; override;
  1265. end;
  1266. TfdLuminance8Alpha8ub2 = class(TfdLuminanceAlphaUB2)
  1267. procedure SetValues; override;
  1268. end;
  1269. TfdLuminance12Alpha4us2 = class(TfdLuminanceAlphaUS2)
  1270. procedure SetValues; override;
  1271. end;
  1272. TfdLuminance16Alpha16us2 = class(TfdLuminanceAlphaUS2)
  1273. procedure SetValues; override;
  1274. end;
  1275. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1276. TfdR3G3B2ub1 = class(TfdUniversalUB1)
  1277. procedure SetValues; override;
  1278. end;
  1279. TfdRGBX4us1 = class(TfdUniversalUS1)
  1280. procedure SetValues; override;
  1281. end;
  1282. TfdXRGB4us1 = class(TfdUniversalUS1)
  1283. procedure SetValues; override;
  1284. end;
  1285. TfdR5G6B5us1 = class(TfdUniversalUS1)
  1286. procedure SetValues; override;
  1287. end;
  1288. TfdRGB5X1us1 = class(TfdUniversalUS1)
  1289. procedure SetValues; override;
  1290. end;
  1291. TfdX1RGB5us1 = class(TfdUniversalUS1)
  1292. procedure SetValues; override;
  1293. end;
  1294. TfdRGB8ub3 = class(TfdRGBub3)
  1295. procedure SetValues; override;
  1296. end;
  1297. TfdRGBX8ui1 = class(TfdUniversalUI1)
  1298. procedure SetValues; override;
  1299. end;
  1300. TfdXRGB8ui1 = class(TfdUniversalUI1)
  1301. procedure SetValues; override;
  1302. end;
  1303. TfdRGB10X2ui1 = class(TfdUniversalUI1)
  1304. procedure SetValues; override;
  1305. end;
  1306. TfdX2RGB10ui1 = class(TfdUniversalUI1)
  1307. procedure SetValues; override;
  1308. end;
  1309. TfdRGB16us3 = class(TfdRGBus3)
  1310. procedure SetValues; override;
  1311. end;
  1312. TfdRGBA4us1 = class(TfdUniversalUS1)
  1313. procedure SetValues; override;
  1314. end;
  1315. TfdARGB4us1 = class(TfdUniversalUS1)
  1316. procedure SetValues; override;
  1317. end;
  1318. TfdRGB5A1us1 = class(TfdUniversalUS1)
  1319. procedure SetValues; override;
  1320. end;
  1321. TfdA1RGB5us1 = class(TfdUniversalUS1)
  1322. procedure SetValues; override;
  1323. end;
  1324. TfdRGBA8ui1 = class(TfdUniversalUI1)
  1325. procedure SetValues; override;
  1326. end;
  1327. TfdARGB8ui1 = class(TfdUniversalUI1)
  1328. procedure SetValues; override;
  1329. end;
  1330. TfdRGBA8ub4 = class(TfdRGBAub4)
  1331. procedure SetValues; override;
  1332. end;
  1333. TfdRGB10A2ui1 = class(TfdUniversalUI1)
  1334. procedure SetValues; override;
  1335. end;
  1336. TfdA2RGB10ui1 = class(TfdUniversalUI1)
  1337. procedure SetValues; override;
  1338. end;
  1339. TfdRGBA16us4 = class(TfdRGBAus4)
  1340. procedure SetValues; override;
  1341. end;
  1342. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1343. TfdBGRX4us1 = class(TfdUniversalUS1)
  1344. procedure SetValues; override;
  1345. end;
  1346. TfdXBGR4us1 = class(TfdUniversalUS1)
  1347. procedure SetValues; override;
  1348. end;
  1349. TfdB5G6R5us1 = class(TfdUniversalUS1)
  1350. procedure SetValues; override;
  1351. end;
  1352. TfdBGR5X1us1 = class(TfdUniversalUS1)
  1353. procedure SetValues; override;
  1354. end;
  1355. TfdX1BGR5us1 = class(TfdUniversalUS1)
  1356. procedure SetValues; override;
  1357. end;
  1358. TfdBGR8ub3 = class(TfdBGRub3)
  1359. procedure SetValues; override;
  1360. end;
  1361. TfdBGRX8ui1 = class(TfdUniversalUI1)
  1362. procedure SetValues; override;
  1363. end;
  1364. TfdXBGR8ui1 = class(TfdUniversalUI1)
  1365. procedure SetValues; override;
  1366. end;
  1367. TfdBGR10X2ui1 = class(TfdUniversalUI1)
  1368. procedure SetValues; override;
  1369. end;
  1370. TfdX2BGR10ui1 = class(TfdUniversalUI1)
  1371. procedure SetValues; override;
  1372. end;
  1373. TfdBGR16us3 = class(TfdBGRus3)
  1374. procedure SetValues; override;
  1375. end;
  1376. TfdBGRA4us1 = class(TfdUniversalUS1)
  1377. procedure SetValues; override;
  1378. end;
  1379. TfdABGR4us1 = class(TfdUniversalUS1)
  1380. procedure SetValues; override;
  1381. end;
  1382. TfdBGR5A1us1 = class(TfdUniversalUS1)
  1383. procedure SetValues; override;
  1384. end;
  1385. TfdA1BGR5us1 = class(TfdUniversalUS1)
  1386. procedure SetValues; override;
  1387. end;
  1388. TfdBGRA8ui1 = class(TfdUniversalUI1)
  1389. procedure SetValues; override;
  1390. end;
  1391. TfdABGR8ui1 = class(TfdUniversalUI1)
  1392. procedure SetValues; override;
  1393. end;
  1394. TfdBGRA8ub4 = class(TfdBGRAub4)
  1395. procedure SetValues; override;
  1396. end;
  1397. TfdBGR10A2ui1 = class(TfdUniversalUI1)
  1398. procedure SetValues; override;
  1399. end;
  1400. TfdA2BGR10ui1 = class(TfdUniversalUI1)
  1401. procedure SetValues; override;
  1402. end;
  1403. TfdBGRA16us4 = class(TfdBGRAus4)
  1404. procedure SetValues; override;
  1405. end;
  1406. TfdDepth16us1 = class(TfdDepthUS1)
  1407. procedure SetValues; override;
  1408. end;
  1409. TfdDepth24ui1 = class(TfdDepthUI1)
  1410. procedure SetValues; override;
  1411. end;
  1412. TfdDepth32ui1 = class(TfdDepthUI1)
  1413. procedure SetValues; override;
  1414. end;
  1415. TfdS3tcDtx1RGBA = class(TFormatDescriptor)
  1416. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1417. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1418. procedure SetValues; override;
  1419. end;
  1420. TfdS3tcDtx3RGBA = class(TFormatDescriptor)
  1421. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1422. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1423. procedure SetValues; override;
  1424. end;
  1425. TfdS3tcDtx5RGBA = class(TFormatDescriptor)
  1426. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1427. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1428. procedure SetValues; override;
  1429. end;
  1430. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1431. TbmpBitfieldFormat = class(TFormatDescriptor)
  1432. public
  1433. procedure SetCustomValues(const aBPP: Integer; aMask: TglBitmapRec4ul); overload;
  1434. procedure SetCustomValues(const aBBP: Integer; const aPrec, aShift: TglBitmapRec4ub); overload;
  1435. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1436. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1437. end;
  1438. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1439. TbmpColorTableEnty = packed record
  1440. b, g, r, a: Byte;
  1441. end;
  1442. TbmpColorTable = array of TbmpColorTableEnty;
  1443. TbmpColorTableFormat = class(TFormatDescriptor)
  1444. private
  1445. fBitsPerPixel: Integer;
  1446. fColorTable: TbmpColorTable;
  1447. protected
  1448. procedure SetValues; override;
  1449. public
  1450. property ColorTable: TbmpColorTable read fColorTable write fColorTable;
  1451. property BitsPerPixel: Integer read fBitsPerPixel write fBitsPerPixel;
  1452. procedure SetCustomValues(const aFormat: TglBitmapFormat; const aBPP: Integer; const aPrec, aShift: TglBitmapRec4ub); overload;
  1453. procedure CalcValues;
  1454. procedure CreateColorTable;
  1455. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1456. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1457. destructor Destroy; override;
  1458. end;
  1459. const
  1460. LUMINANCE_WEIGHT_R = 0.30;
  1461. LUMINANCE_WEIGHT_G = 0.59;
  1462. LUMINANCE_WEIGHT_B = 0.11;
  1463. ALPHA_WEIGHT_R = 0.30;
  1464. ALPHA_WEIGHT_G = 0.59;
  1465. ALPHA_WEIGHT_B = 0.11;
  1466. DEPTH_WEIGHT_R = 0.333333333;
  1467. DEPTH_WEIGHT_G = 0.333333333;
  1468. DEPTH_WEIGHT_B = 0.333333333;
  1469. FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
  1470. TfdEmpty,
  1471. TfdAlpha4ub1,
  1472. TfdAlpha8ub1,
  1473. TfdAlpha16us1,
  1474. TfdLuminance4ub1,
  1475. TfdLuminance8ub1,
  1476. TfdLuminance16us1,
  1477. TfdLuminance4Alpha4ub2,
  1478. TfdLuminance6Alpha2ub2,
  1479. TfdLuminance8Alpha8ub2,
  1480. TfdLuminance12Alpha4us2,
  1481. TfdLuminance16Alpha16us2,
  1482. TfdR3G3B2ub1,
  1483. TfdRGBX4us1,
  1484. TfdXRGB4us1,
  1485. TfdR5G6B5us1,
  1486. TfdRGB5X1us1,
  1487. TfdX1RGB5us1,
  1488. TfdRGB8ub3,
  1489. TfdRGBX8ui1,
  1490. TfdXRGB8ui1,
  1491. TfdRGB10X2ui1,
  1492. TfdX2RGB10ui1,
  1493. TfdRGB16us3,
  1494. TfdRGBA4us1,
  1495. TfdARGB4us1,
  1496. TfdRGB5A1us1,
  1497. TfdA1RGB5us1,
  1498. TfdRGBA8ui1,
  1499. TfdARGB8ui1,
  1500. TfdRGBA8ub4,
  1501. TfdRGB10A2ui1,
  1502. TfdA2RGB10ui1,
  1503. TfdRGBA16us4,
  1504. TfdBGRX4us1,
  1505. TfdXBGR4us1,
  1506. TfdB5G6R5us1,
  1507. TfdBGR5X1us1,
  1508. TfdX1BGR5us1,
  1509. TfdBGR8ub3,
  1510. TfdBGRX8ui1,
  1511. TfdXBGR8ui1,
  1512. TfdBGR10X2ui1,
  1513. TfdX2BGR10ui1,
  1514. TfdBGR16us3,
  1515. TfdBGRA4us1,
  1516. TfdABGR4us1,
  1517. TfdBGR5A1us1,
  1518. TfdA1BGR5us1,
  1519. TfdBGRA8ui1,
  1520. TfdABGR8ui1,
  1521. TfdBGRA8ub4,
  1522. TfdBGR10A2ui1,
  1523. TfdA2BGR10ui1,
  1524. TfdBGRA16us4,
  1525. TfdDepth16us1,
  1526. TfdDepth24ui1,
  1527. TfdDepth32ui1,
  1528. TfdS3tcDtx1RGBA,
  1529. TfdS3tcDtx3RGBA,
  1530. TfdS3tcDtx5RGBA
  1531. );
  1532. var
  1533. FormatDescriptorCS: TCriticalSection;
  1534. FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
  1535. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1536. constructor EglBitmapUnsupportedFormat.Create(const aFormat: TglBitmapFormat);
  1537. begin
  1538. inherited Create('unsupported format: ' + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
  1539. end;
  1540. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1541. constructor EglBitmapUnsupportedFormat.Create(const aMsg: String; const aFormat: TglBitmapFormat);
  1542. begin
  1543. inherited Create(aMsg + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
  1544. end;
  1545. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1546. function glBitmapPosition(X: Integer; Y: Integer): TglBitmapPixelPosition;
  1547. begin
  1548. result.Fields := [];
  1549. if X >= 0 then
  1550. result.Fields := result.Fields + [ffX];
  1551. if Y >= 0 then
  1552. result.Fields := result.Fields + [ffY];
  1553. result.X := Max(0, X);
  1554. result.Y := Max(0, Y);
  1555. end;
  1556. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1557. function glBitmapRec4ub(const r, g, b, a: Byte): TglBitmapRec4ub;
  1558. begin
  1559. result.r := r;
  1560. result.g := g;
  1561. result.b := b;
  1562. result.a := a;
  1563. end;
  1564. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1565. function glBitmapRec4ui(const r, g, b, a: Cardinal): TglBitmapRec4ui;
  1566. begin
  1567. result.r := r;
  1568. result.g := g;
  1569. result.b := b;
  1570. result.a := a;
  1571. end;
  1572. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1573. function glBitmapRec4ul(const r, g, b, a: QWord): TglBitmapRec4ul;
  1574. begin
  1575. result.r := r;
  1576. result.g := g;
  1577. result.b := b;
  1578. result.a := a;
  1579. end;
  1580. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1581. function glBitmapRec4ubCompare(const r1, r2: TglBitmapRec4ub): Boolean;
  1582. var
  1583. i: Integer;
  1584. begin
  1585. result := false;
  1586. for i := 0 to high(r1.arr) do
  1587. if (r1.arr[i] <> r2.arr[i]) then
  1588. exit;
  1589. result := true;
  1590. end;
  1591. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1592. function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean;
  1593. var
  1594. i: Integer;
  1595. begin
  1596. result := false;
  1597. for i := 0 to high(r1.arr) do
  1598. if (r1.arr[i] <> r2.arr[i]) then
  1599. exit;
  1600. result := true;
  1601. end;
  1602. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1603. function glBitmapCreateTestTexture(const aFormat: TglBitmapFormat): TglBitmap2D;
  1604. var
  1605. desc: TFormatDescriptor;
  1606. p, tmp: PByte;
  1607. x, y, i: Integer;
  1608. md: Pointer;
  1609. px: TglBitmapPixelData;
  1610. begin
  1611. result := nil;
  1612. desc := TFormatDescriptor.Get(aFormat);
  1613. if (desc.IsCompressed) or (desc.glFormat = 0) then
  1614. exit;
  1615. p := GetMemory(ceil(25 * desc.BytesPerPixel)); // 5 x 5 pixel
  1616. md := desc.CreateMappingData;
  1617. try
  1618. tmp := p;
  1619. desc.PreparePixel(px);
  1620. for y := 0 to 4 do
  1621. for x := 0 to 4 do begin
  1622. px.Data := glBitmapRec4ui(0, 0, 0, 0);
  1623. for i := 0 to 3 do begin
  1624. if ((y < 3) and (y = i)) or
  1625. ((y = 3) and (i < 3)) or
  1626. ((y = 4) and (i = 3))
  1627. then
  1628. px.Data.arr[i] := Trunc(px.Range.arr[i] / 4 * x)
  1629. else if ((y < 4) and (i = 3)) or
  1630. ((y = 4) and (i < 3))
  1631. then
  1632. px.Data.arr[i] := px.Range.arr[i]
  1633. else
  1634. px.Data.arr[i] := 0; //px.Range.arr[i];
  1635. end;
  1636. desc.Map(px, tmp, md);
  1637. end;
  1638. finally
  1639. desc.FreeMappingData(md);
  1640. end;
  1641. result := TglBitmap2D.Create(glBitmapPosition(5, 5), aFormat, p);
  1642. result.FreeDataOnDestroy := true;
  1643. result.FreeDataAfterGenTexture := false;
  1644. result.SetFilter(GL_NEAREST, GL_NEAREST);
  1645. end;
  1646. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1647. function glBitmapShiftRec(const r, g, b, a: Byte): TglBitmapRec4ub;
  1648. begin
  1649. result.r := r;
  1650. result.g := g;
  1651. result.b := b;
  1652. result.a := a;
  1653. end;
  1654. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1655. function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
  1656. begin
  1657. result := [];
  1658. if (aFormat in [
  1659. //8bpp
  1660. tfAlpha4ub1, tfAlpha8ub1,
  1661. tfLuminance4ub1, tfLuminance8ub1, tfR3G3B2ub1,
  1662. //16bpp
  1663. tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
  1664. tfRGBX4us1, tfXRGB4us1, tfRGB5X1us1, tfX1RGB5us1, tfR5G6B5us1, tfRGB5A1us1, tfA1RGB5us1, tfRGBA4us1, tfARGB4us1,
  1665. tfBGRX4us1, tfXBGR4us1, tfBGR5X1us1, tfX1BGR5us1, tfB5G6R5us1, tfBGR5A1us1, tfA1BGR5us1, tfBGRA4us1, tfABGR4us1,
  1666. //24bpp
  1667. tfBGR8ub3, tfRGB8ub3,
  1668. //32bpp
  1669. tfRGBX8ui1, tfXRGB8ui1, tfRGB10X2ui1, tfX2RGB10ui1, tfRGBA8ui1, tfARGB8ui1, tfRGBA8ub4, tfRGB10A2ui1, tfA2RGB10ui1,
  1670. tfBGRX8ui1, tfXBGR8ui1, tfBGR10X2ui1, tfX2BGR10ui1, tfBGRA8ui1, tfABGR8ui1, tfBGRA8ub4, tfBGR10A2ui1, tfA2BGR10ui1])
  1671. then
  1672. result := result + [ ftBMP ];
  1673. if (aFormat in [
  1674. //8bbp
  1675. tfAlpha4ub1, tfAlpha8ub1, tfLuminance4ub1, tfLuminance8ub1,
  1676. //16bbp
  1677. tfAlpha16us1, tfLuminance16us1,
  1678. tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
  1679. tfX1RGB5us1, tfARGB4us1, tfA1RGB5us1, tfDepth16us1,
  1680. //24bbp
  1681. tfBGR8ub3,
  1682. //32bbp
  1683. tfX2RGB10ui1, tfARGB8ui1, tfBGRA8ub4, tfA2RGB10ui1,
  1684. tfDepth24ui1, tfDepth32ui1])
  1685. then
  1686. result := result + [ftTGA];
  1687. if not (aFormat in [tfEmpty, tfRGB16us3, tfBGR16us3]) then
  1688. result := result + [ftDDS];
  1689. {$IFDEF GLB_SUPPORT_PNG_WRITE}
  1690. if aFormat in [
  1691. tfAlpha8ub1, tfLuminance8ub1, tfLuminance8Alpha8ub2,
  1692. tfRGB8ub3, tfRGBA8ui1,
  1693. tfBGR8ub3, tfBGRA8ui1] then
  1694. result := result + [ftPNG];
  1695. {$ENDIF}
  1696. {$IFDEF GLB_SUPPORT_JPEG_WRITE}
  1697. if aFormat in [tfAlpha8ub1, tfLuminance8ub1, tfRGB8ub3, tfBGR8ub3] then
  1698. result := result + [ftJPEG];
  1699. {$ENDIF}
  1700. end;
  1701. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1702. function IsPowerOfTwo(aNumber: Integer): Boolean;
  1703. begin
  1704. while (aNumber and 1) = 0 do
  1705. aNumber := aNumber shr 1;
  1706. result := aNumber = 1;
  1707. end;
  1708. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1709. function GetTopMostBit(aBitSet: QWord): Integer;
  1710. begin
  1711. result := 0;
  1712. while aBitSet > 0 do begin
  1713. inc(result);
  1714. aBitSet := aBitSet shr 1;
  1715. end;
  1716. end;
  1717. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1718. function CountSetBits(aBitSet: QWord): Integer;
  1719. begin
  1720. result := 0;
  1721. while aBitSet > 0 do begin
  1722. if (aBitSet and 1) = 1 then
  1723. inc(result);
  1724. aBitSet := aBitSet shr 1;
  1725. end;
  1726. end;
  1727. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1728. function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
  1729. begin
  1730. result := Trunc(
  1731. LUMINANCE_WEIGHT_R * aPixel.Data.r +
  1732. LUMINANCE_WEIGHT_G * aPixel.Data.g +
  1733. LUMINANCE_WEIGHT_B * aPixel.Data.b);
  1734. end;
  1735. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1736. function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
  1737. begin
  1738. result := Trunc(
  1739. DEPTH_WEIGHT_R * aPixel.Data.r +
  1740. DEPTH_WEIGHT_G * aPixel.Data.g +
  1741. DEPTH_WEIGHT_B * aPixel.Data.b);
  1742. end;
  1743. {$IFDEF GLB_NATIVE_OGL}
  1744. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1745. //OpenGLInitialization///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1746. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1747. var
  1748. GL_LibHandle: Pointer = nil;
  1749. function glbGetProcAddress(aProcName: PAnsiChar; aLibHandle: Pointer = nil; const aRaiseOnErr: Boolean = true): Pointer;
  1750. begin
  1751. if not Assigned(aLibHandle) then
  1752. aLibHandle := GL_LibHandle;
  1753. {$IF DEFINED(GLB_WIN)}
  1754. result := GetProcAddress({%H-}HMODULE(aLibHandle), aProcName);
  1755. if Assigned(result) then
  1756. exit;
  1757. if Assigned(wglGetProcAddress) then
  1758. result := wglGetProcAddress(aProcName);
  1759. {$ELSEIF DEFINED(GLB_LINUX)}
  1760. if Assigned(glXGetProcAddress) then begin
  1761. result := glXGetProcAddress(aProcName);
  1762. if Assigned(result) then
  1763. exit;
  1764. end;
  1765. if Assigned(glXGetProcAddressARB) then begin
  1766. result := glXGetProcAddressARB(aProcName);
  1767. if Assigned(result) then
  1768. exit;
  1769. end;
  1770. result := dlsym(aLibHandle, aProcName);
  1771. {$IFEND}
  1772. if not Assigned(result) and aRaiseOnErr then
  1773. raise EglBitmap.Create('unable to load procedure form library: ' + aProcName);
  1774. end;
  1775. {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
  1776. var
  1777. GLU_LibHandle: Pointer = nil;
  1778. OpenGLInitialized: Boolean;
  1779. InitOpenGLCS: TCriticalSection;
  1780. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1781. procedure glbInitOpenGL;
  1782. ////////////////////////////////////////////////////////////////////////////////
  1783. function glbLoadLibrary(const aName: PChar): Pointer;
  1784. begin
  1785. {$IF DEFINED(GLB_WIN)}
  1786. result := {%H-}Pointer(LoadLibrary(aName));
  1787. {$ELSEIF DEFINED(GLB_LINUX)}
  1788. result := dlopen(Name, RTLD_LAZY);
  1789. {$ELSE}
  1790. result := nil;
  1791. {$IFEND}
  1792. end;
  1793. ////////////////////////////////////////////////////////////////////////////////
  1794. function glbFreeLibrary(const aLibHandle: Pointer): Boolean;
  1795. begin
  1796. result := false;
  1797. if not Assigned(aLibHandle) then
  1798. exit;
  1799. {$IF DEFINED(GLB_WIN)}
  1800. Result := FreeLibrary({%H-}HINST(aLibHandle));
  1801. {$ELSEIF DEFINED(GLB_LINUX)}
  1802. Result := dlclose(aLibHandle) = 0;
  1803. {$IFEND}
  1804. end;
  1805. begin
  1806. if Assigned(GL_LibHandle) then
  1807. glbFreeLibrary(GL_LibHandle);
  1808. if Assigned(GLU_LibHandle) then
  1809. glbFreeLibrary(GLU_LibHandle);
  1810. GL_LibHandle := glbLoadLibrary(libopengl);
  1811. if not Assigned(GL_LibHandle) then
  1812. raise EglBitmap.Create('unable to load library: ' + libopengl);
  1813. GLU_LibHandle := glbLoadLibrary(libglu);
  1814. if not Assigned(GLU_LibHandle) then
  1815. raise EglBitmap.Create('unable to load library: ' + libglu);
  1816. {$IF DEFINED(GLB_WIN)}
  1817. wglGetProcAddress := glbGetProcAddress('wglGetProcAddress');
  1818. {$ELSEIF DEFINED(GLB_LINUX)}
  1819. glXGetProcAddress := glbGetProcAddress('glXGetProcAddress');
  1820. glXGetProcAddressARB := glbGetProcAddress('glXGetProcAddressARB');
  1821. {$IFEND}
  1822. glEnable := glbGetProcAddress('glEnable');
  1823. glDisable := glbGetProcAddress('glDisable');
  1824. glGetString := glbGetProcAddress('glGetString');
  1825. glGetIntegerv := glbGetProcAddress('glGetIntegerv');
  1826. glTexParameteri := glbGetProcAddress('glTexParameteri');
  1827. glTexParameteriv := glbGetProcAddress('glTexParameteriv');
  1828. glTexParameterfv := glbGetProcAddress('glTexParameterfv');
  1829. glGetTexParameteriv := glbGetProcAddress('glGetTexParameteriv');
  1830. glGetTexParameterfv := glbGetProcAddress('glGetTexParameterfv');
  1831. glGetTexLevelParameteriv := glbGetProcAddress('glGetTexLevelParameteriv');
  1832. glGetTexLevelParameterfv := glbGetProcAddress('glGetTexLevelParameterfv');
  1833. glTexGeni := glbGetProcAddress('glTexGeni');
  1834. glGenTextures := glbGetProcAddress('glGenTextures');
  1835. glBindTexture := glbGetProcAddress('glBindTexture');
  1836. glDeleteTextures := glbGetProcAddress('glDeleteTextures');
  1837. glAreTexturesResident := glbGetProcAddress('glAreTexturesResident');
  1838. glReadPixels := glbGetProcAddress('glReadPixels');
  1839. glPixelStorei := glbGetProcAddress('glPixelStorei');
  1840. glTexImage1D := glbGetProcAddress('glTexImage1D');
  1841. glTexImage2D := glbGetProcAddress('glTexImage2D');
  1842. glGetTexImage := glbGetProcAddress('glGetTexImage');
  1843. gluBuild1DMipmaps := glbGetProcAddress('gluBuild1DMipmaps', GLU_LibHandle);
  1844. gluBuild2DMipmaps := glbGetProcAddress('gluBuild2DMipmaps', GLU_LibHandle);
  1845. end;
  1846. {$ENDIF}
  1847. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1848. procedure glbReadOpenGLExtensions;
  1849. var
  1850. Buffer: AnsiString;
  1851. MajorVersion, MinorVersion: Integer;
  1852. ///////////////////////////////////////////////////////////////////////////////////////////
  1853. procedure TrimVersionString(aBuffer: AnsiString; out aMajor, aMinor: Integer);
  1854. var
  1855. Separator: Integer;
  1856. begin
  1857. aMinor := 0;
  1858. aMajor := 0;
  1859. Separator := Pos(AnsiString('.'), aBuffer);
  1860. if (Separator > 1) and (Separator < Length(aBuffer)) and
  1861. (aBuffer[Separator - 1] in ['0'..'9']) and
  1862. (aBuffer[Separator + 1] in ['0'..'9']) then begin
  1863. Dec(Separator);
  1864. while (Separator > 0) and (aBuffer[Separator] in ['0'..'9']) do
  1865. Dec(Separator);
  1866. Delete(aBuffer, 1, Separator);
  1867. Separator := Pos(AnsiString('.'), aBuffer) + 1;
  1868. while (Separator <= Length(aBuffer)) and (AnsiChar(aBuffer[Separator]) in ['0'..'9']) do
  1869. Inc(Separator);
  1870. Delete(aBuffer, Separator, 255);
  1871. Separator := Pos(AnsiString('.'), aBuffer);
  1872. aMajor := StrToInt(Copy(String(aBuffer), 1, Separator - 1));
  1873. aMinor := StrToInt(Copy(String(aBuffer), Separator + 1, 1));
  1874. end;
  1875. end;
  1876. ///////////////////////////////////////////////////////////////////////////////////////////
  1877. function CheckExtension(const Extension: AnsiString): Boolean;
  1878. var
  1879. ExtPos: Integer;
  1880. begin
  1881. ExtPos := Pos(Extension, Buffer);
  1882. result := ExtPos > 0;
  1883. if result then
  1884. result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
  1885. end;
  1886. ///////////////////////////////////////////////////////////////////////////////////////////
  1887. function CheckVersion(const aMajor, aMinor: Integer): Boolean;
  1888. begin
  1889. result := (MajorVersion > aMajor) or ((MajorVersion = aMajor) and (MinorVersion >= aMinor));
  1890. end;
  1891. begin
  1892. {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
  1893. InitOpenGLCS.Enter;
  1894. try
  1895. if not OpenGLInitialized then begin
  1896. glbInitOpenGL;
  1897. OpenGLInitialized := true;
  1898. end;
  1899. finally
  1900. InitOpenGLCS.Leave;
  1901. end;
  1902. {$ENDIF}
  1903. // Version
  1904. Buffer := glGetString(GL_VERSION);
  1905. TrimVersionString(Buffer, MajorVersion, MinorVersion);
  1906. GL_VERSION_1_2 := CheckVersion(1, 2);
  1907. GL_VERSION_1_3 := CheckVersion(1, 3);
  1908. GL_VERSION_1_4 := CheckVersion(1, 4);
  1909. GL_VERSION_2_0 := CheckVersion(2, 0);
  1910. GL_VERSION_3_3 := CheckVersion(3, 3);
  1911. // Extensions
  1912. Buffer := glGetString(GL_EXTENSIONS);
  1913. GL_ARB_texture_border_clamp := CheckExtension('GL_ARB_texture_border_clamp');
  1914. GL_ARB_texture_non_power_of_two := CheckExtension('GL_ARB_texture_non_power_of_two');
  1915. GL_ARB_texture_swizzle := CheckExtension('GL_ARB_texture_swizzle');
  1916. GL_ARB_texture_cube_map := CheckExtension('GL_ARB_texture_cube_map');
  1917. GL_ARB_texture_rectangle := CheckExtension('GL_ARB_texture_rectangle');
  1918. GL_ARB_texture_mirrored_repeat := CheckExtension('GL_ARB_texture_mirrored_repeat');
  1919. GL_EXT_texture_edge_clamp := CheckExtension('GL_EXT_texture_edge_clamp');
  1920. GL_EXT_texture_filter_anisotropic := CheckExtension('GL_EXT_texture_filter_anisotropic');
  1921. GL_EXT_texture_rectangle := CheckExtension('GL_EXT_texture_rectangle');
  1922. GL_EXT_texture_swizzle := CheckExtension('GL_EXT_texture_swizzle');
  1923. GL_EXT_texture_cube_map := CheckExtension('GL_EXT_texture_cube_map');
  1924. GL_NV_texture_rectangle := CheckExtension('GL_NV_texture_rectangle');
  1925. GL_IBM_texture_mirrored_repeat := CheckExtension('GL_IBM_texture_mirrored_repeat');
  1926. GL_SGIS_generate_mipmap := CheckExtension('GL_SGIS_generate_mipmap');
  1927. if GL_VERSION_1_3 then begin
  1928. glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1D');
  1929. glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2D');
  1930. glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImage');
  1931. end else begin
  1932. glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1DARB', nil, false);
  1933. glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2DARB', nil, false);
  1934. glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImageARB', nil, false);
  1935. end;
  1936. end;
  1937. {$ENDIF}
  1938. {$IFDEF GLB_SDL_IMAGE}
  1939. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1940. // SDL Image Helper /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1941. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1942. function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
  1943. begin
  1944. result := TStream(context^.unknown.data1).Seek(offset, whence);
  1945. end;
  1946. function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
  1947. begin
  1948. result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
  1949. end;
  1950. function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
  1951. begin
  1952. result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
  1953. end;
  1954. function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
  1955. begin
  1956. result := 0;
  1957. end;
  1958. function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
  1959. begin
  1960. result := SDL_AllocRW;
  1961. if result = nil then
  1962. raise EglBitmap.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
  1963. result^.seek := glBitmapRWseek;
  1964. result^.read := glBitmapRWread;
  1965. result^.write := glBitmapRWwrite;
  1966. result^.close := glBitmapRWclose;
  1967. result^.unknown.data1 := Stream;
  1968. end;
  1969. {$ENDIF}
  1970. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1971. procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
  1972. begin
  1973. glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
  1974. end;
  1975. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1976. procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
  1977. begin
  1978. glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
  1979. end;
  1980. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1981. procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
  1982. begin
  1983. glBitmapDefaultMipmap := aValue;
  1984. end;
  1985. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1986. procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
  1987. begin
  1988. glBitmapDefaultFormat := aFormat;
  1989. end;
  1990. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1991. procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
  1992. begin
  1993. glBitmapDefaultFilterMin := aMin;
  1994. glBitmapDefaultFilterMag := aMag;
  1995. end;
  1996. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1997. procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
  1998. begin
  1999. glBitmapDefaultWrapS := S;
  2000. glBitmapDefaultWrapT := T;
  2001. glBitmapDefaultWrapR := R;
  2002. end;
  2003. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2004. procedure glBitmapSetDefaultSwizzle(const r: GLenum = GL_RED; g: GLenum = GL_GREEN; b: GLenum = GL_BLUE; a: GLenum = GL_ALPHA);
  2005. begin
  2006. glDefaultSwizzle[0] := r;
  2007. glDefaultSwizzle[1] := g;
  2008. glDefaultSwizzle[2] := b;
  2009. glDefaultSwizzle[3] := a;
  2010. end;
  2011. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2012. function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
  2013. begin
  2014. result := glBitmapDefaultDeleteTextureOnFree;
  2015. end;
  2016. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2017. function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
  2018. begin
  2019. result := glBitmapDefaultFreeDataAfterGenTextures;
  2020. end;
  2021. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2022. function glBitmapGetDefaultMipmap: TglBitmapMipMap;
  2023. begin
  2024. result := glBitmapDefaultMipmap;
  2025. end;
  2026. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2027. function glBitmapGetDefaultFormat: TglBitmapFormat;
  2028. begin
  2029. result := glBitmapDefaultFormat;
  2030. end;
  2031. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2032. procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
  2033. begin
  2034. aMin := glBitmapDefaultFilterMin;
  2035. aMag := glBitmapDefaultFilterMag;
  2036. end;
  2037. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2038. procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
  2039. begin
  2040. S := glBitmapDefaultWrapS;
  2041. T := glBitmapDefaultWrapT;
  2042. R := glBitmapDefaultWrapR;
  2043. end;
  2044. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2045. procedure glBitmapGetDefaultSwizzle(var r, g, b, a: GLenum);
  2046. begin
  2047. r := glDefaultSwizzle[0];
  2048. g := glDefaultSwizzle[1];
  2049. b := glDefaultSwizzle[2];
  2050. a := glDefaultSwizzle[3];
  2051. end;
  2052. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2053. //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2054. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2055. function TFormatDescriptor.GetSize(const aSize: TglBitmapPixelPosition): Integer;
  2056. var
  2057. w, h: Integer;
  2058. begin
  2059. if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
  2060. w := Max(1, aSize.X);
  2061. h := Max(1, aSize.Y);
  2062. result := GetSize(w, h);
  2063. end else
  2064. result := 0;
  2065. end;
  2066. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2067. function TFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer;
  2068. begin
  2069. result := 0;
  2070. if (aWidth <= 0) or (aHeight <= 0) then
  2071. exit;
  2072. result := Ceil(aWidth * aHeight * BytesPerPixel);
  2073. end;
  2074. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2075. function TFormatDescriptor.CreateMappingData: Pointer;
  2076. begin
  2077. result := nil;
  2078. end;
  2079. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2080. procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
  2081. begin
  2082. //DUMMY
  2083. end;
  2084. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2085. function TFormatDescriptor.IsEmpty: Boolean;
  2086. begin
  2087. result := (fFormat = tfEmpty);
  2088. end;
  2089. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2090. function TFormatDescriptor.MaskMatch(const aMask: TglBitmapRec4ul): Boolean;
  2091. var
  2092. i: Integer;
  2093. m: TglBitmapRec4ul;
  2094. begin
  2095. result := false;
  2096. if (aMask.r = 0) and (aMask.g = 0) and (aMask.b = 0) and (aMask.a = 0) then
  2097. raise EglBitmap.Create('FormatCheckFormat - All Masks are 0');
  2098. m := Mask;
  2099. for i := 0 to 3 do
  2100. if (aMask.arr[i] <> m.arr[i]) then
  2101. exit;
  2102. result := true;
  2103. end;
  2104. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2105. procedure TFormatDescriptor.PreparePixel(out aPixel: TglBitmapPixelData);
  2106. begin
  2107. FillChar(aPixel{%H-}, SizeOf(aPixel), 0);
  2108. aPixel.Data := Range;
  2109. aPixel.Format := fFormat;
  2110. aPixel.Range := Range;
  2111. end;
  2112. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2113. constructor TFormatDescriptor.Create;
  2114. begin
  2115. inherited Create;
  2116. end;
  2117. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2118. //TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2119. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2120. procedure TfdAlphaUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2121. begin
  2122. aData^ := aPixel.Data.a;
  2123. inc(aData);
  2124. end;
  2125. procedure TfdAlphaUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2126. begin
  2127. aPixel.Data.r := 0;
  2128. aPixel.Data.g := 0;
  2129. aPixel.Data.b := 0;
  2130. aPixel.Data.a := aData^;
  2131. inc(aData);
  2132. end;
  2133. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2134. //TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2135. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2136. procedure TfdLuminanceUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2137. begin
  2138. aData^ := LuminanceWeight(aPixel);
  2139. inc(aData);
  2140. end;
  2141. procedure TfdLuminanceUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2142. begin
  2143. aPixel.Data.r := aData^;
  2144. aPixel.Data.g := aData^;
  2145. aPixel.Data.b := aData^;
  2146. aPixel.Data.a := 0;
  2147. inc(aData);
  2148. end;
  2149. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2150. //TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2151. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2152. procedure TfdUniversalUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2153. var
  2154. i: Integer;
  2155. begin
  2156. aData^ := 0;
  2157. for i := 0 to 3 do
  2158. if (Range.arr[i] > 0) then
  2159. aData^ := aData^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
  2160. inc(aData);
  2161. end;
  2162. procedure TfdUniversalUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2163. var
  2164. i: Integer;
  2165. begin
  2166. for i := 0 to 3 do
  2167. aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and Range.arr[i];
  2168. inc(aData);
  2169. end;
  2170. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2171. //TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2172. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2173. procedure TfdLuminanceAlphaUB2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2174. begin
  2175. inherited Map(aPixel, aData, aMapData);
  2176. aData^ := aPixel.Data.a;
  2177. inc(aData);
  2178. end;
  2179. procedure TfdLuminanceAlphaUB2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2180. begin
  2181. inherited Unmap(aData, aPixel, aMapData);
  2182. aPixel.Data.a := aData^;
  2183. inc(aData);
  2184. end;
  2185. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2186. //TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2187. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2188. procedure TfdRGBub3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2189. begin
  2190. aData^ := aPixel.Data.r;
  2191. inc(aData);
  2192. aData^ := aPixel.Data.g;
  2193. inc(aData);
  2194. aData^ := aPixel.Data.b;
  2195. inc(aData);
  2196. end;
  2197. procedure TfdRGBub3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2198. begin
  2199. aPixel.Data.r := aData^;
  2200. inc(aData);
  2201. aPixel.Data.g := aData^;
  2202. inc(aData);
  2203. aPixel.Data.b := aData^;
  2204. inc(aData);
  2205. aPixel.Data.a := 0;
  2206. end;
  2207. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2208. //TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2209. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2210. procedure TfdBGRub3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2211. begin
  2212. aData^ := aPixel.Data.b;
  2213. inc(aData);
  2214. aData^ := aPixel.Data.g;
  2215. inc(aData);
  2216. aData^ := aPixel.Data.r;
  2217. inc(aData);
  2218. end;
  2219. procedure TfdBGRub3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2220. begin
  2221. aPixel.Data.b := aData^;
  2222. inc(aData);
  2223. aPixel.Data.g := aData^;
  2224. inc(aData);
  2225. aPixel.Data.r := aData^;
  2226. inc(aData);
  2227. aPixel.Data.a := 0;
  2228. end;
  2229. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2230. //TfdRGBA_UB4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2231. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2232. procedure TfdRGBAub4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2233. begin
  2234. inherited Map(aPixel, aData, aMapData);
  2235. aData^ := aPixel.Data.a;
  2236. inc(aData);
  2237. end;
  2238. procedure TfdRGBAub4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2239. begin
  2240. inherited Unmap(aData, aPixel, aMapData);
  2241. aPixel.Data.a := aData^;
  2242. inc(aData);
  2243. end;
  2244. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2245. //TfdBGRA_UB4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2246. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2247. procedure TfdBGRAub4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2248. begin
  2249. inherited Map(aPixel, aData, aMapData);
  2250. aData^ := aPixel.Data.a;
  2251. inc(aData);
  2252. end;
  2253. procedure TfdBGRAub4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2254. begin
  2255. inherited Unmap(aData, aPixel, aMapData);
  2256. aPixel.Data.a := aData^;
  2257. inc(aData);
  2258. end;
  2259. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2260. //TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2261. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2262. procedure TfdAlphaUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2263. begin
  2264. PWord(aData)^ := aPixel.Data.a;
  2265. inc(aData, 2);
  2266. end;
  2267. procedure TfdAlphaUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2268. begin
  2269. aPixel.Data.r := 0;
  2270. aPixel.Data.g := 0;
  2271. aPixel.Data.b := 0;
  2272. aPixel.Data.a := PWord(aData)^;
  2273. inc(aData, 2);
  2274. end;
  2275. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2276. //TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2277. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2278. procedure TfdLuminanceUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2279. begin
  2280. PWord(aData)^ := LuminanceWeight(aPixel);
  2281. inc(aData, 2);
  2282. end;
  2283. procedure TfdLuminanceUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2284. begin
  2285. aPixel.Data.r := PWord(aData)^;
  2286. aPixel.Data.g := PWord(aData)^;
  2287. aPixel.Data.b := PWord(aData)^;
  2288. aPixel.Data.a := 0;
  2289. inc(aData, 2);
  2290. end;
  2291. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2292. //TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2293. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2294. procedure TfdUniversalUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2295. var
  2296. i: Integer;
  2297. begin
  2298. PWord(aData)^ := 0;
  2299. for i := 0 to 3 do
  2300. if (Range.arr[i] > 0) then
  2301. PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
  2302. inc(aData, 2);
  2303. end;
  2304. procedure TfdUniversalUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2305. var
  2306. i: Integer;
  2307. begin
  2308. for i := 0 to 3 do
  2309. aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and Range.arr[i];
  2310. inc(aData, 2);
  2311. end;
  2312. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2313. //TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2314. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2315. procedure TfdDepthUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2316. begin
  2317. PWord(aData)^ := DepthWeight(aPixel);
  2318. inc(aData, 2);
  2319. end;
  2320. procedure TfdDepthUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2321. begin
  2322. aPixel.Data.r := PWord(aData)^;
  2323. aPixel.Data.g := PWord(aData)^;
  2324. aPixel.Data.b := PWord(aData)^;
  2325. aPixel.Data.a := PWord(aData)^;;
  2326. inc(aData, 2);
  2327. end;
  2328. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2329. //TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2330. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2331. procedure TfdLuminanceAlphaUS2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2332. begin
  2333. inherited Map(aPixel, aData, aMapData);
  2334. PWord(aData)^ := aPixel.Data.a;
  2335. inc(aData, 2);
  2336. end;
  2337. procedure TfdLuminanceAlphaUS2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2338. begin
  2339. inherited Unmap(aData, aPixel, aMapData);
  2340. aPixel.Data.a := PWord(aData)^;
  2341. inc(aData, 2);
  2342. end;
  2343. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2344. //TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2345. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2346. procedure TfdRGBus3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2347. begin
  2348. PWord(aData)^ := aPixel.Data.r;
  2349. inc(aData, 2);
  2350. PWord(aData)^ := aPixel.Data.g;
  2351. inc(aData, 2);
  2352. PWord(aData)^ := aPixel.Data.b;
  2353. inc(aData, 2);
  2354. end;
  2355. procedure TfdRGBus3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2356. begin
  2357. aPixel.Data.r := PWord(aData)^;
  2358. inc(aData, 2);
  2359. aPixel.Data.g := PWord(aData)^;
  2360. inc(aData, 2);
  2361. aPixel.Data.b := PWord(aData)^;
  2362. inc(aData, 2);
  2363. aPixel.Data.a := 0;
  2364. end;
  2365. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2366. //TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2367. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2368. procedure TfdBGRus3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2369. begin
  2370. PWord(aData)^ := aPixel.Data.b;
  2371. inc(aData, 2);
  2372. PWord(aData)^ := aPixel.Data.g;
  2373. inc(aData, 2);
  2374. PWord(aData)^ := aPixel.Data.r;
  2375. inc(aData, 2);
  2376. end;
  2377. procedure TfdBGRus3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2378. begin
  2379. aPixel.Data.b := PWord(aData)^;
  2380. inc(aData, 2);
  2381. aPixel.Data.g := PWord(aData)^;
  2382. inc(aData, 2);
  2383. aPixel.Data.r := PWord(aData)^;
  2384. inc(aData, 2);
  2385. aPixel.Data.a := 0;
  2386. end;
  2387. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2388. //TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2389. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2390. procedure TfdRGBAus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2391. begin
  2392. inherited Map(aPixel, aData, aMapData);
  2393. PWord(aData)^ := aPixel.Data.a;
  2394. inc(aData, 2);
  2395. end;
  2396. procedure TfdRGBAus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2397. begin
  2398. inherited Unmap(aData, aPixel, aMapData);
  2399. aPixel.Data.a := PWord(aData)^;
  2400. inc(aData, 2);
  2401. end;
  2402. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2403. //TfdARGB_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2404. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2405. procedure TfdARGBus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2406. begin
  2407. PWord(aData)^ := aPixel.Data.a;
  2408. inc(aData, 2);
  2409. inherited Map(aPixel, aData, aMapData);
  2410. end;
  2411. procedure TfdARGBus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2412. begin
  2413. aPixel.Data.a := PWord(aData)^;
  2414. inc(aData, 2);
  2415. inherited Unmap(aData, aPixel, aMapData);
  2416. end;
  2417. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2418. //TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2419. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2420. procedure TfdBGRAus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2421. begin
  2422. inherited Map(aPixel, aData, aMapData);
  2423. PWord(aData)^ := aPixel.Data.a;
  2424. inc(aData, 2);
  2425. end;
  2426. procedure TfdBGRAus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2427. begin
  2428. inherited Unmap(aData, aPixel, aMapData);
  2429. aPixel.Data.a := PWord(aData)^;
  2430. inc(aData, 2);
  2431. end;
  2432. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2433. //TfdABGR_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2434. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2435. procedure TfdABGRus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2436. begin
  2437. PWord(aData)^ := aPixel.Data.a;
  2438. inc(aData, 2);
  2439. inherited Map(aPixel, aData, aMapData);
  2440. end;
  2441. procedure TfdABGRus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2442. begin
  2443. aPixel.Data.a := PWord(aData)^;
  2444. inc(aData, 2);
  2445. inherited Unmap(aData, aPixel, aMapData);
  2446. end;
  2447. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2448. //TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2449. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2450. procedure TfdUniversalUI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2451. var
  2452. i: Integer;
  2453. begin
  2454. PCardinal(aData)^ := 0;
  2455. for i := 0 to 3 do
  2456. if (Range.arr[i] > 0) then
  2457. PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
  2458. inc(aData, 4);
  2459. end;
  2460. procedure TfdUniversalUI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2461. var
  2462. i: Integer;
  2463. begin
  2464. for i := 0 to 3 do
  2465. aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and Range.arr[i];
  2466. inc(aData, 2);
  2467. end;
  2468. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2469. //TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2470. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2471. procedure TfdDepthUI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2472. begin
  2473. PCardinal(aData)^ := DepthWeight(aPixel);
  2474. inc(aData, 4);
  2475. end;
  2476. procedure TfdDepthUI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2477. begin
  2478. aPixel.Data.r := PCardinal(aData)^;
  2479. aPixel.Data.g := PCardinal(aData)^;
  2480. aPixel.Data.b := PCardinal(aData)^;
  2481. aPixel.Data.a := PCardinal(aData)^;
  2482. inc(aData, 4);
  2483. end;
  2484. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2485. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2486. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2487. procedure TfdAlpha4ub1.SetValues;
  2488. begin
  2489. inherited SetValues;
  2490. fBitsPerPixel := 8;
  2491. fFormat := tfAlpha4ub1;
  2492. fWithAlpha := tfAlpha4ub1;
  2493. fOpenGLFormat := tfAlpha4ub1;
  2494. fPrecision := glBitmapRec4ub(0, 0, 0, 8);
  2495. fShift := glBitmapRec4ub(0, 0, 0, 0);
  2496. fglFormat := GL_ALPHA;
  2497. fglInternalFormat := GL_ALPHA4;
  2498. fglDataFormat := GL_UNSIGNED_BYTE;
  2499. end;
  2500. procedure TfdAlpha8ub1.SetValues;
  2501. begin
  2502. inherited SetValues;
  2503. fBitsPerPixel := 8;
  2504. fFormat := tfAlpha8ub1;
  2505. fWithAlpha := tfAlpha8ub1;
  2506. fOpenGLFormat := tfAlpha8ub1;
  2507. fPrecision := glBitmapRec4ub(0, 0, 0, 8);
  2508. fShift := glBitmapRec4ub(0, 0, 0, 0);
  2509. fglFormat := GL_ALPHA;
  2510. fglInternalFormat := GL_ALPHA8;
  2511. fglDataFormat := GL_UNSIGNED_BYTE;
  2512. end;
  2513. procedure TfdAlpha16us1.SetValues;
  2514. begin
  2515. inherited SetValues;
  2516. fBitsPerPixel := 16;
  2517. fFormat := tfAlpha16us1;
  2518. fWithAlpha := tfAlpha16us1;
  2519. fOpenGLFormat := tfAlpha16us1;
  2520. fPrecision := glBitmapRec4ub(0, 0, 0, 16);
  2521. fShift := glBitmapRec4ub(0, 0, 0, 0);
  2522. fglFormat := GL_ALPHA;
  2523. fglInternalFormat := GL_ALPHA16;
  2524. fglDataFormat := GL_UNSIGNED_SHORT;
  2525. end;
  2526. procedure TfdLuminance4ub1.SetValues;
  2527. begin
  2528. inherited SetValues;
  2529. fBitsPerPixel := 8;
  2530. fFormat := tfLuminance4ub1;
  2531. fWithAlpha := tfLuminance4Alpha4ub2;
  2532. fWithoutAlpha := tfLuminance4ub1;
  2533. fOpenGLFormat := tfLuminance4ub1;
  2534. fPrecision := glBitmapRec4ub(8, 8, 8, 0);
  2535. fShift := glBitmapRec4ub(0, 0, 0, 0);
  2536. fglFormat := GL_LUMINANCE;
  2537. fglInternalFormat := GL_LUMINANCE4;
  2538. fglDataFormat := GL_UNSIGNED_BYTE;
  2539. end;
  2540. procedure TfdLuminance8ub1.SetValues;
  2541. begin
  2542. inherited SetValues;
  2543. fBitsPerPixel := 8;
  2544. fFormat := tfLuminance8ub1;
  2545. fWithAlpha := tfLuminance8Alpha8ub2;
  2546. fWithoutAlpha := tfLuminance8ub1;
  2547. fOpenGLFormat := tfLuminance8ub1;
  2548. fPrecision := glBitmapRec4ub(8, 8, 8, 0);
  2549. fShift := glBitmapRec4ub(0, 0, 0, 0);
  2550. fglFormat := GL_LUMINANCE;
  2551. fglInternalFormat := GL_LUMINANCE8;
  2552. fglDataFormat := GL_UNSIGNED_BYTE;
  2553. end;
  2554. procedure TfdLuminance16us1.SetValues;
  2555. begin
  2556. inherited SetValues;
  2557. fBitsPerPixel := 16;
  2558. fFormat := tfLuminance16us1;
  2559. fWithAlpha := tfLuminance16Alpha16us2;
  2560. fWithoutAlpha := tfLuminance16us1;
  2561. fOpenGLFormat := tfLuminance16us1;
  2562. fPrecision := glBitmapRec4ub(16, 16, 16, 0);
  2563. fShift := glBitmapRec4ub( 0, 0, 0, 0);
  2564. fglFormat := GL_LUMINANCE;
  2565. fglInternalFormat := GL_LUMINANCE16;
  2566. fglDataFormat := GL_UNSIGNED_SHORT;
  2567. end;
  2568. procedure TfdLuminance4Alpha4ub2.SetValues;
  2569. begin
  2570. inherited SetValues;
  2571. fBitsPerPixel := 16;
  2572. fFormat := tfLuminance4Alpha4ub2;
  2573. fWithAlpha := tfLuminance4Alpha4ub2;
  2574. fWithoutAlpha := tfLuminance4ub1;
  2575. fOpenGLFormat := tfLuminance4Alpha4ub2;
  2576. fPrecision := glBitmapRec4ub(8, 8, 8, 8);
  2577. fShift := glBitmapRec4ub(0, 0, 0, 8);
  2578. fglFormat := GL_LUMINANCE_ALPHA;
  2579. fglInternalFormat := GL_LUMINANCE4_ALPHA4;
  2580. fglDataFormat := GL_UNSIGNED_BYTE;
  2581. end;
  2582. procedure TfdLuminance6Alpha2ub2.SetValues;
  2583. begin
  2584. inherited SetValues;
  2585. fBitsPerPixel := 16;
  2586. fFormat := tfLuminance6Alpha2ub2;
  2587. fWithAlpha := tfLuminance6Alpha2ub2;
  2588. fWithoutAlpha := tfLuminance8ub1;
  2589. fOpenGLFormat := tfLuminance6Alpha2ub2;
  2590. fPrecision := glBitmapRec4ub(8, 8, 8, 8);
  2591. fShift := glBitmapRec4ub(0, 0, 0, 8);
  2592. fglFormat := GL_LUMINANCE_ALPHA;
  2593. fglInternalFormat := GL_LUMINANCE6_ALPHA2;
  2594. fglDataFormat := GL_UNSIGNED_BYTE;
  2595. end;
  2596. procedure TfdLuminance8Alpha8ub2.SetValues;
  2597. begin
  2598. inherited SetValues;
  2599. fBitsPerPixel := 16;
  2600. fFormat := tfLuminance8Alpha8ub2;
  2601. fWithAlpha := tfLuminance8Alpha8ub2;
  2602. fWithoutAlpha := tfLuminance8ub1;
  2603. fOpenGLFormat := tfLuminance8Alpha8ub2;
  2604. fPrecision := glBitmapRec4ub(8, 8, 8, 8);
  2605. fShift := glBitmapRec4ub(0, 0, 0, 8);
  2606. fglFormat := GL_LUMINANCE_ALPHA;
  2607. fglInternalFormat := GL_LUMINANCE8_ALPHA8;
  2608. fglDataFormat := GL_UNSIGNED_BYTE;
  2609. end;
  2610. procedure TfdLuminance12Alpha4us2.SetValues;
  2611. begin
  2612. inherited SetValues;
  2613. fBitsPerPixel := 32;
  2614. fFormat := tfLuminance12Alpha4us2;
  2615. fWithAlpha := tfLuminance12Alpha4us2;
  2616. fWithoutAlpha := tfLuminance16us1;
  2617. fOpenGLFormat := tfLuminance12Alpha4us2;
  2618. fPrecision := glBitmapRec4ub(16, 16, 16, 16);
  2619. fShift := glBitmapRec4ub( 0, 0, 0, 16);
  2620. fglFormat := GL_LUMINANCE_ALPHA;
  2621. fglInternalFormat := GL_LUMINANCE12_ALPHA4;
  2622. fglDataFormat := GL_UNSIGNED_SHORT;
  2623. end;
  2624. procedure TfdLuminance16Alpha16us2.SetValues;
  2625. begin
  2626. inherited SetValues;
  2627. fBitsPerPixel := 32;
  2628. fFormat := tfLuminance16Alpha16us2;
  2629. fWithAlpha := tfLuminance16Alpha16us2;
  2630. fWithoutAlpha := tfLuminance16us1;
  2631. fOpenGLFormat := tfLuminance16Alpha16us2;
  2632. fPrecision := glBitmapRec4ub(16, 16, 16, 16);
  2633. fShift := glBitmapRec4ub( 0, 0, 0, 16);
  2634. fglFormat := GL_LUMINANCE_ALPHA;
  2635. fglInternalFormat := GL_LUMINANCE16_ALPHA16;
  2636. fglDataFormat := GL_UNSIGNED_SHORT;
  2637. end;
  2638. procedure TfdR3G3B2ub1.SetValues;
  2639. begin
  2640. inherited SetValues;
  2641. fBitsPerPixel := 8;
  2642. fFormat := tfR3G3B2ub1;
  2643. fWithAlpha := tfRGBA4us1;
  2644. fWithoutAlpha := tfR3G3B2ub1;
  2645. fOpenGLFormat := tfR3G3B2ub1;
  2646. fRGBInverted := tfEmpty;
  2647. fPrecision := glBitmapRec4ub(3, 3, 2, 0);
  2648. fShift := glBitmapRec4ub(5, 2, 0, 0);
  2649. fglFormat := GL_RGB;
  2650. fglInternalFormat := GL_R3_G3_B2;
  2651. fglDataFormat := GL_UNSIGNED_BYTE_3_3_2;
  2652. end;
  2653. procedure TfdRGBX4us1.SetValues;
  2654. begin
  2655. inherited SetValues;
  2656. fBitsPerPixel := 16;
  2657. fFormat := tfRGBX4us1;
  2658. fWithAlpha := tfRGBA4us1;
  2659. fWithoutAlpha := tfRGBX4us1;
  2660. fOpenGLFormat := tfRGBX4us1;
  2661. fRGBInverted := tfBGRX4us1;
  2662. fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
  2663. fShift := glBitmapRec4ub(12, 8, 4, 0);
  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;
  2667. end;
  2668. procedure TfdXRGB4us1.SetValues;
  2669. begin
  2670. inherited SetValues;
  2671. fBitsPerPixel := 16;
  2672. fFormat := tfXRGB4us1;
  2673. fWithAlpha := tfARGB4us1;
  2674. fWithoutAlpha := tfXRGB4us1;
  2675. fOpenGLFormat := tfXRGB4us1;
  2676. fRGBInverted := tfXBGR4us1;
  2677. fPrecision := glBitmapRec4ub(4, 4, 4, 0);
  2678. fShift := glBitmapRec4ub(8, 4, 0, 0);
  2679. fglFormat := GL_BGRA;
  2680. fglInternalFormat := GL_RGB4;
  2681. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
  2682. end;
  2683. procedure TfdR5G6B5us1.SetValues;
  2684. begin
  2685. inherited SetValues;
  2686. fBitsPerPixel := 16;
  2687. fFormat := tfR5G6B5us1;
  2688. fWithAlpha := tfRGB5A1us1;
  2689. fWithoutAlpha := tfR5G6B5us1;
  2690. fOpenGLFormat := tfR5G6B5us1;
  2691. fRGBInverted := tfB5G6R5us1;
  2692. fPrecision := glBitmapRec4ub( 5, 6, 5, 0);
  2693. fShift := glBitmapRec4ub(11, 5, 0, 0);
  2694. fglFormat := GL_RGB;
  2695. fglInternalFormat := GL_RGB565;
  2696. fglDataFormat := GL_UNSIGNED_SHORT_5_6_5;
  2697. end;
  2698. procedure TfdRGB5X1us1.SetValues;
  2699. begin
  2700. inherited SetValues;
  2701. fBitsPerPixel := 16;
  2702. fFormat := tfRGB5X1us1;
  2703. fWithAlpha := tfRGB5A1us1;
  2704. fWithoutAlpha := tfRGB5X1us1;
  2705. fOpenGLFormat := tfRGB5X1us1;
  2706. fRGBInverted := tfBGR5X1us1;
  2707. fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
  2708. fShift := glBitmapRec4ub(11, 6, 1, 0);
  2709. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2710. fglInternalFormat := GL_RGB5;
  2711. fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
  2712. end;
  2713. procedure TfdX1RGB5us1.SetValues;
  2714. begin
  2715. inherited SetValues;
  2716. fBitsPerPixel := 16;
  2717. fFormat := tfX1RGB5us1;
  2718. fWithAlpha := tfA1RGB5us1;
  2719. fWithoutAlpha := tfX1RGB5us1;
  2720. fOpenGLFormat := tfX1RGB5us1;
  2721. fRGBInverted := tfX1BGR5us1;
  2722. fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
  2723. fShift := glBitmapRec4ub(10, 5, 0, 0);
  2724. fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2725. fglInternalFormat := GL_RGB5;
  2726. fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
  2727. end;
  2728. procedure TfdRGB8ub3.SetValues;
  2729. begin
  2730. inherited SetValues;
  2731. fBitsPerPixel := 24;
  2732. fFormat := tfRGB8ub3;
  2733. fWithAlpha := tfRGBA8ub4;
  2734. fWithoutAlpha := tfRGB8ub3;
  2735. fOpenGLFormat := tfRGB8ub3;
  2736. fRGBInverted := tfBGR8ub3;
  2737. fPrecision := glBitmapRec4ub(8, 8, 8, 0);
  2738. fShift := glBitmapRec4ub(0, 8, 16, 0);
  2739. fglFormat := GL_RGB;
  2740. fglInternalFormat := GL_RGB8;
  2741. fglDataFormat := GL_UNSIGNED_BYTE;
  2742. end;
  2743. procedure TfdRGBX8ui1.SetValues;
  2744. begin
  2745. inherited SetValues;
  2746. fBitsPerPixel := 32;
  2747. fFormat := tfRGBX8ui1;
  2748. fWithAlpha := tfRGBA8ui1;
  2749. fWithoutAlpha := tfRGBX8ui1;
  2750. fOpenGLFormat := tfRGB8ub3;
  2751. fRGBInverted := tfBGRX8ui1;
  2752. fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
  2753. fShift := glBitmapRec4ub(24, 16, 8, 0);
  2754. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2755. fglInternalFormat := GL_RGB8;
  2756. fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
  2757. end;
  2758. procedure TfdXRGB8ui1.SetValues;
  2759. begin
  2760. inherited SetValues;
  2761. fBitsPerPixel := 32;
  2762. fFormat := tfXRGB8ui1;
  2763. fWithAlpha := tfXRGB8ui1;
  2764. fWithoutAlpha := tfXRGB8ui1;
  2765. fOpenGLFormat := tfRGB8ub3;
  2766. fRGBInverted := tfXBGR8ui1;
  2767. fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
  2768. fShift := glBitmapRec4ub(16, 8, 0, 0);
  2769. fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2770. fglInternalFormat := GL_RGB8;
  2771. fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
  2772. end;
  2773. procedure TfdRGB10X2ui1.SetValues;
  2774. begin
  2775. inherited SetValues;
  2776. fBitsPerPixel := 32;
  2777. fFormat := tfRGB10X2ui1;
  2778. fWithAlpha := tfRGB10A2ui1;
  2779. fWithoutAlpha := tfRGB10X2ui1;
  2780. fOpenGLFormat := tfRGB10X2ui1;
  2781. fRGBInverted := tfBGR10X2ui1;
  2782. fPrecision := glBitmapRec4ub(10, 10, 10, 0);
  2783. fShift := glBitmapRec4ub(22, 12, 2, 0);
  2784. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2785. fglInternalFormat := GL_RGB10;
  2786. fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
  2787. end;
  2788. procedure TfdX2RGB10ui1.SetValues;
  2789. begin
  2790. inherited SetValues;
  2791. fBitsPerPixel := 32;
  2792. fFormat := tfX2RGB10ui1;
  2793. fWithAlpha := tfA2RGB10ui1;
  2794. fWithoutAlpha := tfX2RGB10ui1;
  2795. fOpenGLFormat := tfX2RGB10ui1;
  2796. fRGBInverted := tfX2BGR10ui1;
  2797. fPrecision := glBitmapRec4ub(10, 10, 10, 0);
  2798. fShift := glBitmapRec4ub(20, 10, 0, 0);
  2799. fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2800. fglInternalFormat := GL_RGB10;
  2801. fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
  2802. end;
  2803. procedure TfdRGB16us3.SetValues;
  2804. begin
  2805. inherited SetValues;
  2806. fBitsPerPixel := 48;
  2807. fFormat := tfRGB16us3;
  2808. fWithAlpha := tfRGBA16us4;
  2809. fWithoutAlpha := tfRGB16us3;
  2810. fOpenGLFormat := tfRGB16us3;
  2811. fRGBInverted := tfBGR16us3;
  2812. fPrecision := glBitmapRec4ub(16, 16, 16, 0);
  2813. fShift := glBitmapRec4ub( 0, 16, 32, 0);
  2814. fglFormat := GL_RGB;
  2815. fglInternalFormat := GL_RGB16;
  2816. fglDataFormat := GL_UNSIGNED_SHORT;
  2817. end;
  2818. procedure TfdRGBA4us1.SetValues;
  2819. begin
  2820. inherited SetValues;
  2821. fBitsPerPixel := 16;
  2822. fFormat := tfRGBA4us1;
  2823. fWithAlpha := tfRGBA4us1;
  2824. fWithoutAlpha := tfRGBX4us1;
  2825. fOpenGLFormat := tfRGBA4us1;
  2826. fRGBInverted := tfBGRA4us1;
  2827. fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
  2828. fShift := glBitmapRec4ub(12, 8, 4, 0);
  2829. fglFormat := GL_RGBA;
  2830. fglInternalFormat := GL_RGBA4;
  2831. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
  2832. end;
  2833. procedure TfdARGB4us1.SetValues;
  2834. begin
  2835. inherited SetValues;
  2836. fBitsPerPixel := 16;
  2837. fFormat := tfARGB4us1;
  2838. fWithAlpha := tfARGB4us1;
  2839. fWithoutAlpha := tfXRGB4us1;
  2840. fOpenGLFormat := tfARGB4us1;
  2841. fRGBInverted := tfABGR4us1;
  2842. fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
  2843. fShift := glBitmapRec4ub( 8, 4, 0, 12);
  2844. fglFormat := GL_BGRA;
  2845. fglInternalFormat := GL_RGBA4;
  2846. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
  2847. end;
  2848. procedure TfdRGB5A1us1.SetValues;
  2849. begin
  2850. inherited SetValues;
  2851. fBitsPerPixel := 16;
  2852. fFormat := tfRGB5A1us1;
  2853. fWithAlpha := tfRGB5A1us1;
  2854. fWithoutAlpha := tfRGB5X1us1;
  2855. fOpenGLFormat := tfRGB5A1us1;
  2856. fRGBInverted := tfBGR5A1us1;
  2857. fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
  2858. fShift := glBitmapRec4ub(11, 6, 1, 0);
  2859. fglFormat := GL_RGBA;
  2860. fglInternalFormat := GL_RGB5_A1;
  2861. fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
  2862. end;
  2863. procedure TfdA1RGB5us1.SetValues;
  2864. begin
  2865. inherited SetValues;
  2866. fBitsPerPixel := 16;
  2867. fFormat := tfA1RGB5us1;
  2868. fWithAlpha := tfA1RGB5us1;
  2869. fWithoutAlpha := tfX1RGB5us1;
  2870. fOpenGLFormat := tfA1RGB5us1;
  2871. fRGBInverted := tfA1BGR5us1;
  2872. fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
  2873. fShift := glBitmapRec4ub(10, 5, 0, 15);
  2874. fglFormat := GL_BGRA;
  2875. fglInternalFormat := GL_RGB5_A1;
  2876. fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
  2877. end;
  2878. procedure TfdRGBA8ui1.SetValues;
  2879. begin
  2880. inherited SetValues;
  2881. fBitsPerPixel := 32;
  2882. fFormat := tfRGBA8ui1;
  2883. fWithAlpha := tfRGBA8ui1;
  2884. fWithoutAlpha := tfRGBX8ui1;
  2885. fOpenGLFormat := tfRGBA8ui1;
  2886. fRGBInverted := tfBGRA8ui1;
  2887. fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
  2888. fShift := glBitmapRec4ub(24, 16, 8, 0);
  2889. fglFormat := GL_RGBA;
  2890. fglInternalFormat := GL_RGBA8;
  2891. fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
  2892. end;
  2893. procedure TfdARGB8ui1.SetValues;
  2894. begin
  2895. inherited SetValues;
  2896. fBitsPerPixel := 32;
  2897. fFormat := tfARGB8ui1;
  2898. fWithAlpha := tfARGB8ui1;
  2899. fWithoutAlpha := tfXRGB8ui1;
  2900. fOpenGLFormat := tfARGB8ui1;
  2901. fRGBInverted := tfABGR8ui1;
  2902. fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
  2903. fShift := glBitmapRec4ub(16, 8, 0, 24);
  2904. fglFormat := GL_BGRA;
  2905. fglInternalFormat := GL_RGBA8;
  2906. fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
  2907. end;
  2908. procedure TfdRGBA8ub4.SetValues;
  2909. begin
  2910. inherited SetValues;
  2911. fBitsPerPixel := 32;
  2912. fFormat := tfRGBA8ub4;
  2913. fWithAlpha := tfRGBA8ub4;
  2914. fWithoutAlpha := tfRGB8ub3;
  2915. fOpenGLFormat := tfRGBA8ub4;
  2916. fRGBInverted := tfBGRA8ub4;
  2917. fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
  2918. fShift := glBitmapRec4ub( 0, 8, 16, 24);
  2919. fglFormat := GL_RGBA;
  2920. fglInternalFormat := GL_RGBA8;
  2921. fglDataFormat := GL_UNSIGNED_BYTE;
  2922. end;
  2923. procedure TfdRGB10A2ui1.SetValues;
  2924. begin
  2925. inherited SetValues;
  2926. fBitsPerPixel := 32;
  2927. fFormat := tfRGB10A2ui1;
  2928. fWithAlpha := tfRGB10A2ui1;
  2929. fWithoutAlpha := tfRGB10X2ui1;
  2930. fOpenGLFormat := tfRGB10A2ui1;
  2931. fRGBInverted := tfBGR10A2ui1;
  2932. fPrecision := glBitmapRec4ub(10, 10, 10, 2);
  2933. fShift := glBitmapRec4ub(22, 12, 2, 0);
  2934. fglFormat := GL_RGBA;
  2935. fglInternalFormat := GL_RGB10_A2;
  2936. fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
  2937. end;
  2938. procedure TfdA2RGB10ui1.SetValues;
  2939. begin
  2940. inherited SetValues;
  2941. fBitsPerPixel := 32;
  2942. fFormat := tfA2RGB10ui1;
  2943. fWithAlpha := tfA2RGB10ui1;
  2944. fWithoutAlpha := tfX2RGB10ui1;
  2945. fOpenGLFormat := tfA2RGB10ui1;
  2946. fRGBInverted := tfA2BGR10ui1;
  2947. fPrecision := glBitmapRec4ub(10, 10, 10, 2);
  2948. fShift := glBitmapRec4ub(20, 10, 0, 30);
  2949. fglFormat := GL_BGRA;
  2950. fglInternalFormat := GL_RGB10_A2;
  2951. fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
  2952. end;
  2953. procedure TfdRGBA16us4.SetValues;
  2954. begin
  2955. inherited SetValues;
  2956. fBitsPerPixel := 64;
  2957. fFormat := tfRGBA16us4;
  2958. fWithAlpha := tfRGBA16us4;
  2959. fWithoutAlpha := tfRGB16us3;
  2960. fOpenGLFormat := tfRGBA16us4;
  2961. fRGBInverted := tfBGRA16us4;
  2962. fPrecision := glBitmapRec4ub(16, 16, 16, 16);
  2963. fShift := glBitmapRec4ub( 0, 16, 32, 48);
  2964. fglFormat := GL_RGBA;
  2965. fglInternalFormat := GL_RGBA16;
  2966. fglDataFormat := GL_UNSIGNED_SHORT;
  2967. end;
  2968. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2969. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2970. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2971. procedure TfdBGRX4us1.SetValues;
  2972. begin
  2973. inherited SetValues;
  2974. fBitsPerPixel := 16;
  2975. fFormat := tfBGRX4us1;
  2976. fWithAlpha := tfBGRA4us1;
  2977. fWithoutAlpha := tfBGRX4us1;
  2978. fOpenGLFormat := tfBGRX4us1;
  2979. fRGBInverted := tfRGBX4us1;
  2980. fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
  2981. fShift := glBitmapRec4ub( 4, 8, 12, 0);
  2982. fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2983. fglInternalFormat := GL_RGB4;
  2984. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
  2985. end;
  2986. procedure TfdXBGR4us1.SetValues;
  2987. begin
  2988. inherited SetValues;
  2989. fBitsPerPixel := 16;
  2990. fFormat := tfXBGR4us1;
  2991. fWithAlpha := tfABGR4us1;
  2992. fWithoutAlpha := tfXBGR4us1;
  2993. fOpenGLFormat := tfXBGR4us1;
  2994. fRGBInverted := tfXRGB4us1;
  2995. fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
  2996. fShift := glBitmapRec4ub( 0, 4, 8, 0);
  2997. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2998. fglInternalFormat := GL_RGB4;
  2999. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
  3000. end;
  3001. procedure TfdB5G6R5us1.SetValues;
  3002. begin
  3003. inherited SetValues;
  3004. fBitsPerPixel := 16;
  3005. fFormat := tfB5G6R5us1;
  3006. fWithAlpha := tfBGR5A1us1;
  3007. fWithoutAlpha := tfB5G6R5us1;
  3008. fOpenGLFormat := tfB5G6R5us1;
  3009. fRGBInverted := tfR5G6B5us1;
  3010. fPrecision := glBitmapRec4ub( 5, 6, 5, 0);
  3011. fShift := glBitmapRec4ub( 0, 5, 11, 0);
  3012. fglFormat := GL_RGB;
  3013. fglInternalFormat := GL_RGB565;
  3014. fglDataFormat := GL_UNSIGNED_SHORT_5_6_5_REV;
  3015. end;
  3016. procedure TfdBGR5X1us1.SetValues;
  3017. begin
  3018. inherited SetValues;
  3019. fBitsPerPixel := 16;
  3020. fFormat := tfBGR5X1us1;
  3021. fWithAlpha := tfBGR5A1us1;
  3022. fWithoutAlpha := tfBGR5X1us1;
  3023. fOpenGLFormat := tfBGR5X1us1;
  3024. fRGBInverted := tfRGB5X1us1;
  3025. fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
  3026. fShift := glBitmapRec4ub( 1, 6, 11, 0);
  3027. fglFormat := GL_BGRA;
  3028. fglInternalFormat := GL_RGB5;
  3029. fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
  3030. end;
  3031. procedure TfdX1BGR5us1.SetValues;
  3032. begin
  3033. inherited SetValues;
  3034. fBitsPerPixel := 16;
  3035. fFormat := tfX1BGR5us1;
  3036. fWithAlpha := tfA1BGR5us1;
  3037. fWithoutAlpha := tfX1BGR5us1;
  3038. fOpenGLFormat := tfX1BGR5us1;
  3039. fRGBInverted := tfX1RGB5us1;
  3040. fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
  3041. fShift := glBitmapRec4ub( 0, 5, 10, 0);
  3042. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  3043. fglInternalFormat := GL_RGB5;
  3044. fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
  3045. end;
  3046. procedure TfdBGR8ub3.SetValues;
  3047. begin
  3048. inherited SetValues;
  3049. fBitsPerPixel := 24;
  3050. fFormat := tfBGR8ub3;
  3051. fWithAlpha := tfBGRA8ub4;
  3052. fWithoutAlpha := tfBGR8ub3;
  3053. fOpenGLFormat := tfBGR8ub3;
  3054. fRGBInverted := tfRGB8ub3;
  3055. fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
  3056. fShift := glBitmapRec4ub(16, 8, 0, 0);
  3057. fglFormat := GL_BGR;
  3058. fglInternalFormat := GL_RGB8;
  3059. fglDataFormat := GL_UNSIGNED_BYTE;
  3060. end;
  3061. procedure TfdBGRX8ui1.SetValues;
  3062. begin
  3063. inherited SetValues;
  3064. fBitsPerPixel := 32;
  3065. fFormat := tfBGRX8ui1;
  3066. fWithAlpha := tfBGRA8ui1;
  3067. fWithoutAlpha := tfBGRX8ui1;
  3068. fOpenGLFormat := tfBGRX8ui1;
  3069. fRGBInverted := tfRGBX8ui1;
  3070. fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
  3071. fShift := glBitmapRec4ub( 8, 16, 24, 0);
  3072. fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  3073. fglInternalFormat := GL_RGB8;
  3074. fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
  3075. end;
  3076. procedure TfdXBGR8ui1.SetValues;
  3077. begin
  3078. inherited SetValues;
  3079. fBitsPerPixel := 32;
  3080. fFormat := tfXBGR8ui1;
  3081. fWithAlpha := tfABGR8ui1;
  3082. fWithoutAlpha := tfXBGR8ui1;
  3083. fOpenGLFormat := tfXBGR8ui1;
  3084. fRGBInverted := tfXRGB8ui1;
  3085. fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
  3086. fShift := glBitmapRec4ub( 0, 8, 16, 0);
  3087. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  3088. fglInternalFormat := GL_RGB8;
  3089. fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
  3090. end;
  3091. procedure TfdBGR10X2ui1.SetValues;
  3092. begin
  3093. inherited SetValues;
  3094. fBitsPerPixel := 32;
  3095. fFormat := tfBGR10X2ui1;
  3096. fWithAlpha := tfBGR10A2ui1;
  3097. fWithoutAlpha := tfBGR10X2ui1;
  3098. fOpenGLFormat := tfBGR10X2ui1;
  3099. fRGBInverted := tfRGB10X2ui1;
  3100. fPrecision := glBitmapRec4ub(10, 10, 10, 0);
  3101. fShift := glBitmapRec4ub( 2, 12, 22, 0);
  3102. fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  3103. fglInternalFormat := GL_RGB10;
  3104. fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
  3105. end;
  3106. procedure TfdX2BGR10ui1.SetValues;
  3107. begin
  3108. inherited SetValues;
  3109. fBitsPerPixel := 32;
  3110. fFormat := tfX2BGR10ui1;
  3111. fWithAlpha := tfA2BGR10ui1;
  3112. fWithoutAlpha := tfX2BGR10ui1;
  3113. fOpenGLFormat := tfX2BGR10ui1;
  3114. fRGBInverted := tfX2RGB10ui1;
  3115. fPrecision := glBitmapRec4ub(10, 10, 10, 0);
  3116. fShift := glBitmapRec4ub( 0, 10, 20, 0);
  3117. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  3118. fglInternalFormat := GL_RGB10;
  3119. fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
  3120. end;
  3121. procedure TfdBGR16us3.SetValues;
  3122. begin
  3123. inherited SetValues;
  3124. fBitsPerPixel := 48;
  3125. fFormat := tfBGR16us3;
  3126. fWithAlpha := tfBGRA16us4;
  3127. fWithoutAlpha := tfBGR16us3;
  3128. fOpenGLFormat := tfBGR16us3;
  3129. fRGBInverted := tfRGB16us3;
  3130. fPrecision := glBitmapRec4ub(16, 16, 16, 0);
  3131. fShift := glBitmapRec4ub(32, 16, 0, 0);
  3132. fglFormat := GL_BGR;
  3133. fglInternalFormat := GL_RGB16;
  3134. fglDataFormat := GL_UNSIGNED_SHORT;
  3135. end;
  3136. procedure TfdBGRA4us1.SetValues;
  3137. begin
  3138. inherited SetValues;
  3139. fBitsPerPixel := 16;
  3140. fFormat := tfBGRA4us1;
  3141. fWithAlpha := tfBGRA4us1;
  3142. fWithoutAlpha := tfBGRX4us1;
  3143. fOpenGLFormat := tfBGRA4us1;
  3144. fRGBInverted := tfRGBA4us1;
  3145. fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
  3146. fShift := glBitmapRec4ub( 4, 8, 12, 0);
  3147. fglFormat := GL_BGRA;
  3148. fglInternalFormat := GL_RGBA4;
  3149. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
  3150. end;
  3151. procedure TfdABGR4us1.SetValues;
  3152. begin
  3153. inherited SetValues;
  3154. fBitsPerPixel := 16;
  3155. fFormat := tfABGR4us1;
  3156. fWithAlpha := tfABGR4us1;
  3157. fWithoutAlpha := tfXBGR4us1;
  3158. fOpenGLFormat := tfABGR4us1;
  3159. fRGBInverted := tfARGB4us1;
  3160. fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
  3161. fShift := glBitmapRec4ub( 0, 4, 8, 12);
  3162. fglFormat := GL_RGBA;
  3163. fglInternalFormat := GL_RGBA4;
  3164. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
  3165. end;
  3166. procedure TfdBGR5A1us1.SetValues;
  3167. begin
  3168. inherited SetValues;
  3169. fBitsPerPixel := 16;
  3170. fFormat := tfBGR5A1us1;
  3171. fWithAlpha := tfBGR5A1us1;
  3172. fWithoutAlpha := tfBGR5X1us1;
  3173. fOpenGLFormat := tfBGR5A1us1;
  3174. fRGBInverted := tfRGB5A1us1;
  3175. fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
  3176. fShift := glBitmapRec4ub( 1, 6, 11, 0);
  3177. fglFormat := GL_BGRA;
  3178. fglInternalFormat := GL_RGB5_A1;
  3179. fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
  3180. end;
  3181. procedure TfdA1BGR5us1.SetValues;
  3182. begin
  3183. inherited SetValues;
  3184. fBitsPerPixel := 16;
  3185. fFormat := tfA1BGR5us1;
  3186. fWithAlpha := tfA1BGR5us1;
  3187. fWithoutAlpha := tfX1BGR5us1;
  3188. fOpenGLFormat := tfA1BGR5us1;
  3189. fRGBInverted := tfA1RGB5us1;
  3190. fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
  3191. fShift := glBitmapRec4ub( 0, 5, 10, 15);
  3192. fglFormat := GL_RGBA;
  3193. fglInternalFormat := GL_RGB5_A1;
  3194. fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
  3195. end;
  3196. procedure TfdBGRA8ui1.SetValues;
  3197. begin
  3198. inherited SetValues;
  3199. fBitsPerPixel := 32;
  3200. fFormat := tfBGRA8ui1;
  3201. fWithAlpha := tfBGRA8ui1;
  3202. fWithoutAlpha := tfBGRX8ui1;
  3203. fOpenGLFormat := tfBGRA8ui1;
  3204. fRGBInverted := tfRGBA8ui1;
  3205. fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
  3206. fShift := glBitmapRec4ub( 8, 16, 24, 0);
  3207. fglFormat := GL_BGRA;
  3208. fglInternalFormat := GL_RGBA8;
  3209. fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
  3210. end;
  3211. procedure TfdABGR8ui1.SetValues;
  3212. begin
  3213. inherited SetValues;
  3214. fBitsPerPixel := 32;
  3215. fFormat := tfABGR8ui1;
  3216. fWithAlpha := tfABGR8ui1;
  3217. fWithoutAlpha := tfXBGR8ui1;
  3218. fOpenGLFormat := tfABGR8ui1;
  3219. fRGBInverted := tfARGB8ui1;
  3220. fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
  3221. fShift := glBitmapRec4ub( 0, 8, 16, 24);
  3222. fglFormat := GL_RGBA;
  3223. fglInternalFormat := GL_RGBA8;
  3224. fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
  3225. end;
  3226. procedure TfdBGRA8ub4.SetValues;
  3227. begin
  3228. inherited SetValues;
  3229. fBitsPerPixel := 32;
  3230. fFormat := tfBGRA8ub4;
  3231. fWithAlpha := tfBGRA8ub4;
  3232. fWithoutAlpha := tfBGR8ub3;
  3233. fOpenGLFormat := tfBGRA8ub4;
  3234. fRGBInverted := tfRGBA8ub4;
  3235. fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
  3236. fShift := glBitmapRec4ub(16, 8, 0, 24);
  3237. fglFormat := GL_BGRA;
  3238. fglInternalFormat := GL_RGBA8;
  3239. fglDataFormat := GL_UNSIGNED_BYTE;
  3240. end;
  3241. procedure TfdBGR10A2ui1.SetValues;
  3242. begin
  3243. inherited SetValues;
  3244. fBitsPerPixel := 32;
  3245. fFormat := tfBGR10A2ui1;
  3246. fWithAlpha := tfBGR10A2ui1;
  3247. fWithoutAlpha := tfBGR10X2ui1;
  3248. fOpenGLFormat := tfBGR10A2ui1;
  3249. fRGBInverted := tfRGB10A2ui1;
  3250. fPrecision := glBitmapRec4ub(10, 10, 10, 2);
  3251. fShift := glBitmapRec4ub( 2, 12, 22, 0);
  3252. fglFormat := GL_BGRA;
  3253. fglInternalFormat := GL_RGB10_A2;
  3254. fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
  3255. end;
  3256. procedure TfdA2BGR10ui1.SetValues;
  3257. begin
  3258. inherited SetValues;
  3259. fBitsPerPixel := 32;
  3260. fFormat := tfA2BGR10ui1;
  3261. fWithAlpha := tfA2BGR10ui1;
  3262. fWithoutAlpha := tfX2BGR10ui1;
  3263. fOpenGLFormat := tfA2BGR10ui1;
  3264. fRGBInverted := tfA2RGB10ui1;
  3265. fPrecision := glBitmapRec4ub(10, 10, 10, 2);
  3266. fShift := glBitmapRec4ub( 0, 10, 20, 30);
  3267. fglFormat := GL_RGBA;
  3268. fglInternalFormat := GL_RGB10_A2;
  3269. fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
  3270. end;
  3271. procedure TfdBGRA16us4.SetValues;
  3272. begin
  3273. inherited SetValues;
  3274. fBitsPerPixel := 64;
  3275. fFormat := tfBGRA16us4;
  3276. fWithAlpha := tfBGRA16us4;
  3277. fWithoutAlpha := tfBGR16us3;
  3278. fOpenGLFormat := tfBGRA16us4;
  3279. fRGBInverted := tfRGBA16us4;
  3280. fPrecision := glBitmapRec4ub(16, 16, 16, 16);
  3281. fShift := glBitmapRec4ub(32, 16, 0, 48);
  3282. fglFormat := GL_BGRA;
  3283. fglInternalFormat := GL_RGBA16;
  3284. fglDataFormat := GL_UNSIGNED_SHORT;
  3285. end;
  3286. procedure TfdDepth16us1.SetValues;
  3287. begin
  3288. inherited SetValues;
  3289. fBitsPerPixel := 16;
  3290. fFormat := tfDepth16us1;
  3291. fWithoutAlpha := tfDepth16us1;
  3292. fOpenGLFormat := tfDepth16us1;
  3293. fPrecision := glBitmapRec4ub(16, 16, 16, 16);
  3294. fShift := glBitmapRec4ub( 0, 0, 0, 0);
  3295. fglFormat := GL_DEPTH_COMPONENT;
  3296. fglInternalFormat := GL_DEPTH_COMPONENT16;
  3297. fglDataFormat := GL_UNSIGNED_SHORT;
  3298. end;
  3299. procedure TfdDepth24ui1.SetValues;
  3300. begin
  3301. inherited SetValues;
  3302. fBitsPerPixel := 32;
  3303. fFormat := tfDepth24ui1;
  3304. fWithoutAlpha := tfDepth24ui1;
  3305. fOpenGLFormat := tfDepth24ui1;
  3306. fPrecision := glBitmapRec4ub(32, 32, 32, 32);
  3307. fShift := glBitmapRec4ub( 0, 0, 0, 0);
  3308. fglFormat := GL_DEPTH_COMPONENT;
  3309. fglInternalFormat := GL_DEPTH_COMPONENT24;
  3310. fglDataFormat := GL_UNSIGNED_INT;
  3311. end;
  3312. procedure TfdDepth32ui1.SetValues;
  3313. begin
  3314. inherited SetValues;
  3315. fBitsPerPixel := 32;
  3316. fFormat := tfDepth32ui1;
  3317. fWithoutAlpha := tfDepth32ui1;
  3318. fOpenGLFormat := tfDepth32ui1;
  3319. fPrecision := glBitmapRec4ub(32, 32, 32, 32);
  3320. fShift := glBitmapRec4ub( 0, 0, 0, 0);
  3321. fglFormat := GL_DEPTH_COMPONENT;
  3322. fglInternalFormat := GL_DEPTH_COMPONENT32;
  3323. fglDataFormat := GL_UNSIGNED_INT;
  3324. end;
  3325. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3326. //TfdS3tcDtx1RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3327. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3328. procedure TfdS3tcDtx1RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  3329. begin
  3330. raise EglBitmap.Create('mapping for compressed formats is not supported');
  3331. end;
  3332. procedure TfdS3tcDtx1RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  3333. begin
  3334. raise EglBitmap.Create('mapping for compressed formats is not supported');
  3335. end;
  3336. procedure TfdS3tcDtx1RGBA.SetValues;
  3337. begin
  3338. inherited SetValues;
  3339. fFormat := tfS3tcDtx1RGBA;
  3340. fWithAlpha := tfS3tcDtx1RGBA;
  3341. fOpenGLFormat := tfS3tcDtx1RGBA;
  3342. fUncompressed := tfRGB5A1us1;
  3343. fBitsPerPixel := 4;
  3344. fIsCompressed := true;
  3345. fglFormat := GL_COMPRESSED_RGBA;
  3346. fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
  3347. fglDataFormat := GL_UNSIGNED_BYTE;
  3348. end;
  3349. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3350. //TfdS3tcDtx3RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3351. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3352. procedure TfdS3tcDtx3RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  3353. begin
  3354. raise EglBitmap.Create('mapping for compressed formats is not supported');
  3355. end;
  3356. procedure TfdS3tcDtx3RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  3357. begin
  3358. raise EglBitmap.Create('mapping for compressed formats is not supported');
  3359. end;
  3360. procedure TfdS3tcDtx3RGBA.SetValues;
  3361. begin
  3362. inherited SetValues;
  3363. fFormat := tfS3tcDtx3RGBA;
  3364. fWithAlpha := tfS3tcDtx3RGBA;
  3365. fOpenGLFormat := tfS3tcDtx3RGBA;
  3366. fUncompressed := tfRGBA8ub4;
  3367. fBitsPerPixel := 8;
  3368. fIsCompressed := true;
  3369. fglFormat := GL_COMPRESSED_RGBA;
  3370. fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
  3371. fglDataFormat := GL_UNSIGNED_BYTE;
  3372. end;
  3373. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3374. //TfdS3tcDtx5RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3375. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3376. procedure TfdS3tcDtx5RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  3377. begin
  3378. raise EglBitmap.Create('mapping for compressed formats is not supported');
  3379. end;
  3380. procedure TfdS3tcDtx5RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  3381. begin
  3382. raise EglBitmap.Create('mapping for compressed formats is not supported');
  3383. end;
  3384. procedure TfdS3tcDtx5RGBA.SetValues;
  3385. begin
  3386. inherited SetValues;
  3387. fFormat := tfS3tcDtx3RGBA;
  3388. fWithAlpha := tfS3tcDtx3RGBA;
  3389. fOpenGLFormat := tfS3tcDtx3RGBA;
  3390. fUncompressed := tfRGBA8ub4;
  3391. fBitsPerPixel := 8;
  3392. fIsCompressed := true;
  3393. fglFormat := GL_COMPRESSED_RGBA;
  3394. fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  3395. fglDataFormat := GL_UNSIGNED_BYTE;
  3396. end;
  3397. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3398. //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3399. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3400. function TglBitmapFormatDescriptor.GetHasRed: Boolean;
  3401. begin
  3402. result := (fPrecision.r > 0);
  3403. end;
  3404. function TglBitmapFormatDescriptor.GetHasGreen: Boolean;
  3405. begin
  3406. result := (fPrecision.g > 0);
  3407. end;
  3408. function TglBitmapFormatDescriptor.GetHasBlue: Boolean;
  3409. begin
  3410. result := (fPrecision.b > 0);
  3411. end;
  3412. function TglBitmapFormatDescriptor.GetHasAlpha: Boolean;
  3413. begin
  3414. result := (fPrecision.a > 0);
  3415. end;
  3416. function TglBitmapFormatDescriptor.GetHasColor: Boolean;
  3417. begin
  3418. result := HasRed or HasGreen or HasBlue;
  3419. end;
  3420. function TglBitmapFormatDescriptor.GetIsGrayscale: Boolean;
  3421. begin
  3422. result := (Mask.r = Mask.g) and (Mask.g = Mask.b) and (Mask.r > 0);
  3423. end;
  3424. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3425. procedure TglBitmapFormatDescriptor.SetValues;
  3426. begin
  3427. fFormat := tfEmpty;
  3428. fWithAlpha := tfEmpty;
  3429. fWithoutAlpha := tfEmpty;
  3430. fOpenGLFormat := tfEmpty;
  3431. fRGBInverted := tfEmpty;
  3432. fUncompressed := tfEmpty;
  3433. fBitsPerPixel := 0;
  3434. fIsCompressed := false;
  3435. fglFormat := 0;
  3436. fglInternalFormat := 0;
  3437. fglDataFormat := 0;
  3438. FillChar(fPrecision, 0, SizeOf(fPrecision));
  3439. FillChar(fShift, 0, SizeOf(fShift));
  3440. end;
  3441. procedure TglBitmapFormatDescriptor.CalcValues;
  3442. var
  3443. i: Integer;
  3444. begin
  3445. fBytesPerPixel := fBitsPerPixel / 8;
  3446. fChannelCount := 0;
  3447. for i := 0 to 3 do begin
  3448. if (fPrecision.arr[i] > 0) then
  3449. inc(fChannelCount);
  3450. fRange.arr[i] := (1 shl fPrecision.arr[i]) - 1;
  3451. fMask.arr[i] := fRange.arr[i] shl fShift.arr[i];
  3452. end;
  3453. end;
  3454. constructor TglBitmapFormatDescriptor.Create;
  3455. begin
  3456. inherited Create;
  3457. SetValues;
  3458. CalcValues;
  3459. end;
  3460. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3461. class function TglBitmapFormatDescriptor.GetByFormat(const aInternalFormat: GLenum): TglBitmapFormatDescriptor;
  3462. var
  3463. f: TglBitmapFormat;
  3464. begin
  3465. for f := Low(TglBitmapFormat) to High(TglBitmapFormat) do begin
  3466. result := TFormatDescriptor.Get(f);
  3467. if (result.glInternalFormat = aInternalFormat) then
  3468. exit;
  3469. end;
  3470. result := TFormatDescriptor.Get(tfEmpty);
  3471. end;
  3472. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3473. //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3474. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3475. class procedure TFormatDescriptor.Init;
  3476. begin
  3477. if not Assigned(FormatDescriptorCS) then
  3478. FormatDescriptorCS := TCriticalSection.Create;
  3479. end;
  3480. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3481. class function TFormatDescriptor.Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
  3482. begin
  3483. FormatDescriptorCS.Enter;
  3484. try
  3485. result := FormatDescriptors[aFormat];
  3486. if not Assigned(result) then begin
  3487. result := FORMAT_DESCRIPTOR_CLASSES[aFormat].Create;
  3488. FormatDescriptors[aFormat] := result;
  3489. end;
  3490. finally
  3491. FormatDescriptorCS.Leave;
  3492. end;
  3493. end;
  3494. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3495. class function TFormatDescriptor.GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
  3496. begin
  3497. result := Get(Get(aFormat).WithAlpha);
  3498. end;
  3499. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3500. class function TFormatDescriptor.GetFromMask(const aMask: TglBitmapRec4ul; const aBitCount: Integer): TFormatDescriptor;
  3501. var
  3502. ft: TglBitmapFormat;
  3503. begin
  3504. // find matching format with OpenGL support
  3505. for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
  3506. result := Get(ft);
  3507. if (result.MaskMatch(aMask)) and
  3508. (result.glFormat <> 0) and
  3509. (result.glInternalFormat <> 0) and
  3510. ((aBitCount = 0) or (aBitCount = result.BitsPerPixel))
  3511. then
  3512. exit;
  3513. end;
  3514. // find matching format without OpenGL Support
  3515. for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
  3516. result := Get(ft);
  3517. if result.MaskMatch(aMask) and ((aBitCount = 0) or (aBitCount = result.BitsPerPixel)) then
  3518. exit;
  3519. end;
  3520. result := TFormatDescriptor.Get(tfEmpty);
  3521. end;
  3522. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3523. class function TFormatDescriptor.GetFromPrecShift(const aPrec, aShift: TglBitmapRec4ub; const aBitCount: Integer): TFormatDescriptor;
  3524. var
  3525. ft: TglBitmapFormat;
  3526. begin
  3527. // find matching format with OpenGL support
  3528. for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
  3529. result := Get(ft);
  3530. if glBitmapRec4ubCompare(result.Shift, aShift) and
  3531. glBitmapRec4ubCompare(result.Precision, aPrec) and
  3532. (result.glFormat <> 0) and
  3533. (result.glInternalFormat <> 0) and
  3534. ((aBitCount = 0) or (aBitCount = result.BitsPerPixel))
  3535. then
  3536. exit;
  3537. end;
  3538. // find matching format without OpenGL Support
  3539. for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
  3540. result := Get(ft);
  3541. if glBitmapRec4ubCompare(result.Shift, aShift) and
  3542. glBitmapRec4ubCompare(result.Precision, aPrec) and
  3543. ((aBitCount = 0) or (aBitCount = result.BitsPerPixel)) then
  3544. exit;
  3545. end;
  3546. result := TFormatDescriptor.Get(tfEmpty);
  3547. end;
  3548. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3549. class procedure TFormatDescriptor.Clear;
  3550. var
  3551. f: TglBitmapFormat;
  3552. begin
  3553. FormatDescriptorCS.Enter;
  3554. try
  3555. for f := low(FormatDescriptors) to high(FormatDescriptors) do
  3556. FreeAndNil(FormatDescriptors[f]);
  3557. finally
  3558. FormatDescriptorCS.Leave;
  3559. end;
  3560. end;
  3561. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3562. class procedure TFormatDescriptor.Finalize;
  3563. begin
  3564. Clear;
  3565. FreeAndNil(FormatDescriptorCS);
  3566. end;
  3567. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3568. //TBitfieldFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3569. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3570. procedure TbmpBitfieldFormat.SetCustomValues(const aBPP: Integer; aMask: TglBitmapRec4ul);
  3571. var
  3572. i: Integer;
  3573. begin
  3574. for i := 0 to 3 do begin
  3575. fShift.arr[i] := 0;
  3576. while (aMask.arr[i] > 0) and (aMask.arr[i] and 1 > 0) do begin
  3577. aMask.arr[i] := aMask.arr[i] shr 1;
  3578. inc(fShift.arr[i]);
  3579. end;
  3580. fPrecision.arr[i] := CountSetBits(aMask.arr[i]);
  3581. end;
  3582. CalcValues;
  3583. end;
  3584. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3585. procedure TbmpBitfieldFormat.SetCustomValues(const aBBP: Integer; const aPrec, aShift: TglBitmapRec4ub);
  3586. begin
  3587. fBitsPerPixel := aBBP;
  3588. fPrecision := aPrec;
  3589. fShift := aShift;
  3590. CalcValues;
  3591. end;
  3592. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3593. procedure TbmpBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  3594. var
  3595. data: QWord;
  3596. begin
  3597. data :=
  3598. ((aPixel.Data.r and Range.r) shl Shift.r) or
  3599. ((aPixel.Data.g and Range.g) shl Shift.g) or
  3600. ((aPixel.Data.b and Range.b) shl Shift.b) or
  3601. ((aPixel.Data.a and Range.a) shl Shift.a);
  3602. case BitsPerPixel of
  3603. 8: aData^ := data;
  3604. 16: PWord(aData)^ := data;
  3605. 32: PCardinal(aData)^ := data;
  3606. 64: PQWord(aData)^ := data;
  3607. else
  3608. raise EglBitmap.CreateFmt('invalid pixel size: %d', [BitsPerPixel]);
  3609. end;
  3610. inc(aData, Round(BytesPerPixel));
  3611. end;
  3612. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3613. procedure TbmpBitfieldFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  3614. var
  3615. data: QWord;
  3616. i: Integer;
  3617. begin
  3618. case BitsPerPixel of
  3619. 8: data := aData^;
  3620. 16: data := PWord(aData)^;
  3621. 32: data := PCardinal(aData)^;
  3622. 64: data := PQWord(aData)^;
  3623. else
  3624. raise EglBitmap.CreateFmt('invalid pixel size: %d', [BitsPerPixel]);
  3625. end;
  3626. for i := 0 to 3 do
  3627. aPixel.Data.arr[i] := (data shr fShift.arr[i]) and Range.arr[i];
  3628. inc(aData, Round(BytesPerPixel));
  3629. end;
  3630. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3631. //TColorTableFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3632. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3633. procedure TbmpColorTableFormat.SetValues;
  3634. begin
  3635. inherited SetValues;
  3636. fShift := glBitmapRec4ub(8, 8, 8, 0);
  3637. end;
  3638. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3639. procedure TbmpColorTableFormat.SetCustomValues(const aFormat: TglBitmapFormat; const aBPP: Integer; const aPrec, aShift: TglBitmapRec4ub);
  3640. begin
  3641. fFormat := aFormat;
  3642. fBitsPerPixel := aBPP;
  3643. fPrecision := aPrec;
  3644. fShift := aShift;
  3645. CalcValues;
  3646. end;
  3647. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3648. procedure TbmpColorTableFormat.CalcValues;
  3649. begin
  3650. inherited CalcValues;
  3651. end;
  3652. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3653. procedure TbmpColorTableFormat.CreateColorTable;
  3654. var
  3655. i: Integer;
  3656. begin
  3657. SetLength(fColorTable, 256);
  3658. if not HasColor then begin
  3659. // alpha
  3660. for i := 0 to High(fColorTable) do begin
  3661. fColorTable[i].r := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
  3662. fColorTable[i].g := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
  3663. fColorTable[i].b := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
  3664. fColorTable[i].a := 0;
  3665. end;
  3666. end else begin
  3667. // normal
  3668. for i := 0 to High(fColorTable) do begin
  3669. fColorTable[i].r := Round(((i shr Shift.r) and Range.r) / Range.r * 255);
  3670. fColorTable[i].g := Round(((i shr Shift.g) and Range.g) / Range.g * 255);
  3671. fColorTable[i].b := Round(((i shr Shift.b) and Range.b) / Range.b * 255);
  3672. fColorTable[i].a := 0;
  3673. end;
  3674. end;
  3675. end;
  3676. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3677. procedure TbmpColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  3678. begin
  3679. if (BitsPerPixel <> 8) then
  3680. raise EglBitmapUnsupportedFormat.Create('color table are only supported for 8bit formats');
  3681. if not HasColor then
  3682. // alpha
  3683. aData^ := aPixel.Data.a
  3684. else
  3685. // normal
  3686. aData^ := Round(
  3687. ((aPixel.Data.r and Range.r) shl Shift.r) or
  3688. ((aPixel.Data.g and Range.g) shl Shift.g) or
  3689. ((aPixel.Data.b and Range.b) shl Shift.b));
  3690. inc(aData);
  3691. end;
  3692. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3693. procedure TbmpColorTableFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  3694. begin
  3695. if (BitsPerPixel <> 8) then
  3696. raise EglBitmapUnsupportedFormat.Create('color table are only supported for 8bit formats');
  3697. with fColorTable[aData^] do begin
  3698. aPixel.Data.r := r;
  3699. aPixel.Data.g := g;
  3700. aPixel.Data.b := b;
  3701. aPixel.Data.a := a;
  3702. end;
  3703. inc(aData, 1);
  3704. end;
  3705. destructor TbmpColorTableFormat.Destroy;
  3706. begin
  3707. SetLength(fColorTable, 0);
  3708. inherited Destroy;
  3709. end;
  3710. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3711. //TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3712. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3713. procedure glBitmapConvertPixel(var aPixel: TglBitmapPixelData; const aSourceFD, aDestFD: TFormatDescriptor);
  3714. var
  3715. i: Integer;
  3716. begin
  3717. for i := 0 to 3 do begin
  3718. if (aSourceFD.Range.arr[i] <> aDestFD.Range.arr[i]) then begin
  3719. if (aSourceFD.Range.arr[i] > 0) then
  3720. aPixel.Data.arr[i] := Round(aPixel.Data.arr[i] / aSourceFD.Range.arr[i] * aDestFD.Range.arr[i])
  3721. else
  3722. aPixel.Data.arr[i] := 0;
  3723. end;
  3724. end;
  3725. end;
  3726. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3727. procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
  3728. begin
  3729. with aFuncRec do begin
  3730. if (Source.Range.r > 0) then
  3731. Dest.Data.r := Source.Data.r;
  3732. if (Source.Range.g > 0) then
  3733. Dest.Data.g := Source.Data.g;
  3734. if (Source.Range.b > 0) then
  3735. Dest.Data.b := Source.Data.b;
  3736. if (Source.Range.a > 0) then
  3737. Dest.Data.a := Source.Data.a;
  3738. end;
  3739. end;
  3740. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3741. procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
  3742. var
  3743. i: Integer;
  3744. begin
  3745. with aFuncRec do begin
  3746. for i := 0 to 3 do
  3747. if (Source.Range.arr[i] > 0) then
  3748. Dest.Data.arr[i] := Round(Dest.Range.arr[i] * Source.Data.arr[i] / Source.Range.arr[i]);
  3749. end;
  3750. end;
  3751. type
  3752. TShiftData = packed record
  3753. case Integer of
  3754. 0: (r, g, b, a: SmallInt);
  3755. 1: (arr: array[0..3] of SmallInt);
  3756. end;
  3757. PShiftData = ^TShiftData;
  3758. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3759. procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
  3760. var
  3761. i: Integer;
  3762. begin
  3763. with aFuncRec do
  3764. for i := 0 to 3 do
  3765. if (Source.Range.arr[i] > 0) then
  3766. Dest.Data.arr[i] := Source.Data.arr[i] shr PShiftData(Args)^.arr[i];
  3767. end;
  3768. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3769. procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
  3770. begin
  3771. with aFuncRec do begin
  3772. Dest.Data := Source.Data;
  3773. if ({%H-}PtrUInt(Args) and $1 > 0) then begin
  3774. Dest.Data.r := Dest.Data.r xor Dest.Range.r;
  3775. Dest.Data.g := Dest.Data.g xor Dest.Range.g;
  3776. Dest.Data.b := Dest.Data.b xor Dest.Range.b;
  3777. end;
  3778. if ({%H-}PtrUInt(Args) and $2 > 0) then begin
  3779. Dest.Data.a := Dest.Data.a xor Dest.Range.a;
  3780. end;
  3781. end;
  3782. end;
  3783. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3784. procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
  3785. var
  3786. i: Integer;
  3787. begin
  3788. with aFuncRec do begin
  3789. for i := 0 to 3 do
  3790. Dest.Data.arr[i] := PglBitmapPixelData(Args)^.Data.arr[i];
  3791. end;
  3792. end;
  3793. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3794. procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
  3795. var
  3796. Temp: Single;
  3797. begin
  3798. with FuncRec do begin
  3799. if (FuncRec.Args = nil) then begin //source has no alpha
  3800. Temp :=
  3801. Source.Data.r / Source.Range.r * ALPHA_WEIGHT_R +
  3802. Source.Data.g / Source.Range.g * ALPHA_WEIGHT_G +
  3803. Source.Data.b / Source.Range.b * ALPHA_WEIGHT_B;
  3804. Dest.Data.a := Round(Dest.Range.a * Temp);
  3805. end else
  3806. Dest.Data.a := Round(Source.Data.a / Source.Range.a * Dest.Range.a);
  3807. end;
  3808. end;
  3809. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3810. procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
  3811. type
  3812. PglBitmapPixelData = ^TglBitmapPixelData;
  3813. begin
  3814. with FuncRec do begin
  3815. Dest.Data.r := Source.Data.r;
  3816. Dest.Data.g := Source.Data.g;
  3817. Dest.Data.b := Source.Data.b;
  3818. with PglBitmapPixelData(Args)^ do
  3819. if ((Dest.Data.r <= Data.r) and (Dest.Data.r >= Range.r) and
  3820. (Dest.Data.g <= Data.g) and (Dest.Data.g >= Range.g) and
  3821. (Dest.Data.b <= Data.b) and (Dest.Data.b >= Range.b)) then
  3822. Dest.Data.a := 0
  3823. else
  3824. Dest.Data.a := Dest.Range.a;
  3825. end;
  3826. end;
  3827. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3828. procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
  3829. begin
  3830. with FuncRec do begin
  3831. Dest.Data.r := Source.Data.r;
  3832. Dest.Data.g := Source.Data.g;
  3833. Dest.Data.b := Source.Data.b;
  3834. Dest.Data.a := PCardinal(Args)^;
  3835. end;
  3836. end;
  3837. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3838. procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
  3839. type
  3840. PRGBPix = ^TRGBPix;
  3841. TRGBPix = array [0..2] of byte;
  3842. var
  3843. Temp: Byte;
  3844. begin
  3845. while aWidth > 0 do begin
  3846. Temp := PRGBPix(aData)^[0];
  3847. PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
  3848. PRGBPix(aData)^[2] := Temp;
  3849. if aHasAlpha then
  3850. Inc(aData, 4)
  3851. else
  3852. Inc(aData, 3);
  3853. dec(aWidth);
  3854. end;
  3855. end;
  3856. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3857. //TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3858. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3859. function TglBitmap.GetFormatDesc: TglBitmapFormatDescriptor;
  3860. begin
  3861. result := TFormatDescriptor.Get(Format);
  3862. end;
  3863. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3864. function TglBitmap.GetWidth: Integer;
  3865. begin
  3866. if (ffX in fDimension.Fields) then
  3867. result := fDimension.X
  3868. else
  3869. result := -1;
  3870. end;
  3871. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3872. function TglBitmap.GetHeight: Integer;
  3873. begin
  3874. if (ffY in fDimension.Fields) then
  3875. result := fDimension.Y
  3876. else
  3877. result := -1;
  3878. end;
  3879. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3880. function TglBitmap.GetFileWidth: Integer;
  3881. begin
  3882. result := Max(1, Width);
  3883. end;
  3884. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3885. function TglBitmap.GetFileHeight: Integer;
  3886. begin
  3887. result := Max(1, Height);
  3888. end;
  3889. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3890. procedure TglBitmap.SetCustomData(const aValue: Pointer);
  3891. begin
  3892. if fCustomData = aValue then
  3893. exit;
  3894. fCustomData := aValue;
  3895. end;
  3896. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3897. procedure TglBitmap.SetCustomName(const aValue: String);
  3898. begin
  3899. if fCustomName = aValue then
  3900. exit;
  3901. fCustomName := aValue;
  3902. end;
  3903. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3904. procedure TglBitmap.SetCustomNameW(const aValue: WideString);
  3905. begin
  3906. if fCustomNameW = aValue then
  3907. exit;
  3908. fCustomNameW := aValue;
  3909. end;
  3910. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3911. procedure TglBitmap.SetFreeDataOnDestroy(const aValue: Boolean);
  3912. begin
  3913. if fFreeDataOnDestroy = aValue then
  3914. exit;
  3915. fFreeDataOnDestroy := aValue;
  3916. end;
  3917. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3918. procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
  3919. begin
  3920. if fDeleteTextureOnFree = aValue then
  3921. exit;
  3922. fDeleteTextureOnFree := aValue;
  3923. end;
  3924. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3925. procedure TglBitmap.SetFormat(const aValue: TglBitmapFormat);
  3926. begin
  3927. if fFormat = aValue then
  3928. exit;
  3929. if TFormatDescriptor.Get(Format).BitsPerPixel <> TFormatDescriptor.Get(aValue).BitsPerPixel then
  3930. raise EglBitmapUnsupportedFormat.Create(Format);
  3931. SetDataPointer(fData, aValue, Width, Height); //be careful, Data could be freed by this method
  3932. end;
  3933. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3934. procedure TglBitmap.SetFreeDataAfterGenTexture(const aValue: Boolean);
  3935. begin
  3936. if fFreeDataAfterGenTexture = aValue then
  3937. exit;
  3938. fFreeDataAfterGenTexture := aValue;
  3939. end;
  3940. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3941. procedure TglBitmap.SetID(const aValue: Cardinal);
  3942. begin
  3943. if fID = aValue then
  3944. exit;
  3945. fID := aValue;
  3946. end;
  3947. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3948. procedure TglBitmap.SetMipMap(const aValue: TglBitmapMipMap);
  3949. begin
  3950. if fMipMap = aValue then
  3951. exit;
  3952. fMipMap := aValue;
  3953. end;
  3954. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3955. procedure TglBitmap.SetTarget(const aValue: Cardinal);
  3956. begin
  3957. if fTarget = aValue then
  3958. exit;
  3959. fTarget := aValue;
  3960. end;
  3961. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3962. procedure TglBitmap.SetAnisotropic(const aValue: Integer);
  3963. var
  3964. MaxAnisotropic: Integer;
  3965. begin
  3966. fAnisotropic := aValue;
  3967. if (ID > 0) then begin
  3968. if GL_EXT_texture_filter_anisotropic then begin
  3969. if fAnisotropic > 0 then begin
  3970. Bind(false);
  3971. glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
  3972. if aValue > MaxAnisotropic then
  3973. fAnisotropic := MaxAnisotropic;
  3974. glTexParameteri(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, fAnisotropic);
  3975. end;
  3976. end else begin
  3977. fAnisotropic := 0;
  3978. end;
  3979. end;
  3980. end;
  3981. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3982. procedure TglBitmap.CreateID;
  3983. begin
  3984. if (ID <> 0) then
  3985. glDeleteTextures(1, @fID);
  3986. glGenTextures(1, @fID);
  3987. Bind(false);
  3988. end;
  3989. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3990. procedure TglBitmap.SetupParameters(out aBuildWithGlu: Boolean);
  3991. begin
  3992. // Set Up Parameters
  3993. SetWrap(fWrapS, fWrapT, fWrapR);
  3994. SetFilter(fFilterMin, fFilterMag);
  3995. SetAnisotropic(fAnisotropic);
  3996. SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
  3997. if (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
  3998. SetSwizzle(fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
  3999. // Mip Maps Generation Mode
  4000. aBuildWithGlu := false;
  4001. if (MipMap = mmMipmap) then begin
  4002. if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
  4003. glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
  4004. else
  4005. aBuildWithGlu := true;
  4006. end else if (MipMap = mmMipmapGlu) then
  4007. aBuildWithGlu := true;
  4008. end;
  4009. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4010. procedure TglBitmap.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
  4011. const aWidth: Integer; const aHeight: Integer);
  4012. var
  4013. s: Single;
  4014. begin
  4015. if (Data <> aData) then begin
  4016. if (Assigned(Data)) then
  4017. FreeMem(Data);
  4018. fData := aData;
  4019. end;
  4020. if not Assigned(fData) then begin
  4021. fPixelSize := 0;
  4022. fRowSize := 0;
  4023. end else begin
  4024. FillChar(fDimension, SizeOf(fDimension), 0);
  4025. if aWidth <> -1 then begin
  4026. fDimension.Fields := fDimension.Fields + [ffX];
  4027. fDimension.X := aWidth;
  4028. end;
  4029. if aHeight <> -1 then begin
  4030. fDimension.Fields := fDimension.Fields + [ffY];
  4031. fDimension.Y := aHeight;
  4032. end;
  4033. s := TFormatDescriptor.Get(aFormat).BytesPerPixel;
  4034. fFormat := aFormat;
  4035. fPixelSize := Ceil(s);
  4036. fRowSize := Ceil(s * aWidth);
  4037. end;
  4038. end;
  4039. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4040. function TglBitmap.FlipHorz: Boolean;
  4041. begin
  4042. result := false;
  4043. end;
  4044. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4045. function TglBitmap.FlipVert: Boolean;
  4046. begin
  4047. result := false;
  4048. end;
  4049. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4050. //TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4051. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4052. procedure TglBitmap.AfterConstruction;
  4053. begin
  4054. inherited AfterConstruction;
  4055. fID := 0;
  4056. fTarget := 0;
  4057. fIsResident := false;
  4058. fMipMap := glBitmapDefaultMipmap;
  4059. fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
  4060. fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
  4061. glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
  4062. glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
  4063. glBitmapGetDefaultSwizzle (fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
  4064. end;
  4065. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4066. procedure TglBitmap.BeforeDestruction;
  4067. var
  4068. NewData: PByte;
  4069. begin
  4070. if fFreeDataOnDestroy then begin
  4071. NewData := nil;
  4072. SetDataPointer(NewData, tfEmpty); //be careful, Data could be freed by this method
  4073. end;
  4074. if (fID > 0) and fDeleteTextureOnFree then
  4075. glDeleteTextures(1, @fID);
  4076. inherited BeforeDestruction;
  4077. end;
  4078. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4079. procedure TglBitmap.PrepareResType(var aResource: String; var aResType: PChar);
  4080. var
  4081. TempPos: Integer;
  4082. begin
  4083. if not Assigned(aResType) then begin
  4084. TempPos := Pos('.', aResource);
  4085. aResType := PChar(UpperCase(Copy(aResource, TempPos + 1, Length(aResource) - TempPos)));
  4086. aResource := UpperCase(Copy(aResource, 0, TempPos -1));
  4087. end;
  4088. end;
  4089. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4090. procedure TglBitmap.LoadFromFile(const aFilename: String);
  4091. var
  4092. fs: TFileStream;
  4093. begin
  4094. if not FileExists(aFilename) then
  4095. raise EglBitmap.Create('file does not exist: ' + aFilename);
  4096. fFilename := aFilename;
  4097. fs := TFileStream.Create(fFilename, fmOpenRead);
  4098. try
  4099. fs.Position := 0;
  4100. LoadFromStream(fs);
  4101. finally
  4102. fs.Free;
  4103. end;
  4104. end;
  4105. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4106. procedure TglBitmap.LoadFromStream(const aStream: TStream);
  4107. begin
  4108. {$IFDEF GLB_SUPPORT_PNG_READ}
  4109. if not LoadPNG(aStream) then
  4110. {$ENDIF}
  4111. {$IFDEF GLB_SUPPORT_JPEG_READ}
  4112. if not LoadJPEG(aStream) then
  4113. {$ENDIF}
  4114. if not LoadDDS(aStream) then
  4115. if not LoadTGA(aStream) then
  4116. if not LoadBMP(aStream) then
  4117. if not LoadRAW(aStream) then
  4118. raise EglBitmap.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
  4119. end;
  4120. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4121. procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
  4122. const aFormat: TglBitmapFormat; const aArgs: Pointer);
  4123. var
  4124. tmpData: PByte;
  4125. size: Integer;
  4126. begin
  4127. size := TFormatDescriptor.Get(aFormat).GetSize(aSize);
  4128. GetMem(tmpData, size);
  4129. try
  4130. FillChar(tmpData^, size, #$FF);
  4131. SetDataPointer(tmpData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
  4132. except
  4133. if Assigned(tmpData) then
  4134. FreeMem(tmpData);
  4135. raise;
  4136. end;
  4137. AddFunc(Self, aFunc, false, aFormat, aArgs);
  4138. end;
  4139. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4140. procedure TglBitmap.LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar);
  4141. var
  4142. rs: TResourceStream;
  4143. begin
  4144. PrepareResType(aResource, aResType);
  4145. rs := TResourceStream.Create(aInstance, aResource, aResType);
  4146. try
  4147. LoadFromStream(rs);
  4148. finally
  4149. rs.Free;
  4150. end;
  4151. end;
  4152. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4153. procedure TglBitmap.LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
  4154. var
  4155. rs: TResourceStream;
  4156. begin
  4157. rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
  4158. try
  4159. LoadFromStream(rs);
  4160. finally
  4161. rs.Free;
  4162. end;
  4163. end;
  4164. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4165. procedure TglBitmap.SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
  4166. var
  4167. fs: TFileStream;
  4168. begin
  4169. fs := TFileStream.Create(aFileName, fmCreate);
  4170. try
  4171. fs.Position := 0;
  4172. SaveToStream(fs, aFileType);
  4173. finally
  4174. fs.Free;
  4175. end;
  4176. end;
  4177. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4178. procedure TglBitmap.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
  4179. begin
  4180. case aFileType of
  4181. {$IFDEF GLB_SUPPORT_PNG_WRITE}
  4182. ftPNG: SavePNG(aStream);
  4183. {$ENDIF}
  4184. {$IFDEF GLB_SUPPORT_JPEG_WRITE}
  4185. ftJPEG: SaveJPEG(aStream);
  4186. {$ENDIF}
  4187. ftDDS: SaveDDS(aStream);
  4188. ftTGA: SaveTGA(aStream);
  4189. ftBMP: SaveBMP(aStream);
  4190. ftRAW: SaveRAW(aStream);
  4191. end;
  4192. end;
  4193. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4194. function TglBitmap.AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer): Boolean;
  4195. begin
  4196. result := AddFunc(Self, aFunc, aCreateTemp, Format, aArgs);
  4197. end;
  4198. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4199. function TglBitmap.AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
  4200. const aFormat: TglBitmapFormat; const aArgs: Pointer): Boolean;
  4201. var
  4202. DestData, TmpData, SourceData: pByte;
  4203. TempHeight, TempWidth: Integer;
  4204. SourceFD, DestFD: TFormatDescriptor;
  4205. SourceMD, DestMD: Pointer;
  4206. FuncRec: TglBitmapFunctionRec;
  4207. begin
  4208. Assert(Assigned(Data));
  4209. Assert(Assigned(aSource));
  4210. Assert(Assigned(aSource.Data));
  4211. result := false;
  4212. if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
  4213. SourceFD := TFormatDescriptor.Get(aSource.Format);
  4214. DestFD := TFormatDescriptor.Get(aFormat);
  4215. if (SourceFD.IsCompressed) then
  4216. raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', SourceFD.Format);
  4217. if (DestFD.IsCompressed) then
  4218. raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', DestFD.Format);
  4219. // inkompatible Formats so CreateTemp
  4220. if (SourceFD.BitsPerPixel <> DestFD.BitsPerPixel) then
  4221. aCreateTemp := true;
  4222. // Values
  4223. TempHeight := Max(1, aSource.Height);
  4224. TempWidth := Max(1, aSource.Width);
  4225. FuncRec.Sender := Self;
  4226. FuncRec.Args := aArgs;
  4227. TmpData := nil;
  4228. if aCreateTemp then begin
  4229. GetMem(TmpData, DestFD.GetSize(TempWidth, TempHeight));
  4230. DestData := TmpData;
  4231. end else
  4232. DestData := Data;
  4233. try
  4234. SourceFD.PreparePixel(FuncRec.Source);
  4235. DestFD.PreparePixel (FuncRec.Dest);
  4236. SourceMD := SourceFD.CreateMappingData;
  4237. DestMD := DestFD.CreateMappingData;
  4238. FuncRec.Size := aSource.Dimension;
  4239. FuncRec.Position.Fields := FuncRec.Size.Fields;
  4240. try
  4241. SourceData := aSource.Data;
  4242. FuncRec.Position.Y := 0;
  4243. while FuncRec.Position.Y < TempHeight do begin
  4244. FuncRec.Position.X := 0;
  4245. while FuncRec.Position.X < TempWidth do begin
  4246. SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
  4247. aFunc(FuncRec);
  4248. DestFD.Map(FuncRec.Dest, DestData, DestMD);
  4249. inc(FuncRec.Position.X);
  4250. end;
  4251. inc(FuncRec.Position.Y);
  4252. end;
  4253. // Updating Image or InternalFormat
  4254. if aCreateTemp then
  4255. SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height) //be careful, Data could be freed by this method
  4256. else if (aFormat <> fFormat) then
  4257. Format := aFormat;
  4258. result := true;
  4259. finally
  4260. SourceFD.FreeMappingData(SourceMD);
  4261. DestFD.FreeMappingData(DestMD);
  4262. end;
  4263. except
  4264. if aCreateTemp and Assigned(TmpData) then
  4265. FreeMem(TmpData);
  4266. raise;
  4267. end;
  4268. end;
  4269. end;
  4270. {$IFDEF GLB_SDL}
  4271. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4272. function TglBitmap.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
  4273. var
  4274. Row, RowSize: Integer;
  4275. SourceData, TmpData: PByte;
  4276. TempDepth: Integer;
  4277. FormatDesc: TFormatDescriptor;
  4278. function GetRowPointer(Row: Integer): pByte;
  4279. begin
  4280. result := aSurface.pixels;
  4281. Inc(result, Row * RowSize);
  4282. end;
  4283. begin
  4284. result := false;
  4285. FormatDesc := TFormatDescriptor.Get(Format);
  4286. if FormatDesc.IsCompressed then
  4287. raise EglBitmapUnsupportedFormat.Create(Format);
  4288. if Assigned(Data) then begin
  4289. case Trunc(FormatDesc.PixelSize) of
  4290. 1: TempDepth := 8;
  4291. 2: TempDepth := 16;
  4292. 3: TempDepth := 24;
  4293. 4: TempDepth := 32;
  4294. else
  4295. raise EglBitmapUnsupportedFormat.Create(Format);
  4296. end;
  4297. aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
  4298. FormatDesc.RedMask, FormatDesc.GreenMask, FormatDesc.BlueMask, FormatDesc.AlphaMask);
  4299. SourceData := Data;
  4300. RowSize := FormatDesc.GetSize(FileWidth, 1);
  4301. for Row := 0 to FileHeight-1 do begin
  4302. TmpData := GetRowPointer(Row);
  4303. if Assigned(TmpData) then begin
  4304. Move(SourceData^, TmpData^, RowSize);
  4305. inc(SourceData, RowSize);
  4306. end;
  4307. end;
  4308. result := true;
  4309. end;
  4310. end;
  4311. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4312. function TglBitmap.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
  4313. var
  4314. pSource, pData, pTempData: PByte;
  4315. Row, RowSize, TempWidth, TempHeight: Integer;
  4316. IntFormat: TglBitmapFormat;
  4317. fd: TFormatDescriptor;
  4318. Mask: TglBitmapMask;
  4319. function GetRowPointer(Row: Integer): pByte;
  4320. begin
  4321. result := aSurface^.pixels;
  4322. Inc(result, Row * RowSize);
  4323. end;
  4324. begin
  4325. result := false;
  4326. if (Assigned(aSurface)) then begin
  4327. with aSurface^.format^ do begin
  4328. Mask.r := RMask;
  4329. Mask.g := GMask;
  4330. Mask.b := BMask;
  4331. Mask.a := AMask;
  4332. IntFormat := TFormatDescriptor.GetFromMask(Mask).Format;
  4333. if (IntFormat = tfEmpty) then
  4334. raise EglBitmap.Create('AssignFromSurface - Invalid Pixelformat.');
  4335. end;
  4336. fd := TFormatDescriptor.Get(IntFormat);
  4337. TempWidth := aSurface^.w;
  4338. TempHeight := aSurface^.h;
  4339. RowSize := fd.GetSize(TempWidth, 1);
  4340. GetMem(pData, TempHeight * RowSize);
  4341. try
  4342. pTempData := pData;
  4343. for Row := 0 to TempHeight -1 do begin
  4344. pSource := GetRowPointer(Row);
  4345. if (Assigned(pSource)) then begin
  4346. Move(pSource^, pTempData^, RowSize);
  4347. Inc(pTempData, RowSize);
  4348. end;
  4349. end;
  4350. SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
  4351. result := true;
  4352. except
  4353. if Assigned(pData) then
  4354. FreeMem(pData);
  4355. raise;
  4356. end;
  4357. end;
  4358. end;
  4359. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4360. function TglBitmap.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
  4361. var
  4362. Row, Col, AlphaInterleave: Integer;
  4363. pSource, pDest: PByte;
  4364. function GetRowPointer(Row: Integer): pByte;
  4365. begin
  4366. result := aSurface.pixels;
  4367. Inc(result, Row * Width);
  4368. end;
  4369. begin
  4370. result := false;
  4371. if Assigned(Data) then begin
  4372. if Format in [tfAlpha8ub1, tfLuminance8Alpha8ub2, tfBGRA8ub4, tfRGBA8ub4] then begin
  4373. aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
  4374. AlphaInterleave := 0;
  4375. case Format of
  4376. tfLuminance8Alpha8ub2:
  4377. AlphaInterleave := 1;
  4378. tfBGRA8ub4, tfRGBA8ub4:
  4379. AlphaInterleave := 3;
  4380. end;
  4381. pSource := Data;
  4382. for Row := 0 to Height -1 do begin
  4383. pDest := GetRowPointer(Row);
  4384. if Assigned(pDest) then begin
  4385. for Col := 0 to Width -1 do begin
  4386. Inc(pSource, AlphaInterleave);
  4387. pDest^ := pSource^;
  4388. Inc(pDest);
  4389. Inc(pSource);
  4390. end;
  4391. end;
  4392. end;
  4393. result := true;
  4394. end;
  4395. end;
  4396. end;
  4397. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4398. function TglBitmap.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  4399. var
  4400. bmp: TglBitmap2D;
  4401. begin
  4402. bmp := TglBitmap2D.Create;
  4403. try
  4404. bmp.AssignFromSurface(aSurface);
  4405. result := AddAlphaFromGlBitmap(bmp, aFunc, aArgs);
  4406. finally
  4407. bmp.Free;
  4408. end;
  4409. end;
  4410. {$ENDIF}
  4411. {$IFDEF GLB_DELPHI}
  4412. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4413. function CreateGrayPalette: HPALETTE;
  4414. var
  4415. Idx: Integer;
  4416. Pal: PLogPalette;
  4417. begin
  4418. GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
  4419. Pal.palVersion := $300;
  4420. Pal.palNumEntries := 256;
  4421. for Idx := 0 to Pal.palNumEntries - 1 do begin
  4422. Pal.palPalEntry[Idx].peRed := Idx;
  4423. Pal.palPalEntry[Idx].peGreen := Idx;
  4424. Pal.palPalEntry[Idx].peBlue := Idx;
  4425. Pal.palPalEntry[Idx].peFlags := 0;
  4426. end;
  4427. Result := CreatePalette(Pal^);
  4428. FreeMem(Pal);
  4429. end;
  4430. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4431. function TglBitmap.AssignToBitmap(const aBitmap: TBitmap): Boolean;
  4432. var
  4433. Row: Integer;
  4434. pSource, pData: PByte;
  4435. begin
  4436. result := false;
  4437. if Assigned(Data) then begin
  4438. if Assigned(aBitmap) then begin
  4439. aBitmap.Width := Width;
  4440. aBitmap.Height := Height;
  4441. case Format of
  4442. tfAlpha8ub1, tfLuminance8ub1: begin
  4443. aBitmap.PixelFormat := pf8bit;
  4444. aBitmap.Palette := CreateGrayPalette;
  4445. end;
  4446. tfRGB5A1us1:
  4447. aBitmap.PixelFormat := pf15bit;
  4448. tfR5G6B5us1:
  4449. aBitmap.PixelFormat := pf16bit;
  4450. tfRGB8ub3, tfBGR8ub3:
  4451. aBitmap.PixelFormat := pf24bit;
  4452. tfRGBA8ub4, tfBGRA8ub4:
  4453. aBitmap.PixelFormat := pf32bit;
  4454. else
  4455. raise EglBitmap.Create('AssignToBitmap - Invalid Pixelformat.');
  4456. end;
  4457. pSource := Data;
  4458. for Row := 0 to FileHeight -1 do begin
  4459. pData := aBitmap.Scanline[Row];
  4460. Move(pSource^, pData^, fRowSize);
  4461. Inc(pSource, fRowSize);
  4462. if (Format in [tfRGB8ub3, tfRGBA8ub4]) then // swap RGB(A) to BGR(A)
  4463. SwapRGB(pData, FileWidth, Format = tfRGBA8ub4);
  4464. end;
  4465. result := true;
  4466. end;
  4467. end;
  4468. end;
  4469. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4470. function TglBitmap.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
  4471. var
  4472. pSource, pData, pTempData: PByte;
  4473. Row, RowSize, TempWidth, TempHeight: Integer;
  4474. IntFormat: TglBitmapFormat;
  4475. begin
  4476. result := false;
  4477. if (Assigned(aBitmap)) then begin
  4478. case aBitmap.PixelFormat of
  4479. pf8bit:
  4480. IntFormat := tfLuminance8ub1;
  4481. pf15bit:
  4482. IntFormat := tfRGB5A1us1;
  4483. pf16bit:
  4484. IntFormat := tfR5G6B5us1;
  4485. pf24bit:
  4486. IntFormat := tfBGR8ub3;
  4487. pf32bit:
  4488. IntFormat := tfBGRA8ub4;
  4489. else
  4490. raise EglBitmap.Create('AssignFromBitmap - Invalid Pixelformat.');
  4491. end;
  4492. TempWidth := aBitmap.Width;
  4493. TempHeight := aBitmap.Height;
  4494. RowSize := TFormatDescriptor.Get(IntFormat).GetSize(TempWidth, 1);
  4495. GetMem(pData, TempHeight * RowSize);
  4496. try
  4497. pTempData := pData;
  4498. for Row := 0 to TempHeight -1 do begin
  4499. pSource := aBitmap.Scanline[Row];
  4500. if (Assigned(pSource)) then begin
  4501. Move(pSource^, pTempData^, RowSize);
  4502. Inc(pTempData, RowSize);
  4503. end;
  4504. end;
  4505. SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
  4506. result := true;
  4507. except
  4508. if Assigned(pData) then
  4509. FreeMem(pData);
  4510. raise;
  4511. end;
  4512. end;
  4513. end;
  4514. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4515. function TglBitmap.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
  4516. var
  4517. Row, Col, AlphaInterleave: Integer;
  4518. pSource, pDest: PByte;
  4519. begin
  4520. result := false;
  4521. if Assigned(Data) then begin
  4522. if (Format in [tfAlpha8ub1, tfLuminance8Alpha8ub2, tfRGBA8ub4, tfBGRA8ub4]) then begin
  4523. if Assigned(aBitmap) then begin
  4524. aBitmap.PixelFormat := pf8bit;
  4525. aBitmap.Palette := CreateGrayPalette;
  4526. aBitmap.Width := Width;
  4527. aBitmap.Height := Height;
  4528. case Format of
  4529. tfLuminance8Alpha8ub2:
  4530. AlphaInterleave := 1;
  4531. tfRGBA8ub4, tfBGRA8ub4:
  4532. AlphaInterleave := 3;
  4533. else
  4534. AlphaInterleave := 0;
  4535. end;
  4536. // Copy Data
  4537. pSource := Data;
  4538. for Row := 0 to Height -1 do begin
  4539. pDest := aBitmap.Scanline[Row];
  4540. if Assigned(pDest) then begin
  4541. for Col := 0 to Width -1 do begin
  4542. Inc(pSource, AlphaInterleave);
  4543. pDest^ := pSource^;
  4544. Inc(pDest);
  4545. Inc(pSource);
  4546. end;
  4547. end;
  4548. end;
  4549. result := true;
  4550. end;
  4551. end;
  4552. end;
  4553. end;
  4554. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4555. function TglBitmap.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  4556. var
  4557. tex: TglBitmap2D;
  4558. begin
  4559. tex := TglBitmap2D.Create;
  4560. try
  4561. tex.AssignFromBitmap(ABitmap);
  4562. result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
  4563. finally
  4564. tex.Free;
  4565. end;
  4566. end;
  4567. {$ENDIF}
  4568. {$IFDEF GLB_LAZARUS}
  4569. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4570. function TglBitmap.AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
  4571. var
  4572. rid: TRawImageDescription;
  4573. FormatDesc: TFormatDescriptor;
  4574. begin
  4575. if not Assigned(Data) then
  4576. raise EglBitmap.Create('no pixel data assigned. load data before save');
  4577. result := false;
  4578. if not Assigned(aImage) or (Format = tfEmpty) then
  4579. exit;
  4580. FormatDesc := TFormatDescriptor.Get(Format);
  4581. if FormatDesc.IsCompressed then
  4582. exit;
  4583. FillChar(rid{%H-}, SizeOf(rid), 0);
  4584. if FormatDesc.IsGrayscale then
  4585. rid.Format := ricfGray
  4586. else
  4587. rid.Format := ricfRGBA;
  4588. rid.Width := Width;
  4589. rid.Height := Height;
  4590. rid.Depth := FormatDesc.BitsPerPixel;
  4591. rid.BitOrder := riboBitsInOrder;
  4592. rid.ByteOrder := riboLSBFirst;
  4593. rid.LineOrder := riloTopToBottom;
  4594. rid.LineEnd := rileTight;
  4595. rid.BitsPerPixel := FormatDesc.BitsPerPixel;
  4596. rid.RedPrec := CountSetBits(FormatDesc.Range.r);
  4597. rid.GreenPrec := CountSetBits(FormatDesc.Range.g);
  4598. rid.BluePrec := CountSetBits(FormatDesc.Range.b);
  4599. rid.AlphaPrec := CountSetBits(FormatDesc.Range.a);
  4600. rid.RedShift := FormatDesc.Shift.r;
  4601. rid.GreenShift := FormatDesc.Shift.g;
  4602. rid.BlueShift := FormatDesc.Shift.b;
  4603. rid.AlphaShift := FormatDesc.Shift.a;
  4604. rid.MaskBitsPerPixel := 0;
  4605. rid.PaletteColorCount := 0;
  4606. aImage.DataDescription := rid;
  4607. aImage.CreateData;
  4608. if not Assigned(aImage.PixelData) then
  4609. raise EglBitmap.Create('error while creating LazIntfImage');
  4610. Move(Data^, aImage.PixelData^, FormatDesc.GetSize(Dimension));
  4611. result := true;
  4612. end;
  4613. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4614. function TglBitmap.AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
  4615. var
  4616. f: TglBitmapFormat;
  4617. FormatDesc: TFormatDescriptor;
  4618. ImageData: PByte;
  4619. ImageSize: Integer;
  4620. CanCopy: Boolean;
  4621. Mask: TglBitmapRec4ul;
  4622. procedure CopyConvert;
  4623. var
  4624. bfFormat: TbmpBitfieldFormat;
  4625. pSourceLine, pDestLine: PByte;
  4626. pSourceMD, pDestMD: Pointer;
  4627. Shift, Prec: TglBitmapRec4ub;
  4628. x, y: Integer;
  4629. pixel: TglBitmapPixelData;
  4630. begin
  4631. bfFormat := TbmpBitfieldFormat.Create;
  4632. with aImage.DataDescription do begin
  4633. Prec.r := RedPrec;
  4634. Prec.g := GreenPrec;
  4635. Prec.b := BluePrec;
  4636. Prec.a := AlphaPrec;
  4637. Shift.r := RedShift;
  4638. Shift.g := GreenShift;
  4639. Shift.b := BlueShift;
  4640. Shift.a := AlphaShift;
  4641. bfFormat.SetCustomValues(BitsPerPixel, Prec, Shift);
  4642. end;
  4643. pSourceMD := bfFormat.CreateMappingData;
  4644. pDestMD := FormatDesc.CreateMappingData;
  4645. try
  4646. for y := 0 to aImage.Height-1 do begin
  4647. pSourceLine := aImage.PixelData + y {%H-}* aImage.DataDescription.BytesPerLine;
  4648. pDestLine := ImageData + y * Round(FormatDesc.BytesPerPixel * aImage.Width);
  4649. for x := 0 to aImage.Width-1 do begin
  4650. bfFormat.Unmap(pSourceLine, pixel, pSourceMD);
  4651. FormatDesc.Map(pixel, pDestLine, pDestMD);
  4652. end;
  4653. end;
  4654. finally
  4655. FormatDesc.FreeMappingData(pDestMD);
  4656. bfFormat.FreeMappingData(pSourceMD);
  4657. bfFormat.Free;
  4658. end;
  4659. end;
  4660. begin
  4661. result := false;
  4662. if not Assigned(aImage) then
  4663. exit;
  4664. with aImage.DataDescription do begin
  4665. Mask.r := (QWord(1 shl RedPrec )-1) shl RedShift;
  4666. Mask.g := (QWord(1 shl GreenPrec)-1) shl GreenShift;
  4667. Mask.b := (QWord(1 shl BluePrec )-1) shl BlueShift;
  4668. Mask.a := (QWord(1 shl AlphaPrec)-1) shl AlphaShift;
  4669. end;
  4670. FormatDesc := TFormatDescriptor.GetFromMask(Mask);
  4671. f := FormatDesc.Format;
  4672. if (f = tfEmpty) then
  4673. exit;
  4674. CanCopy :=
  4675. (FormatDesc.BitsPerPixel = aImage.DataDescription.Depth) and
  4676. (aImage.DataDescription.BitsPerPixel = aImage.DataDescription.Depth);
  4677. ImageSize := FormatDesc.GetSize(aImage.Width, aImage.Height);
  4678. ImageData := GetMem(ImageSize);
  4679. try
  4680. if CanCopy then
  4681. Move(aImage.PixelData^, ImageData^, ImageSize)
  4682. else
  4683. CopyConvert;
  4684. SetDataPointer(ImageData, f, aImage.Width, aImage.Height); //be careful, Data could be freed by this method
  4685. except
  4686. if Assigned(ImageData) then
  4687. FreeMem(ImageData);
  4688. raise;
  4689. end;
  4690. result := true;
  4691. end;
  4692. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4693. function TglBitmap.AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
  4694. var
  4695. rid: TRawImageDescription;
  4696. FormatDesc: TFormatDescriptor;
  4697. Pixel: TglBitmapPixelData;
  4698. x, y: Integer;
  4699. srcMD: Pointer;
  4700. src, dst: PByte;
  4701. begin
  4702. result := false;
  4703. if not Assigned(aImage) or (Format = tfEmpty) then
  4704. exit;
  4705. FormatDesc := TFormatDescriptor.Get(Format);
  4706. if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
  4707. exit;
  4708. FillChar(rid{%H-}, SizeOf(rid), 0);
  4709. rid.Format := ricfGray;
  4710. rid.Width := Width;
  4711. rid.Height := Height;
  4712. rid.Depth := CountSetBits(FormatDesc.Range.a);
  4713. rid.BitOrder := riboBitsInOrder;
  4714. rid.ByteOrder := riboLSBFirst;
  4715. rid.LineOrder := riloTopToBottom;
  4716. rid.LineEnd := rileTight;
  4717. rid.BitsPerPixel := 8 * Ceil(rid.Depth / 8);
  4718. rid.RedPrec := CountSetBits(FormatDesc.Range.a);
  4719. rid.GreenPrec := 0;
  4720. rid.BluePrec := 0;
  4721. rid.AlphaPrec := 0;
  4722. rid.RedShift := 0;
  4723. rid.GreenShift := 0;
  4724. rid.BlueShift := 0;
  4725. rid.AlphaShift := 0;
  4726. rid.MaskBitsPerPixel := 0;
  4727. rid.PaletteColorCount := 0;
  4728. aImage.DataDescription := rid;
  4729. aImage.CreateData;
  4730. srcMD := FormatDesc.CreateMappingData;
  4731. try
  4732. FormatDesc.PreparePixel(Pixel);
  4733. src := Data;
  4734. dst := aImage.PixelData;
  4735. for y := 0 to Height-1 do
  4736. for x := 0 to Width-1 do begin
  4737. FormatDesc.Unmap(src, Pixel, srcMD);
  4738. case rid.BitsPerPixel of
  4739. 8: begin
  4740. dst^ := Pixel.Data.a;
  4741. inc(dst);
  4742. end;
  4743. 16: begin
  4744. PWord(dst)^ := Pixel.Data.a;
  4745. inc(dst, 2);
  4746. end;
  4747. 24: begin
  4748. PByteArray(dst)^[0] := PByteArray(@Pixel.Data.a)^[0];
  4749. PByteArray(dst)^[1] := PByteArray(@Pixel.Data.a)^[1];
  4750. PByteArray(dst)^[2] := PByteArray(@Pixel.Data.a)^[2];
  4751. inc(dst, 3);
  4752. end;
  4753. 32: begin
  4754. PCardinal(dst)^ := Pixel.Data.a;
  4755. inc(dst, 4);
  4756. end;
  4757. else
  4758. raise EglBitmapUnsupportedFormat.Create(Format);
  4759. end;
  4760. end;
  4761. finally
  4762. FormatDesc.FreeMappingData(srcMD);
  4763. end;
  4764. result := true;
  4765. end;
  4766. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4767. function TglBitmap.AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  4768. var
  4769. tex: TglBitmap2D;
  4770. begin
  4771. tex := TglBitmap2D.Create;
  4772. try
  4773. tex.AssignFromLazIntfImage(aImage);
  4774. result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
  4775. finally
  4776. tex.Free;
  4777. end;
  4778. end;
  4779. {$ENDIF}
  4780. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4781. function TglBitmap.AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar;
  4782. const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  4783. var
  4784. rs: TResourceStream;
  4785. begin
  4786. PrepareResType(aResource, aResType);
  4787. rs := TResourceStream.Create(aInstance, aResource, aResType);
  4788. try
  4789. result := AddAlphaFromStream(rs, aFunc, aArgs);
  4790. finally
  4791. rs.Free;
  4792. end;
  4793. end;
  4794. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4795. function TglBitmap.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
  4796. const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  4797. var
  4798. rs: TResourceStream;
  4799. begin
  4800. rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
  4801. try
  4802. result := AddAlphaFromStream(rs, aFunc, aArgs);
  4803. finally
  4804. rs.Free;
  4805. end;
  4806. end;
  4807. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4808. function TglBitmap.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  4809. begin
  4810. if TFormatDescriptor.Get(Format).IsCompressed then
  4811. raise EglBitmapUnsupportedFormat.Create(Format);
  4812. result := AddFunc(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs);
  4813. end;
  4814. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4815. function TglBitmap.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  4816. var
  4817. FS: TFileStream;
  4818. begin
  4819. FS := TFileStream.Create(aFileName, fmOpenRead);
  4820. try
  4821. result := AddAlphaFromStream(FS, aFunc, aArgs);
  4822. finally
  4823. FS.Free;
  4824. end;
  4825. end;
  4826. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4827. function TglBitmap.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  4828. var
  4829. tex: TglBitmap2D;
  4830. begin
  4831. tex := TglBitmap2D.Create(aStream);
  4832. try
  4833. result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
  4834. finally
  4835. tex.Free;
  4836. end;
  4837. end;
  4838. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4839. function TglBitmap.AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  4840. var
  4841. DestData, DestData2, SourceData: pByte;
  4842. TempHeight, TempWidth: Integer;
  4843. SourceFD, DestFD: TFormatDescriptor;
  4844. SourceMD, DestMD, DestMD2: Pointer;
  4845. FuncRec: TglBitmapFunctionRec;
  4846. begin
  4847. result := false;
  4848. Assert(Assigned(Data));
  4849. Assert(Assigned(aBitmap));
  4850. Assert(Assigned(aBitmap.Data));
  4851. if ((aBitmap.Width = Width) and (aBitmap.Height = Height)) then begin
  4852. result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
  4853. SourceFD := TFormatDescriptor.Get(aBitmap.Format);
  4854. DestFD := TFormatDescriptor.Get(Format);
  4855. if not Assigned(aFunc) then begin
  4856. aFunc := glBitmapAlphaFunc;
  4857. FuncRec.Args := {%H-}Pointer(SourceFD.HasAlpha);
  4858. end else
  4859. FuncRec.Args := aArgs;
  4860. // Values
  4861. TempHeight := aBitmap.FileHeight;
  4862. TempWidth := aBitmap.FileWidth;
  4863. FuncRec.Sender := Self;
  4864. FuncRec.Size := Dimension;
  4865. FuncRec.Position.Fields := FuncRec.Size.Fields;
  4866. DestData := Data;
  4867. DestData2 := Data;
  4868. SourceData := aBitmap.Data;
  4869. // Mapping
  4870. SourceFD.PreparePixel(FuncRec.Source);
  4871. DestFD.PreparePixel (FuncRec.Dest);
  4872. SourceMD := SourceFD.CreateMappingData;
  4873. DestMD := DestFD.CreateMappingData;
  4874. DestMD2 := DestFD.CreateMappingData;
  4875. try
  4876. FuncRec.Position.Y := 0;
  4877. while FuncRec.Position.Y < TempHeight do begin
  4878. FuncRec.Position.X := 0;
  4879. while FuncRec.Position.X < TempWidth do begin
  4880. SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
  4881. DestFD.Unmap (DestData, FuncRec.Dest, DestMD);
  4882. aFunc(FuncRec);
  4883. DestFD.Map(FuncRec.Dest, DestData2, DestMD2);
  4884. inc(FuncRec.Position.X);
  4885. end;
  4886. inc(FuncRec.Position.Y);
  4887. end;
  4888. finally
  4889. SourceFD.FreeMappingData(SourceMD);
  4890. DestFD.FreeMappingData(DestMD);
  4891. DestFD.FreeMappingData(DestMD2);
  4892. end;
  4893. end;
  4894. end;
  4895. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4896. function TglBitmap.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
  4897. begin
  4898. result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
  4899. end;
  4900. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4901. function TglBitmap.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
  4902. var
  4903. PixelData: TglBitmapPixelData;
  4904. begin
  4905. TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
  4906. result := AddAlphaFromColorKeyFloat(
  4907. aRed / PixelData.Range.r,
  4908. aGreen / PixelData.Range.g,
  4909. aBlue / PixelData.Range.b,
  4910. aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b)));
  4911. end;
  4912. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4913. function TglBitmap.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
  4914. var
  4915. values: array[0..2] of Single;
  4916. tmp: Cardinal;
  4917. i: Integer;
  4918. PixelData: TglBitmapPixelData;
  4919. begin
  4920. TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
  4921. with PixelData do begin
  4922. values[0] := aRed;
  4923. values[1] := aGreen;
  4924. values[2] := aBlue;
  4925. for i := 0 to 2 do begin
  4926. tmp := Trunc(Range.arr[i] * aDeviation);
  4927. Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp));
  4928. Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp));
  4929. end;
  4930. Data.a := 0;
  4931. Range.a := 0;
  4932. end;
  4933. result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, @PixelData);
  4934. end;
  4935. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4936. function TglBitmap.AddAlphaFromValue(const aAlpha: Byte): Boolean;
  4937. begin
  4938. result := AddAlphaFromValueFloat(aAlpha / $FF);
  4939. end;
  4940. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4941. function TglBitmap.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
  4942. var
  4943. PixelData: TglBitmapPixelData;
  4944. begin
  4945. TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
  4946. result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
  4947. end;
  4948. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4949. function TglBitmap.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
  4950. var
  4951. PixelData: TglBitmapPixelData;
  4952. begin
  4953. TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
  4954. with PixelData do
  4955. Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
  4956. result := AddAlphaFromFunc(glBitmapValueAlphaFunc, @PixelData.Data.a);
  4957. end;
  4958. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4959. function TglBitmap.RemoveAlpha: Boolean;
  4960. var
  4961. FormatDesc: TFormatDescriptor;
  4962. begin
  4963. result := false;
  4964. FormatDesc := TFormatDescriptor.Get(Format);
  4965. if Assigned(Data) then begin
  4966. if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
  4967. raise EglBitmapUnsupportedFormat.Create(Format);
  4968. result := ConvertTo(FormatDesc.WithoutAlpha);
  4969. end;
  4970. end;
  4971. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4972. function TglBitmap.Clone: TglBitmap;
  4973. var
  4974. Temp: TglBitmap;
  4975. TempPtr: PByte;
  4976. Size: Integer;
  4977. begin
  4978. result := nil;
  4979. Temp := (ClassType.Create as TglBitmap);
  4980. try
  4981. // copy texture data if assigned
  4982. if Assigned(Data) then begin
  4983. Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
  4984. GetMem(TempPtr, Size);
  4985. try
  4986. Move(Data^, TempPtr^, Size);
  4987. Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
  4988. except
  4989. if Assigned(TempPtr) then
  4990. FreeMem(TempPtr);
  4991. raise;
  4992. end;
  4993. end else begin
  4994. TempPtr := nil;
  4995. Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
  4996. end;
  4997. // copy properties
  4998. Temp.fID := ID;
  4999. Temp.fTarget := Target;
  5000. Temp.fFormat := Format;
  5001. Temp.fMipMap := MipMap;
  5002. Temp.fAnisotropic := Anisotropic;
  5003. Temp.fBorderColor := fBorderColor;
  5004. Temp.fDeleteTextureOnFree := DeleteTextureOnFree;
  5005. Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
  5006. Temp.fFilterMin := fFilterMin;
  5007. Temp.fFilterMag := fFilterMag;
  5008. Temp.fWrapS := fWrapS;
  5009. Temp.fWrapT := fWrapT;
  5010. Temp.fWrapR := fWrapR;
  5011. Temp.fFilename := fFilename;
  5012. Temp.fCustomName := fCustomName;
  5013. Temp.fCustomNameW := fCustomNameW;
  5014. Temp.fCustomData := fCustomData;
  5015. result := Temp;
  5016. except
  5017. FreeAndNil(Temp);
  5018. raise;
  5019. end;
  5020. end;
  5021. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5022. function TglBitmap.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
  5023. var
  5024. SourceFD, DestFD: TFormatDescriptor;
  5025. SourcePD, DestPD: TglBitmapPixelData;
  5026. ShiftData: TShiftData;
  5027. function DataIsIdentical: Boolean;
  5028. begin
  5029. result := SourceFD.MaskMatch(DestFD.Mask);
  5030. end;
  5031. function CanCopyDirect: Boolean;
  5032. begin
  5033. result :=
  5034. ((SourcePD.Range.r = DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
  5035. ((SourcePD.Range.g = DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
  5036. ((SourcePD.Range.b = DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
  5037. ((SourcePD.Range.a = DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
  5038. end;
  5039. function CanShift: Boolean;
  5040. begin
  5041. result :=
  5042. ((SourcePD.Range.r >= DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
  5043. ((SourcePD.Range.g >= DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
  5044. ((SourcePD.Range.b >= DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
  5045. ((SourcePD.Range.a >= DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
  5046. end;
  5047. function GetShift(aSource, aDest: Cardinal) : ShortInt;
  5048. begin
  5049. result := 0;
  5050. while (aSource > aDest) and (aSource > 0) do begin
  5051. inc(result);
  5052. aSource := aSource shr 1;
  5053. end;
  5054. end;
  5055. begin
  5056. if (aFormat <> fFormat) and (aFormat <> tfEmpty) then begin
  5057. SourceFD := TFormatDescriptor.Get(Format);
  5058. DestFD := TFormatDescriptor.Get(aFormat);
  5059. if DataIsIdentical then begin
  5060. result := true;
  5061. Format := aFormat;
  5062. exit;
  5063. end;
  5064. SourceFD.PreparePixel(SourcePD);
  5065. DestFD.PreparePixel (DestPD);
  5066. if CanCopyDirect then
  5067. result := AddFunc(Self, glBitmapConvertCopyFunc, false, aFormat)
  5068. else if CanShift then begin
  5069. ShiftData.r := GetShift(SourcePD.Range.r, DestPD.Range.r);
  5070. ShiftData.g := GetShift(SourcePD.Range.g, DestPD.Range.g);
  5071. ShiftData.b := GetShift(SourcePD.Range.b, DestPD.Range.b);
  5072. ShiftData.a := GetShift(SourcePD.Range.a, DestPD.Range.a);
  5073. result := AddFunc(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, @ShiftData);
  5074. end else
  5075. result := AddFunc(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
  5076. end else
  5077. result := true;
  5078. end;
  5079. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5080. procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
  5081. begin
  5082. if aUseRGB or aUseAlpha then
  5083. AddFunc(glBitmapInvertFunc, false, {%H-}Pointer(
  5084. ((Byte(aUseAlpha) and 1) shl 1) or
  5085. (Byte(aUseRGB) and 1) ));
  5086. end;
  5087. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5088. procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
  5089. begin
  5090. fBorderColor[0] := aRed;
  5091. fBorderColor[1] := aGreen;
  5092. fBorderColor[2] := aBlue;
  5093. fBorderColor[3] := aAlpha;
  5094. if (ID > 0) then begin
  5095. Bind(false);
  5096. glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
  5097. end;
  5098. end;
  5099. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5100. procedure TglBitmap.FreeData;
  5101. var
  5102. TempPtr: PByte;
  5103. begin
  5104. TempPtr := nil;
  5105. SetDataPointer(TempPtr, tfEmpty); //be careful, Data could be freed by this method
  5106. end;
  5107. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5108. procedure TglBitmap.FillWithColor(const aRed, aGreen, aBlue: Byte;
  5109. const aAlpha: Byte);
  5110. begin
  5111. FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
  5112. end;
  5113. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5114. procedure TglBitmap.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
  5115. var
  5116. PixelData: TglBitmapPixelData;
  5117. begin
  5118. TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
  5119. FillWithColorFloat(
  5120. aRed / PixelData.Range.r,
  5121. aGreen / PixelData.Range.g,
  5122. aBlue / PixelData.Range.b,
  5123. aAlpha / PixelData.Range.a);
  5124. end;
  5125. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5126. procedure TglBitmap.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
  5127. var
  5128. PixelData: TglBitmapPixelData;
  5129. begin
  5130. TFormatDescriptor.Get(Format).PreparePixel(PixelData);
  5131. with PixelData do begin
  5132. Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed)));
  5133. Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen)));
  5134. Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue)));
  5135. Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha)));
  5136. end;
  5137. AddFunc(glBitmapFillWithColorFunc, false, @PixelData);
  5138. end;
  5139. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5140. procedure TglBitmap.SetFilter(const aMin, aMag: GLenum);
  5141. begin
  5142. //check MIN filter
  5143. case aMin of
  5144. GL_NEAREST:
  5145. fFilterMin := GL_NEAREST;
  5146. GL_LINEAR:
  5147. fFilterMin := GL_LINEAR;
  5148. GL_NEAREST_MIPMAP_NEAREST:
  5149. fFilterMin := GL_NEAREST_MIPMAP_NEAREST;
  5150. GL_LINEAR_MIPMAP_NEAREST:
  5151. fFilterMin := GL_LINEAR_MIPMAP_NEAREST;
  5152. GL_NEAREST_MIPMAP_LINEAR:
  5153. fFilterMin := GL_NEAREST_MIPMAP_LINEAR;
  5154. GL_LINEAR_MIPMAP_LINEAR:
  5155. fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
  5156. else
  5157. raise EglBitmap.Create('SetFilter - Unknow MIN filter.');
  5158. end;
  5159. //check MAG filter
  5160. case aMag of
  5161. GL_NEAREST:
  5162. fFilterMag := GL_NEAREST;
  5163. GL_LINEAR:
  5164. fFilterMag := GL_LINEAR;
  5165. else
  5166. raise EglBitmap.Create('SetFilter - Unknow MAG filter.');
  5167. end;
  5168. //apply filter
  5169. if (ID > 0) then begin
  5170. Bind(false);
  5171. glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
  5172. if (MipMap = mmNone) or (Target = GL_TEXTURE_RECTANGLE) then begin
  5173. case fFilterMin of
  5174. GL_NEAREST, GL_LINEAR:
  5175. glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
  5176. GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR:
  5177. glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  5178. GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR:
  5179. glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  5180. end;
  5181. end else
  5182. glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
  5183. end;
  5184. end;
  5185. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5186. procedure TglBitmap.SetWrap(const S: GLenum; const T: GLenum; const R: GLenum);
  5187. procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
  5188. begin
  5189. case aValue of
  5190. GL_CLAMP:
  5191. aTarget := GL_CLAMP;
  5192. GL_REPEAT:
  5193. aTarget := GL_REPEAT;
  5194. GL_CLAMP_TO_EDGE: begin
  5195. if GL_VERSION_1_2 or GL_EXT_texture_edge_clamp then
  5196. aTarget := GL_CLAMP_TO_EDGE
  5197. else
  5198. aTarget := GL_CLAMP;
  5199. end;
  5200. GL_CLAMP_TO_BORDER: begin
  5201. if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
  5202. aTarget := GL_CLAMP_TO_BORDER
  5203. else
  5204. aTarget := GL_CLAMP;
  5205. end;
  5206. GL_MIRRORED_REPEAT: begin
  5207. if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
  5208. aTarget := GL_MIRRORED_REPEAT
  5209. else
  5210. raise EglBitmap.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
  5211. end;
  5212. else
  5213. raise EglBitmap.Create('SetWrap - Unknow Texturewrap');
  5214. end;
  5215. end;
  5216. begin
  5217. CheckAndSetWrap(S, fWrapS);
  5218. CheckAndSetWrap(T, fWrapT);
  5219. CheckAndSetWrap(R, fWrapR);
  5220. if (ID > 0) then begin
  5221. Bind(false);
  5222. glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
  5223. glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
  5224. glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
  5225. end;
  5226. end;
  5227. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5228. procedure TglBitmap.SetSwizzle(const r, g, b, a: GLenum);
  5229. procedure CheckAndSetValue(const aValue: GLenum; const aIndex: Integer);
  5230. begin
  5231. if (aValue = GL_ZERO) or (aValue = GL_ONE) or (aValue = GL_ALPHA) or
  5232. (aValue = GL_RED) or (aValue = GL_GREEN) or (aValue = GL_BLUE) then
  5233. fSwizzle[aIndex] := aValue
  5234. else
  5235. raise EglBitmap.Create('SetSwizzle - Unknow Swizle Value');
  5236. end;
  5237. begin
  5238. if not (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
  5239. raise EglBitmapNotSupported.Create('texture swizzle is not supported');
  5240. CheckAndSetValue(r, 0);
  5241. CheckAndSetValue(g, 1);
  5242. CheckAndSetValue(b, 2);
  5243. CheckAndSetValue(a, 3);
  5244. if (ID > 0) then begin
  5245. Bind(false);
  5246. glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_RGBA, PGLint(@fSwizzle[0]));
  5247. end;
  5248. end;
  5249. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5250. procedure TglBitmap.Bind(const aEnableTextureUnit: Boolean);
  5251. begin
  5252. if aEnableTextureUnit then
  5253. glEnable(Target);
  5254. if (ID > 0) then
  5255. glBindTexture(Target, ID);
  5256. end;
  5257. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5258. procedure TglBitmap.Unbind(const aDisableTextureUnit: Boolean);
  5259. begin
  5260. if aDisableTextureUnit then
  5261. glDisable(Target);
  5262. glBindTexture(Target, 0);
  5263. end;
  5264. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5265. constructor TglBitmap.Create;
  5266. begin
  5267. if (ClassType = TglBitmap) then
  5268. raise EglBitmap.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
  5269. {$IFDEF GLB_NATIVE_OGL}
  5270. glbReadOpenGLExtensions;
  5271. {$ENDIF}
  5272. inherited Create;
  5273. fFormat := glBitmapGetDefaultFormat;
  5274. fFreeDataOnDestroy := true;
  5275. end;
  5276. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5277. constructor TglBitmap.Create(const aFileName: String);
  5278. begin
  5279. Create;
  5280. LoadFromFile(aFileName);
  5281. end;
  5282. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5283. constructor TglBitmap.Create(const aStream: TStream);
  5284. begin
  5285. Create;
  5286. LoadFromStream(aStream);
  5287. end;
  5288. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5289. constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; aData: PByte);
  5290. var
  5291. ImageSize: Integer;
  5292. begin
  5293. Create;
  5294. if not Assigned(aData) then begin
  5295. ImageSize := TFormatDescriptor.Get(aFormat).GetSize(aSize);
  5296. GetMem(aData, ImageSize);
  5297. try
  5298. FillChar(aData^, ImageSize, #$FF);
  5299. SetDataPointer(aData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
  5300. except
  5301. if Assigned(aData) then
  5302. FreeMem(aData);
  5303. raise;
  5304. end;
  5305. end else begin
  5306. SetDataPointer(aData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
  5307. fFreeDataOnDestroy := false;
  5308. end;
  5309. end;
  5310. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5311. constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer);
  5312. begin
  5313. Create;
  5314. LoadFromFunc(aSize, aFunc, aFormat, aArgs);
  5315. end;
  5316. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5317. constructor TglBitmap.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
  5318. begin
  5319. Create;
  5320. LoadFromResource(aInstance, aResource, aResType);
  5321. end;
  5322. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5323. constructor TglBitmap.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
  5324. begin
  5325. Create;
  5326. LoadFromResourceID(aInstance, aResourceID, aResType);
  5327. end;
  5328. {$IFDEF GLB_SUPPORT_PNG_READ}
  5329. {$IF DEFINED(GLB_LAZ_PNG)}
  5330. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5331. //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5332. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5333. function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
  5334. const
  5335. MAGIC_LEN = 8;
  5336. PNG_MAGIC: String[MAGIC_LEN] = #$89#$50#$4E#$47#$0D#$0A#$1A#$0A;
  5337. var
  5338. reader: TLazReaderPNG;
  5339. intf: TLazIntfImage;
  5340. StreamPos: Int64;
  5341. magic: String[MAGIC_LEN];
  5342. begin
  5343. result := true;
  5344. StreamPos := aStream.Position;
  5345. SetLength(magic, MAGIC_LEN);
  5346. aStream.Read(magic[1], MAGIC_LEN);
  5347. aStream.Position := StreamPos;
  5348. if (magic <> PNG_MAGIC) then begin
  5349. result := false;
  5350. exit;
  5351. end;
  5352. intf := TLazIntfImage.Create(0, 0);
  5353. reader := TLazReaderPNG.Create;
  5354. try try
  5355. reader.UpdateDescription := true;
  5356. reader.ImageRead(aStream, intf);
  5357. AssignFromLazIntfImage(intf);
  5358. except
  5359. result := false;
  5360. aStream.Position := StreamPos;
  5361. exit;
  5362. end;
  5363. finally
  5364. reader.Free;
  5365. intf.Free;
  5366. end;
  5367. end;
  5368. {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
  5369. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5370. function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
  5371. var
  5372. Surface: PSDL_Surface;
  5373. RWops: PSDL_RWops;
  5374. begin
  5375. result := false;
  5376. RWops := glBitmapCreateRWops(aStream);
  5377. try
  5378. if IMG_isPNG(RWops) > 0 then begin
  5379. Surface := IMG_LoadPNG_RW(RWops);
  5380. try
  5381. AssignFromSurface(Surface);
  5382. result := true;
  5383. finally
  5384. SDL_FreeSurface(Surface);
  5385. end;
  5386. end;
  5387. finally
  5388. SDL_FreeRW(RWops);
  5389. end;
  5390. end;
  5391. {$ELSEIF DEFINED(GLB_LIB_PNG)}
  5392. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5393. procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
  5394. begin
  5395. TStream(png_get_io_ptr(png)).Read(buffer^, size);
  5396. end;
  5397. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5398. function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
  5399. var
  5400. StreamPos: Int64;
  5401. signature: array [0..7] of byte;
  5402. png: png_structp;
  5403. png_info: png_infop;
  5404. TempHeight, TempWidth: Integer;
  5405. Format: TglBitmapFormat;
  5406. png_data: pByte;
  5407. png_rows: array of pByte;
  5408. Row, LineSize: Integer;
  5409. begin
  5410. result := false;
  5411. if not init_libPNG then
  5412. raise Exception.Create('LoadPNG - unable to initialize libPNG.');
  5413. try
  5414. // signature
  5415. StreamPos := aStream.Position;
  5416. aStream.Read(signature{%H-}, 8);
  5417. aStream.Position := StreamPos;
  5418. if png_check_sig(@signature, 8) <> 0 then begin
  5419. // png read struct
  5420. png := png_create_read_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
  5421. if png = nil then
  5422. raise EglBitmapException.Create('LoadPng - couldn''t create read struct.');
  5423. // png info
  5424. png_info := png_create_info_struct(png);
  5425. if png_info = nil then begin
  5426. png_destroy_read_struct(@png, nil, nil);
  5427. raise EglBitmapException.Create('LoadPng - couldn''t create info struct.');
  5428. end;
  5429. // set read callback
  5430. png_set_read_fn(png, aStream, glBitmap_libPNG_read_func);
  5431. // read informations
  5432. png_read_info(png, png_info);
  5433. // size
  5434. TempHeight := png_get_image_height(png, png_info);
  5435. TempWidth := png_get_image_width(png, png_info);
  5436. // format
  5437. case png_get_color_type(png, png_info) of
  5438. PNG_COLOR_TYPE_GRAY:
  5439. Format := tfLuminance8ub1;
  5440. PNG_COLOR_TYPE_GRAY_ALPHA:
  5441. Format := tfLuminance8Alpha8us1;
  5442. PNG_COLOR_TYPE_RGB:
  5443. Format := tfRGB8ub3;
  5444. PNG_COLOR_TYPE_RGB_ALPHA:
  5445. Format := tfRGBA8ub4;
  5446. else
  5447. raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
  5448. end;
  5449. // cut upper 8 bit from 16 bit formats
  5450. if png_get_bit_depth(png, png_info) > 8 then
  5451. png_set_strip_16(png);
  5452. // expand bitdepth smaller than 8
  5453. if png_get_bit_depth(png, png_info) < 8 then
  5454. png_set_expand(png);
  5455. // allocating mem for scanlines
  5456. LineSize := png_get_rowbytes(png, png_info);
  5457. GetMem(png_data, TempHeight * LineSize);
  5458. try
  5459. SetLength(png_rows, TempHeight);
  5460. for Row := Low(png_rows) to High(png_rows) do begin
  5461. png_rows[Row] := png_data;
  5462. Inc(png_rows[Row], Row * LineSize);
  5463. end;
  5464. // read complete image into scanlines
  5465. png_read_image(png, @png_rows[0]);
  5466. // read end
  5467. png_read_end(png, png_info);
  5468. // destroy read struct
  5469. png_destroy_read_struct(@png, @png_info, nil);
  5470. SetLength(png_rows, 0);
  5471. // set new data
  5472. SetDataPointer(png_data, Format, TempWidth, TempHeight); //be careful, Data could be freed by this method
  5473. result := true;
  5474. except
  5475. if Assigned(png_data) then
  5476. FreeMem(png_data);
  5477. raise;
  5478. end;
  5479. end;
  5480. finally
  5481. quit_libPNG;
  5482. end;
  5483. end;
  5484. {$ELSEIF DEFINED(GLB_PNGIMAGE)}
  5485. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5486. function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
  5487. var
  5488. StreamPos: Int64;
  5489. Png: TPNGObject;
  5490. Header: String[8];
  5491. Row, Col, PixSize, LineSize: Integer;
  5492. NewImage, pSource, pDest, pAlpha: pByte;
  5493. PngFormat: TglBitmapFormat;
  5494. FormatDesc: TFormatDescriptor;
  5495. const
  5496. PngHeader: String[8] = #137#80#78#71#13#10#26#10;
  5497. begin
  5498. result := false;
  5499. StreamPos := aStream.Position;
  5500. aStream.Read(Header[0], SizeOf(Header));
  5501. aStream.Position := StreamPos;
  5502. {Test if the header matches}
  5503. if Header = PngHeader then begin
  5504. Png := TPNGObject.Create;
  5505. try
  5506. Png.LoadFromStream(aStream);
  5507. case Png.Header.ColorType of
  5508. COLOR_GRAYSCALE:
  5509. PngFormat := tfLuminance8ub1;
  5510. COLOR_GRAYSCALEALPHA:
  5511. PngFormat := tfLuminance8Alpha8us1;
  5512. COLOR_RGB:
  5513. PngFormat := tfBGR8ub3;
  5514. COLOR_RGBALPHA:
  5515. PngFormat := tfBGRA8ub4;
  5516. else
  5517. raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
  5518. end;
  5519. FormatDesc := TFormatDescriptor.Get(PngFormat);
  5520. PixSize := Round(FormatDesc.PixelSize);
  5521. LineSize := FormatDesc.GetSize(Png.Header.Width, 1);
  5522. GetMem(NewImage, LineSize * Integer(Png.Header.Height));
  5523. try
  5524. pDest := NewImage;
  5525. case Png.Header.ColorType of
  5526. COLOR_RGB, COLOR_GRAYSCALE:
  5527. begin
  5528. for Row := 0 to Png.Height -1 do begin
  5529. Move (Png.Scanline[Row]^, pDest^, LineSize);
  5530. Inc(pDest, LineSize);
  5531. end;
  5532. end;
  5533. COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA:
  5534. begin
  5535. PixSize := PixSize -1;
  5536. for Row := 0 to Png.Height -1 do begin
  5537. pSource := Png.Scanline[Row];
  5538. pAlpha := pByte(Png.AlphaScanline[Row]);
  5539. for Col := 0 to Png.Width -1 do begin
  5540. Move (pSource^, pDest^, PixSize);
  5541. Inc(pSource, PixSize);
  5542. Inc(pDest, PixSize);
  5543. pDest^ := pAlpha^;
  5544. inc(pAlpha);
  5545. Inc(pDest);
  5546. end;
  5547. end;
  5548. end;
  5549. else
  5550. raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
  5551. end;
  5552. SetDataPointer(NewImage, PngFormat, Png.Header.Width, Png.Header.Height); //be careful, Data could be freed by this method
  5553. result := true;
  5554. except
  5555. if Assigned(NewImage) then
  5556. FreeMem(NewImage);
  5557. raise;
  5558. end;
  5559. finally
  5560. Png.Free;
  5561. end;
  5562. end;
  5563. end;
  5564. {$IFEND}
  5565. {$ENDIF}
  5566. {$IFDEF GLB_SUPPORT_PNG_WRITE}
  5567. {$IFDEF GLB_LIB_PNG}
  5568. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5569. procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
  5570. begin
  5571. TStream(png_get_io_ptr(png)).Write(buffer^, size);
  5572. end;
  5573. {$ENDIF}
  5574. {$IF DEFINED(GLB_LAZ_PNG)}
  5575. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5576. procedure TglBitmap.SavePNG(const aStream: TStream);
  5577. var
  5578. png: TPortableNetworkGraphic;
  5579. intf: TLazIntfImage;
  5580. raw: TRawImage;
  5581. begin
  5582. png := TPortableNetworkGraphic.Create;
  5583. intf := TLazIntfImage.Create(0, 0);
  5584. try
  5585. if not AssignToLazIntfImage(intf) then
  5586. raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
  5587. intf.GetRawImage(raw);
  5588. png.LoadFromRawImage(raw, false);
  5589. png.SaveToStream(aStream);
  5590. finally
  5591. png.Free;
  5592. intf.Free;
  5593. end;
  5594. end;
  5595. {$ELSEIF DEFINED(GLB_LIB_PNG)}
  5596. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5597. procedure TglBitmap.SavePNG(const aStream: TStream);
  5598. var
  5599. png: png_structp;
  5600. png_info: png_infop;
  5601. png_rows: array of pByte;
  5602. LineSize: Integer;
  5603. ColorType: Integer;
  5604. Row: Integer;
  5605. FormatDesc: TFormatDescriptor;
  5606. begin
  5607. if not (ftPNG in FormatGetSupportedFiles(Format)) then
  5608. raise EglBitmapUnsupportedFormat.Create(Format);
  5609. if not init_libPNG then
  5610. raise Exception.Create('unable to initialize libPNG.');
  5611. try
  5612. case Format of
  5613. tfAlpha8ub1, tfLuminance8ub1:
  5614. ColorType := PNG_COLOR_TYPE_GRAY;
  5615. tfLuminance8Alpha8us1:
  5616. ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
  5617. tfBGR8ub3, tfRGB8ub3:
  5618. ColorType := PNG_COLOR_TYPE_RGB;
  5619. tfBGRA8ub4, tfRGBA8ub4:
  5620. ColorType := PNG_COLOR_TYPE_RGBA;
  5621. else
  5622. raise EglBitmapUnsupportedFormat.Create(Format);
  5623. end;
  5624. FormatDesc := TFormatDescriptor.Get(Format);
  5625. LineSize := FormatDesc.GetSize(Width, 1);
  5626. // creating array for scanline
  5627. SetLength(png_rows, Height);
  5628. try
  5629. for Row := 0 to Height - 1 do begin
  5630. png_rows[Row] := Data;
  5631. Inc(png_rows[Row], Row * LineSize)
  5632. end;
  5633. // write struct
  5634. png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
  5635. if png = nil then
  5636. raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
  5637. // create png info
  5638. png_info := png_create_info_struct(png);
  5639. if png_info = nil then begin
  5640. png_destroy_write_struct(@png, nil);
  5641. raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
  5642. end;
  5643. // set read callback
  5644. png_set_write_fn(png, aStream, glBitmap_libPNG_write_func, nil);
  5645. // set compression
  5646. png_set_compression_level(png, 6);
  5647. if Format in [tfBGR8ub3, tfBGRA8ub4] then
  5648. png_set_bgr(png);
  5649. png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
  5650. png_write_info(png, png_info);
  5651. png_write_image(png, @png_rows[0]);
  5652. png_write_end(png, png_info);
  5653. png_destroy_write_struct(@png, @png_info);
  5654. finally
  5655. SetLength(png_rows, 0);
  5656. end;
  5657. finally
  5658. quit_libPNG;
  5659. end;
  5660. end;
  5661. {$ELSEIF DEFINED(GLB_PNGIMAGE)}
  5662. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5663. procedure TglBitmap.SavePNG(const aStream: TStream);
  5664. var
  5665. Png: TPNGObject;
  5666. pSource, pDest: pByte;
  5667. X, Y, PixSize: Integer;
  5668. ColorType: Cardinal;
  5669. Alpha: Boolean;
  5670. pTemp: pByte;
  5671. Temp: Byte;
  5672. begin
  5673. if not (ftPNG in FormatGetSupportedFiles (Format)) then
  5674. raise EglBitmapUnsupportedFormat.Create(Format);
  5675. case Format of
  5676. tfAlpha8ub1, tfLuminance8ub1: begin
  5677. ColorType := COLOR_GRAYSCALE;
  5678. PixSize := 1;
  5679. Alpha := false;
  5680. end;
  5681. tfLuminance8Alpha8us1: begin
  5682. ColorType := COLOR_GRAYSCALEALPHA;
  5683. PixSize := 1;
  5684. Alpha := true;
  5685. end;
  5686. tfBGR8ub3, tfRGB8ub3: begin
  5687. ColorType := COLOR_RGB;
  5688. PixSize := 3;
  5689. Alpha := false;
  5690. end;
  5691. tfBGRA8ub4, tfRGBA8ub4: begin
  5692. ColorType := COLOR_RGBALPHA;
  5693. PixSize := 3;
  5694. Alpha := true
  5695. end;
  5696. else
  5697. raise EglBitmapUnsupportedFormat.Create(Format);
  5698. end;
  5699. Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
  5700. try
  5701. // Copy ImageData
  5702. pSource := Data;
  5703. for Y := 0 to Height -1 do begin
  5704. pDest := png.ScanLine[Y];
  5705. for X := 0 to Width -1 do begin
  5706. Move(pSource^, pDest^, PixSize);
  5707. Inc(pDest, PixSize);
  5708. Inc(pSource, PixSize);
  5709. if Alpha then begin
  5710. png.AlphaScanline[Y]^[X] := pSource^;
  5711. Inc(pSource);
  5712. end;
  5713. end;
  5714. // convert RGB line to BGR
  5715. if Format in [tfRGB8ub3, tfRGBA8ub4] then begin
  5716. pTemp := png.ScanLine[Y];
  5717. for X := 0 to Width -1 do begin
  5718. Temp := pByteArray(pTemp)^[0];
  5719. pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
  5720. pByteArray(pTemp)^[2] := Temp;
  5721. Inc(pTemp, 3);
  5722. end;
  5723. end;
  5724. end;
  5725. // Save to Stream
  5726. Png.CompressionLevel := 6;
  5727. Png.SaveToStream(aStream);
  5728. finally
  5729. FreeAndNil(Png);
  5730. end;
  5731. end;
  5732. {$IFEND}
  5733. {$ENDIF}
  5734. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5735. //JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5736. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5737. {$IFDEF GLB_LIB_JPEG}
  5738. type
  5739. glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
  5740. glBitmap_libJPEG_source_mgr = record
  5741. pub: jpeg_source_mgr;
  5742. SrcStream: TStream;
  5743. SrcBuffer: array [1..4096] of byte;
  5744. end;
  5745. glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
  5746. glBitmap_libJPEG_dest_mgr = record
  5747. pub: jpeg_destination_mgr;
  5748. DestStream: TStream;
  5749. DestBuffer: array [1..4096] of byte;
  5750. end;
  5751. procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
  5752. begin
  5753. //DUMMY
  5754. end;
  5755. procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
  5756. begin
  5757. //DUMMY
  5758. end;
  5759. procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
  5760. begin
  5761. //DUMMY
  5762. end;
  5763. procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
  5764. begin
  5765. //DUMMY
  5766. end;
  5767. procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
  5768. begin
  5769. //DUMMY
  5770. end;
  5771. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5772. function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
  5773. var
  5774. src: glBitmap_libJPEG_source_mgr_ptr;
  5775. bytes: integer;
  5776. begin
  5777. src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
  5778. bytes := src^.SrcStream.Read(src^.SrcBuffer[1], 4096);
  5779. if (bytes <= 0) then begin
  5780. src^.SrcBuffer[1] := $FF;
  5781. src^.SrcBuffer[2] := JPEG_EOI;
  5782. bytes := 2;
  5783. end;
  5784. src^.pub.next_input_byte := @(src^.SrcBuffer[1]);
  5785. src^.pub.bytes_in_buffer := bytes;
  5786. result := true;
  5787. end;
  5788. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5789. procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
  5790. var
  5791. src: glBitmap_libJPEG_source_mgr_ptr;
  5792. begin
  5793. src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
  5794. if num_bytes > 0 then begin
  5795. // wanted byte isn't in buffer so set stream position and read buffer
  5796. if num_bytes > src^.pub.bytes_in_buffer then begin
  5797. src^.SrcStream.Position := src^.SrcStream.Position + num_bytes - src^.pub.bytes_in_buffer;
  5798. src^.pub.fill_input_buffer(cinfo);
  5799. end else begin
  5800. // wanted byte is in buffer so only skip
  5801. inc(src^.pub.next_input_byte, num_bytes);
  5802. dec(src^.pub.bytes_in_buffer, num_bytes);
  5803. end;
  5804. end;
  5805. end;
  5806. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5807. function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
  5808. var
  5809. dest: glBitmap_libJPEG_dest_mgr_ptr;
  5810. begin
  5811. dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
  5812. if dest^.pub.free_in_buffer < Cardinal(Length(dest^.DestBuffer)) then begin
  5813. // write complete buffer
  5814. dest^.DestStream.Write(dest^.DestBuffer[1], SizeOf(dest^.DestBuffer));
  5815. // reset buffer
  5816. dest^.pub.next_output_byte := @dest^.DestBuffer[1];
  5817. dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
  5818. end;
  5819. result := true;
  5820. end;
  5821. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5822. procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
  5823. var
  5824. Idx: Integer;
  5825. dest: glBitmap_libJPEG_dest_mgr_ptr;
  5826. begin
  5827. dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
  5828. for Idx := Low(dest^.DestBuffer) to High(dest^.DestBuffer) do begin
  5829. // check for endblock
  5830. if (Idx < High(dest^.DestBuffer)) and (dest^.DestBuffer[Idx] = $FF) and (dest^.DestBuffer[Idx +1] = JPEG_EOI) then begin
  5831. // write endblock
  5832. dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
  5833. // leave
  5834. break;
  5835. end else
  5836. dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
  5837. end;
  5838. end;
  5839. {$ENDIF}
  5840. {$IFDEF GLB_SUPPORT_JPEG_READ}
  5841. {$IF DEFINED(GLB_LAZ_JPEG)}
  5842. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5843. function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
  5844. const
  5845. MAGIC_LEN = 2;
  5846. JPEG_MAGIC: String[MAGIC_LEN] = #$FF#$D8;
  5847. var
  5848. intf: TLazIntfImage;
  5849. reader: TFPReaderJPEG;
  5850. StreamPos: Int64;
  5851. magic: String[MAGIC_LEN];
  5852. begin
  5853. result := true;
  5854. StreamPos := aStream.Position;
  5855. SetLength(magic, MAGIC_LEN);
  5856. aStream.Read(magic[1], MAGIC_LEN);
  5857. aStream.Position := StreamPos;
  5858. if (magic <> JPEG_MAGIC) then begin
  5859. result := false;
  5860. exit;
  5861. end;
  5862. reader := TFPReaderJPEG.Create;
  5863. intf := TLazIntfImage.Create(0, 0);
  5864. try try
  5865. intf.DataDescription := GetDescriptionFromDevice(0, 0, 0);
  5866. reader.ImageRead(aStream, intf);
  5867. AssignFromLazIntfImage(intf);
  5868. except
  5869. result := false;
  5870. aStream.Position := StreamPos;
  5871. exit;
  5872. end;
  5873. finally
  5874. reader.Free;
  5875. intf.Free;
  5876. end;
  5877. end;
  5878. {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
  5879. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5880. function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
  5881. var
  5882. Surface: PSDL_Surface;
  5883. RWops: PSDL_RWops;
  5884. begin
  5885. result := false;
  5886. RWops := glBitmapCreateRWops(aStream);
  5887. try
  5888. if IMG_isJPG(RWops) > 0 then begin
  5889. Surface := IMG_LoadJPG_RW(RWops);
  5890. try
  5891. AssignFromSurface(Surface);
  5892. result := true;
  5893. finally
  5894. SDL_FreeSurface(Surface);
  5895. end;
  5896. end;
  5897. finally
  5898. SDL_FreeRW(RWops);
  5899. end;
  5900. end;
  5901. {$ELSEIF DEFINED(GLB_LIB_JPEG)}
  5902. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5903. function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
  5904. var
  5905. StreamPos: Int64;
  5906. Temp: array[0..1]of Byte;
  5907. jpeg: jpeg_decompress_struct;
  5908. jpeg_err: jpeg_error_mgr;
  5909. IntFormat: TglBitmapFormat;
  5910. pImage: pByte;
  5911. TempHeight, TempWidth: Integer;
  5912. pTemp: pByte;
  5913. Row: Integer;
  5914. FormatDesc: TFormatDescriptor;
  5915. begin
  5916. result := false;
  5917. if not init_libJPEG then
  5918. raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
  5919. try
  5920. // reading first two bytes to test file and set cursor back to begin
  5921. StreamPos := aStream.Position;
  5922. aStream.Read({%H-}Temp[0], 2);
  5923. aStream.Position := StreamPos;
  5924. // if Bitmap then read file.
  5925. if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
  5926. FillChar(jpeg{%H-}, SizeOf(jpeg_decompress_struct), $00);
  5927. FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
  5928. // error managment
  5929. jpeg.err := jpeg_std_error(@jpeg_err);
  5930. jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
  5931. jpeg_err.output_message := glBitmap_libJPEG_output_message;
  5932. // decompression struct
  5933. jpeg_create_decompress(@jpeg);
  5934. // allocation space for streaming methods
  5935. jpeg.src := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_source_mgr));
  5936. // seeting up custom functions
  5937. with glBitmap_libJPEG_source_mgr_ptr(jpeg.src)^ do begin
  5938. pub.init_source := glBitmap_libJPEG_init_source;
  5939. pub.fill_input_buffer := glBitmap_libJPEG_fill_input_buffer;
  5940. pub.skip_input_data := glBitmap_libJPEG_skip_input_data;
  5941. pub.resync_to_restart := jpeg_resync_to_restart; // use default method
  5942. pub.term_source := glBitmap_libJPEG_term_source;
  5943. pub.bytes_in_buffer := 0; // forces fill_input_buffer on first read
  5944. pub.next_input_byte := nil; // until buffer loaded
  5945. SrcStream := aStream;
  5946. end;
  5947. // set global decoding state
  5948. jpeg.global_state := DSTATE_START;
  5949. // read header of jpeg
  5950. jpeg_read_header(@jpeg, false);
  5951. // setting output parameter
  5952. case jpeg.jpeg_color_space of
  5953. JCS_GRAYSCALE:
  5954. begin
  5955. jpeg.out_color_space := JCS_GRAYSCALE;
  5956. IntFormat := tfLuminance8ub1;
  5957. end;
  5958. else
  5959. jpeg.out_color_space := JCS_RGB;
  5960. IntFormat := tfRGB8ub3;
  5961. end;
  5962. // reading image
  5963. jpeg_start_decompress(@jpeg);
  5964. TempHeight := jpeg.output_height;
  5965. TempWidth := jpeg.output_width;
  5966. FormatDesc := TFormatDescriptor.Get(IntFormat);
  5967. // creating new image
  5968. GetMem(pImage, FormatDesc.GetSize(TempWidth, TempHeight));
  5969. try
  5970. pTemp := pImage;
  5971. for Row := 0 to TempHeight -1 do begin
  5972. jpeg_read_scanlines(@jpeg, @pTemp, 1);
  5973. Inc(pTemp, FormatDesc.GetSize(TempWidth, 1));
  5974. end;
  5975. // finish decompression
  5976. jpeg_finish_decompress(@jpeg);
  5977. // destroy decompression
  5978. jpeg_destroy_decompress(@jpeg);
  5979. SetDataPointer(pImage, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
  5980. result := true;
  5981. except
  5982. if Assigned(pImage) then
  5983. FreeMem(pImage);
  5984. raise;
  5985. end;
  5986. end;
  5987. finally
  5988. quit_libJPEG;
  5989. end;
  5990. end;
  5991. {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
  5992. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5993. function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
  5994. var
  5995. bmp: TBitmap;
  5996. jpg: TJPEGImage;
  5997. StreamPos: Int64;
  5998. Temp: array[0..1]of Byte;
  5999. begin
  6000. result := false;
  6001. // reading first two bytes to test file and set cursor back to begin
  6002. StreamPos := aStream.Position;
  6003. aStream.Read(Temp[0], 2);
  6004. aStream.Position := StreamPos;
  6005. // if Bitmap then read file.
  6006. if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
  6007. bmp := TBitmap.Create;
  6008. try
  6009. jpg := TJPEGImage.Create;
  6010. try
  6011. jpg.LoadFromStream(aStream);
  6012. bmp.Assign(jpg);
  6013. result := AssignFromBitmap(bmp);
  6014. finally
  6015. jpg.Free;
  6016. end;
  6017. finally
  6018. bmp.Free;
  6019. end;
  6020. end;
  6021. end;
  6022. {$IFEND}
  6023. {$ENDIF}
  6024. {$IFDEF GLB_SUPPORT_JPEG_WRITE}
  6025. {$IF DEFINED(GLB_LAZ_JPEG)}
  6026. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6027. procedure TglBitmap.SaveJPEG(const aStream: TStream);
  6028. var
  6029. jpeg: TJPEGImage;
  6030. intf: TLazIntfImage;
  6031. raw: TRawImage;
  6032. begin
  6033. jpeg := TJPEGImage.Create;
  6034. intf := TLazIntfImage.Create(0, 0);
  6035. try
  6036. if not AssignToLazIntfImage(intf) then
  6037. raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
  6038. intf.GetRawImage(raw);
  6039. jpeg.LoadFromRawImage(raw, false);
  6040. jpeg.SaveToStream(aStream);
  6041. finally
  6042. intf.Free;
  6043. jpeg.Free;
  6044. end;
  6045. end;
  6046. {$ELSEIF DEFINED(GLB_LIB_JPEG)}
  6047. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6048. procedure TglBitmap.SaveJPEG(const aStream: TStream);
  6049. var
  6050. jpeg: jpeg_compress_struct;
  6051. jpeg_err: jpeg_error_mgr;
  6052. Row: Integer;
  6053. pTemp, pTemp2: pByte;
  6054. procedure CopyRow(pDest, pSource: pByte);
  6055. var
  6056. X: Integer;
  6057. begin
  6058. for X := 0 to Width - 1 do begin
  6059. pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
  6060. pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
  6061. pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
  6062. Inc(pDest, 3);
  6063. Inc(pSource, 3);
  6064. end;
  6065. end;
  6066. begin
  6067. if not (ftJPEG in FormatGetSupportedFiles(Format)) then
  6068. raise EglBitmapUnsupportedFormat.Create(Format);
  6069. if not init_libJPEG then
  6070. raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
  6071. try
  6072. FillChar(jpeg{%H-}, SizeOf(jpeg_compress_struct), $00);
  6073. FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
  6074. // error managment
  6075. jpeg.err := jpeg_std_error(@jpeg_err);
  6076. jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
  6077. jpeg_err.output_message := glBitmap_libJPEG_output_message;
  6078. // compression struct
  6079. jpeg_create_compress(@jpeg);
  6080. // allocation space for streaming methods
  6081. jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
  6082. // seeting up custom functions
  6083. with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
  6084. pub.init_destination := glBitmap_libJPEG_init_destination;
  6085. pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
  6086. pub.term_destination := glBitmap_libJPEG_term_destination;
  6087. pub.next_output_byte := @DestBuffer[1];
  6088. pub.free_in_buffer := Length(DestBuffer);
  6089. DestStream := aStream;
  6090. end;
  6091. // very important state
  6092. jpeg.global_state := CSTATE_START;
  6093. jpeg.image_width := Width;
  6094. jpeg.image_height := Height;
  6095. case Format of
  6096. tfAlpha8ub1, tfLuminance8ub1: begin
  6097. jpeg.input_components := 1;
  6098. jpeg.in_color_space := JCS_GRAYSCALE;
  6099. end;
  6100. tfRGB8ub3, tfBGR8ub3: begin
  6101. jpeg.input_components := 3;
  6102. jpeg.in_color_space := JCS_RGB;
  6103. end;
  6104. end;
  6105. jpeg_set_defaults(@jpeg);
  6106. jpeg_set_quality(@jpeg, 95, true);
  6107. jpeg_start_compress(@jpeg, true);
  6108. pTemp := Data;
  6109. if Format = tfBGR8ub3 then
  6110. GetMem(pTemp2, fRowSize)
  6111. else
  6112. pTemp2 := pTemp;
  6113. try
  6114. for Row := 0 to jpeg.image_height -1 do begin
  6115. // prepare row
  6116. if Format = tfBGR8ub3 then
  6117. CopyRow(pTemp2, pTemp)
  6118. else
  6119. pTemp2 := pTemp;
  6120. // write row
  6121. jpeg_write_scanlines(@jpeg, @pTemp2, 1);
  6122. inc(pTemp, fRowSize);
  6123. end;
  6124. finally
  6125. // free memory
  6126. if Format = tfBGR8ub3 then
  6127. FreeMem(pTemp2);
  6128. end;
  6129. jpeg_finish_compress(@jpeg);
  6130. jpeg_destroy_compress(@jpeg);
  6131. finally
  6132. quit_libJPEG;
  6133. end;
  6134. end;
  6135. {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
  6136. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6137. procedure TglBitmap.SaveJPEG(const aStream: TStream);
  6138. var
  6139. Bmp: TBitmap;
  6140. Jpg: TJPEGImage;
  6141. begin
  6142. if not (ftJPEG in FormatGetSupportedFiles(Format)) then
  6143. raise EglBitmapUnsupportedFormat.Create(Format);
  6144. Bmp := TBitmap.Create;
  6145. try
  6146. Jpg := TJPEGImage.Create;
  6147. try
  6148. AssignToBitmap(Bmp);
  6149. if (Format in [tfAlpha8ub1, tfLuminance8ub1]) then begin
  6150. Jpg.Grayscale := true;
  6151. Jpg.PixelFormat := jf8Bit;
  6152. end;
  6153. Jpg.Assign(Bmp);
  6154. Jpg.SaveToStream(aStream);
  6155. finally
  6156. FreeAndNil(Jpg);
  6157. end;
  6158. finally
  6159. FreeAndNil(Bmp);
  6160. end;
  6161. end;
  6162. {$IFEND}
  6163. {$ENDIF}
  6164. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6165. //RAW/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6166. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6167. type
  6168. RawHeader = packed record
  6169. Magic: String[5];
  6170. Version: Byte;
  6171. Width: Integer;
  6172. Height: Integer;
  6173. DataSize: Integer;
  6174. BitsPerPixel: Integer;
  6175. Precision: TglBitmapRec4ub;
  6176. Shift: TglBitmapRec4ub;
  6177. end;
  6178. function TglBitmap.LoadRAW(const aStream: TStream): Boolean;
  6179. var
  6180. header: RawHeader;
  6181. StartPos: Int64;
  6182. fd: TFormatDescriptor;
  6183. buf: PByte;
  6184. begin
  6185. result := false;
  6186. StartPos := aStream.Position;
  6187. aStream.Read(header{%H-}, SizeOf(header));
  6188. if (header.Magic <> 'glBMP') then begin
  6189. aStream.Position := StartPos;
  6190. exit;
  6191. end;
  6192. fd := TFormatDescriptor.GetFromPrecShift(header.Precision, header.Shift, header.BitsPerPixel);
  6193. if (fd.Format = tfEmpty) then
  6194. raise EglBitmapUnsupportedFormat.Create('no supported format found');
  6195. buf := GetMemory(header.DataSize);
  6196. aStream.Read(buf^, header.DataSize);
  6197. SetDataPointer(buf, fd.Format, header.Width, header.Height);
  6198. result := true;
  6199. end;
  6200. procedure TglBitmap.SaveRAW(const aStream: TStream);
  6201. var
  6202. header: RawHeader;
  6203. fd: TFormatDescriptor;
  6204. begin
  6205. fd := TFormatDescriptor.Get(Format);
  6206. header.Magic := 'glBMP';
  6207. header.Version := 1;
  6208. header.Width := Width;
  6209. header.Height := Height;
  6210. header.DataSize := fd.GetSize(fDimension);
  6211. header.BitsPerPixel := fd.BitsPerPixel;
  6212. header.Precision := fd.Precision;
  6213. header.Shift := fd.Shift;
  6214. aStream.Write(header, SizeOf(header));
  6215. aStream.Write(Data^, header.DataSize);
  6216. end;
  6217. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6218. //BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6219. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6220. const
  6221. BMP_MAGIC = $4D42;
  6222. BMP_COMP_RGB = 0;
  6223. BMP_COMP_RLE8 = 1;
  6224. BMP_COMP_RLE4 = 2;
  6225. BMP_COMP_BITFIELDS = 3;
  6226. type
  6227. TBMPHeader = packed record
  6228. bfType: Word;
  6229. bfSize: Cardinal;
  6230. bfReserved1: Word;
  6231. bfReserved2: Word;
  6232. bfOffBits: Cardinal;
  6233. end;
  6234. TBMPInfo = packed record
  6235. biSize: Cardinal;
  6236. biWidth: Longint;
  6237. biHeight: Longint;
  6238. biPlanes: Word;
  6239. biBitCount: Word;
  6240. biCompression: Cardinal;
  6241. biSizeImage: Cardinal;
  6242. biXPelsPerMeter: Longint;
  6243. biYPelsPerMeter: Longint;
  6244. biClrUsed: Cardinal;
  6245. biClrImportant: Cardinal;
  6246. end;
  6247. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6248. function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
  6249. //////////////////////////////////////////////////////////////////////////////////////////////////
  6250. function ReadInfo(out aInfo: TBMPInfo; out aMask: TglBitmapRec4ul): TglBitmapFormat;
  6251. begin
  6252. result := tfEmpty;
  6253. aStream.Read(aInfo{%H-}, SizeOf(aInfo));
  6254. FillChar(aMask{%H-}, SizeOf(aMask), 0);
  6255. //Read Compression
  6256. case aInfo.biCompression of
  6257. BMP_COMP_RLE4,
  6258. BMP_COMP_RLE8: begin
  6259. raise EglBitmap.Create('RLE compression is not supported');
  6260. end;
  6261. BMP_COMP_BITFIELDS: begin
  6262. if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
  6263. aStream.Read(aMask.r, SizeOf(aMask.r));
  6264. aStream.Read(aMask.g, SizeOf(aMask.g));
  6265. aStream.Read(aMask.b, SizeOf(aMask.b));
  6266. aStream.Read(aMask.a, SizeOf(aMask.a));
  6267. end else
  6268. raise EglBitmap.Create('Bitfields are only supported for 16bit and 32bit formats');
  6269. end;
  6270. end;
  6271. //get suitable format
  6272. case aInfo.biBitCount of
  6273. 8: result := tfLuminance8ub1;
  6274. 16: result := tfX1RGB5us1;
  6275. 24: result := tfBGR8ub3;
  6276. 32: result := tfXRGB8ui1;
  6277. end;
  6278. end;
  6279. function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TbmpColorTableFormat;
  6280. var
  6281. i, c: Integer;
  6282. ColorTable: TbmpColorTable;
  6283. begin
  6284. result := nil;
  6285. if (aInfo.biBitCount >= 16) then
  6286. exit;
  6287. aFormat := tfLuminance8ub1;
  6288. c := aInfo.biClrUsed;
  6289. if (c = 0) then
  6290. c := 1 shl aInfo.biBitCount;
  6291. SetLength(ColorTable, c);
  6292. for i := 0 to c-1 do begin
  6293. aStream.Read(ColorTable[i], SizeOf(TbmpColorTableEnty));
  6294. if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then
  6295. aFormat := tfRGB8ub3;
  6296. end;
  6297. result := TbmpColorTableFormat.Create;
  6298. result.BitsPerPixel := aInfo.biBitCount;
  6299. result.ColorTable := ColorTable;
  6300. result.CalcValues;
  6301. end;
  6302. //////////////////////////////////////////////////////////////////////////////////////////////////
  6303. function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapRec4ul; const aInfo: TBMPInfo): TbmpBitfieldFormat;
  6304. var
  6305. FormatDesc: TFormatDescriptor;
  6306. begin
  6307. result := nil;
  6308. if (aMask.r <> 0) or (aMask.g <> 0) or (aMask.b <> 0) or (aMask.a <> 0) then begin
  6309. FormatDesc := TFormatDescriptor.GetFromMask(aMask);
  6310. if (FormatDesc.Format = tfEmpty) then
  6311. exit;
  6312. aFormat := FormatDesc.Format;
  6313. if (aMask.a = 0) and TFormatDescriptor.Get(aFormat).HasAlpha then
  6314. aFormat := TFormatDescriptor.Get(aFormat).WithoutAlpha;
  6315. if (aMask.a <> 0) and not TFormatDescriptor.Get(aFormat).HasAlpha then
  6316. aFormat := TFormatDescriptor.Get(aFormat).WithAlpha;
  6317. result := TbmpBitfieldFormat.Create;
  6318. result.SetCustomValues(aInfo.biBitCount, aMask);
  6319. end;
  6320. end;
  6321. var
  6322. //simple types
  6323. StartPos: Int64;
  6324. ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
  6325. PaddingBuff: Cardinal;
  6326. LineBuf, ImageData, TmpData: PByte;
  6327. SourceMD, DestMD: Pointer;
  6328. BmpFormat: TglBitmapFormat;
  6329. //records
  6330. Mask: TglBitmapRec4ul;
  6331. Header: TBMPHeader;
  6332. Info: TBMPInfo;
  6333. //classes
  6334. SpecialFormat: TFormatDescriptor;
  6335. FormatDesc: TFormatDescriptor;
  6336. //////////////////////////////////////////////////////////////////////////////////////////////////
  6337. procedure SpecialFormatReadLine(aData: PByte; aLineBuf: PByte);
  6338. var
  6339. i: Integer;
  6340. Pixel: TglBitmapPixelData;
  6341. begin
  6342. aStream.Read(aLineBuf^, rbLineSize);
  6343. SpecialFormat.PreparePixel(Pixel);
  6344. for i := 0 to Info.biWidth-1 do begin
  6345. SpecialFormat.Unmap(aLineBuf, Pixel, SourceMD);
  6346. glBitmapConvertPixel(Pixel, SpecialFormat, FormatDesc);
  6347. FormatDesc.Map(Pixel, aData, DestMD);
  6348. end;
  6349. end;
  6350. begin
  6351. result := false;
  6352. BmpFormat := tfEmpty;
  6353. SpecialFormat := nil;
  6354. LineBuf := nil;
  6355. SourceMD := nil;
  6356. DestMD := nil;
  6357. // Header
  6358. StartPos := aStream.Position;
  6359. aStream.Read(Header{%H-}, SizeOf(Header));
  6360. if Header.bfType = BMP_MAGIC then begin
  6361. try try
  6362. BmpFormat := ReadInfo(Info, Mask);
  6363. SpecialFormat := ReadColorTable(BmpFormat, Info);
  6364. if not Assigned(SpecialFormat) then
  6365. SpecialFormat := CheckBitfields(BmpFormat, Mask, Info);
  6366. aStream.Position := StartPos + Header.bfOffBits;
  6367. if (BmpFormat <> tfEmpty) then begin
  6368. FormatDesc := TFormatDescriptor.Get(BmpFormat);
  6369. rbLineSize := Round(Info.biWidth * Info.biBitCount / 8); //ReadBuffer LineSize
  6370. wbLineSize := Trunc(Info.biWidth * FormatDesc.BytesPerPixel);
  6371. Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
  6372. //get Memory
  6373. DestMD := FormatDesc.CreateMappingData;
  6374. ImageSize := FormatDesc.GetSize(Info.biWidth, abs(Info.biHeight));
  6375. GetMem(ImageData, ImageSize);
  6376. if Assigned(SpecialFormat) then begin
  6377. GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
  6378. SourceMD := SpecialFormat.CreateMappingData;
  6379. end;
  6380. //read Data
  6381. try try
  6382. FillChar(ImageData^, ImageSize, $FF);
  6383. TmpData := ImageData;
  6384. if (Info.biHeight > 0) then
  6385. Inc(TmpData, wbLineSize * (Info.biHeight-1));
  6386. for i := 0 to Abs(Info.biHeight)-1 do begin
  6387. if Assigned(SpecialFormat) then
  6388. SpecialFormatReadLine(TmpData, LineBuf) //if is special format read and convert data
  6389. else
  6390. aStream.Read(TmpData^, wbLineSize); //else only read data
  6391. if (Info.biHeight > 0) then
  6392. dec(TmpData, wbLineSize)
  6393. else
  6394. inc(TmpData, wbLineSize);
  6395. aStream.Read(PaddingBuff{%H-}, Padding);
  6396. end;
  6397. SetDataPointer(ImageData, BmpFormat, Info.biWidth, abs(Info.biHeight)); //be careful, Data could be freed by this method
  6398. result := true;
  6399. finally
  6400. if Assigned(LineBuf) then
  6401. FreeMem(LineBuf);
  6402. if Assigned(SourceMD) then
  6403. SpecialFormat.FreeMappingData(SourceMD);
  6404. FormatDesc.FreeMappingData(DestMD);
  6405. end;
  6406. except
  6407. if Assigned(ImageData) then
  6408. FreeMem(ImageData);
  6409. raise;
  6410. end;
  6411. end else
  6412. raise EglBitmap.Create('LoadBMP - No suitable format found');
  6413. except
  6414. aStream.Position := StartPos;
  6415. raise;
  6416. end;
  6417. finally
  6418. FreeAndNil(SpecialFormat);
  6419. end;
  6420. end
  6421. else aStream.Position := StartPos;
  6422. end;
  6423. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6424. procedure TglBitmap.SaveBMP(const aStream: TStream);
  6425. var
  6426. Header: TBMPHeader;
  6427. Info: TBMPInfo;
  6428. Converter: TFormatDescriptor;
  6429. FormatDesc: TFormatDescriptor;
  6430. SourceFD, DestFD: Pointer;
  6431. pData, srcData, dstData, ConvertBuffer: pByte;
  6432. Pixel: TglBitmapPixelData;
  6433. ImageSize, wbLineSize, rbLineSize, Padding, LineIdx, PixelIdx: Integer;
  6434. RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
  6435. PaddingBuff: Cardinal;
  6436. function GetLineWidth : Integer;
  6437. begin
  6438. result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
  6439. end;
  6440. begin
  6441. if not (ftBMP in FormatGetSupportedFiles(Format)) then
  6442. raise EglBitmapUnsupportedFormat.Create(Format);
  6443. Converter := nil;
  6444. FormatDesc := TFormatDescriptor.Get(Format);
  6445. ImageSize := FormatDesc.GetSize(Dimension);
  6446. FillChar(Header{%H-}, SizeOf(Header), 0);
  6447. Header.bfType := BMP_MAGIC;
  6448. Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
  6449. Header.bfReserved1 := 0;
  6450. Header.bfReserved2 := 0;
  6451. Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
  6452. FillChar(Info{%H-}, SizeOf(Info), 0);
  6453. Info.biSize := SizeOf(Info);
  6454. Info.biWidth := Width;
  6455. Info.biHeight := Height;
  6456. Info.biPlanes := 1;
  6457. Info.biCompression := BMP_COMP_RGB;
  6458. Info.biSizeImage := ImageSize;
  6459. try
  6460. case Format of
  6461. tfAlpha4ub1, tfAlpha8ub1, tfLuminance4ub1, tfLuminance8ub1, tfR3G3B2ub1:
  6462. begin
  6463. Info.biBitCount := 8;
  6464. Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
  6465. Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal); //256 ColorTable entries
  6466. Converter := TbmpColorTableFormat.Create;
  6467. with (Converter as TbmpColorTableFormat) do begin
  6468. SetCustomValues(fFormat, 1, FormatDesc.Precision, FormatDesc.Shift);
  6469. CreateColorTable;
  6470. end;
  6471. end;
  6472. tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
  6473. tfRGBX4us1, tfXRGB4us1, tfRGB5X1us1, tfX1RGB5us1, tfR5G6B5us1, tfRGB5A1us1, tfA1RGB5us1, tfRGBA4us1, tfARGB4us1,
  6474. tfBGRX4us1, tfXBGR4us1, tfBGR5X1us1, tfX1BGR5us1, tfB5G6R5us1, tfBGR5A1us1, tfA1BGR5us1, tfBGRA4us1, tfABGR4us1:
  6475. begin
  6476. Info.biBitCount := 16;
  6477. Info.biCompression := BMP_COMP_BITFIELDS;
  6478. end;
  6479. tfBGR8ub3, tfRGB8ub3:
  6480. begin
  6481. Info.biBitCount := 24;
  6482. if (Format = tfRGB8ub3) then
  6483. Converter := TfdBGR8ub3.Create; //use BGR8 Format Descriptor to Swap RGB Values
  6484. end;
  6485. tfRGBX8ui1, tfXRGB8ui1, tfRGB10X2ui1, tfX2RGB10ui1, tfRGBA8ui1, tfARGB8ui1, tfRGBA8ub4, tfRGB10A2ui1, tfA2RGB10ui1,
  6486. tfBGRX8ui1, tfXBGR8ui1, tfBGR10X2ui1, tfX2BGR10ui1, tfBGRA8ui1, tfABGR8ui1, tfBGRA8ub4, tfBGR10A2ui1, tfA2BGR10ui1:
  6487. begin
  6488. Info.biBitCount := 32;
  6489. Info.biCompression := BMP_COMP_BITFIELDS;
  6490. end;
  6491. else
  6492. raise EglBitmapUnsupportedFormat.Create(Format);
  6493. end;
  6494. Info.biXPelsPerMeter := 2835;
  6495. Info.biYPelsPerMeter := 2835;
  6496. // prepare bitmasks
  6497. if Info.biCompression = BMP_COMP_BITFIELDS then begin
  6498. Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
  6499. Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
  6500. RedMask := FormatDesc.Mask.r;
  6501. GreenMask := FormatDesc.Mask.g;
  6502. BlueMask := FormatDesc.Mask.b;
  6503. AlphaMask := FormatDesc.Mask.a;
  6504. end;
  6505. // headers
  6506. aStream.Write(Header, SizeOf(Header));
  6507. aStream.Write(Info, SizeOf(Info));
  6508. // colortable
  6509. if Assigned(Converter) and (Converter is TbmpColorTableFormat) then
  6510. with (Converter as TbmpColorTableFormat) do
  6511. aStream.Write(ColorTable[0].b,
  6512. SizeOf(TbmpColorTableEnty) * Length(ColorTable));
  6513. // bitmasks
  6514. if Info.biCompression = BMP_COMP_BITFIELDS then begin
  6515. aStream.Write(RedMask, SizeOf(Cardinal));
  6516. aStream.Write(GreenMask, SizeOf(Cardinal));
  6517. aStream.Write(BlueMask, SizeOf(Cardinal));
  6518. aStream.Write(AlphaMask, SizeOf(Cardinal));
  6519. end;
  6520. // image data
  6521. rbLineSize := Round(Info.biWidth * FormatDesc.BytesPerPixel);
  6522. wbLineSize := Round(Info.biWidth * Info.biBitCount / 8);
  6523. Padding := GetLineWidth - wbLineSize;
  6524. PaddingBuff := 0;
  6525. pData := Data;
  6526. inc(pData, (Height-1) * rbLineSize);
  6527. // prepare row buffer. But only for RGB because RGBA supports color masks
  6528. // so it's possible to change color within the image.
  6529. if Assigned(Converter) then begin
  6530. FormatDesc.PreparePixel(Pixel);
  6531. GetMem(ConvertBuffer, wbLineSize);
  6532. SourceFD := FormatDesc.CreateMappingData;
  6533. DestFD := Converter.CreateMappingData;
  6534. end else
  6535. ConvertBuffer := nil;
  6536. try
  6537. for LineIdx := 0 to Height - 1 do begin
  6538. // preparing row
  6539. if Assigned(Converter) then begin
  6540. srcData := pData;
  6541. dstData := ConvertBuffer;
  6542. for PixelIdx := 0 to Info.biWidth-1 do begin
  6543. FormatDesc.Unmap(srcData, Pixel, SourceFD);
  6544. glBitmapConvertPixel(Pixel, FormatDesc, Converter);
  6545. Converter.Map(Pixel, dstData, DestFD);
  6546. end;
  6547. aStream.Write(ConvertBuffer^, wbLineSize);
  6548. end else begin
  6549. aStream.Write(pData^, rbLineSize);
  6550. end;
  6551. dec(pData, rbLineSize);
  6552. if (Padding > 0) then
  6553. aStream.Write(PaddingBuff, Padding);
  6554. end;
  6555. finally
  6556. // destroy row buffer
  6557. if Assigned(ConvertBuffer) then begin
  6558. FormatDesc.FreeMappingData(SourceFD);
  6559. Converter.FreeMappingData(DestFD);
  6560. FreeMem(ConvertBuffer);
  6561. end;
  6562. end;
  6563. finally
  6564. if Assigned(Converter) then
  6565. Converter.Free;
  6566. end;
  6567. end;
  6568. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6569. //TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6570. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6571. type
  6572. TTGAHeader = packed record
  6573. ImageID: Byte;
  6574. ColorMapType: Byte;
  6575. ImageType: Byte;
  6576. //ColorMapSpec: Array[0..4] of Byte;
  6577. ColorMapStart: Word;
  6578. ColorMapLength: Word;
  6579. ColorMapEntrySize: Byte;
  6580. OrigX: Word;
  6581. OrigY: Word;
  6582. Width: Word;
  6583. Height: Word;
  6584. Bpp: Byte;
  6585. ImageDesc: Byte;
  6586. end;
  6587. const
  6588. TGA_UNCOMPRESSED_RGB = 2;
  6589. TGA_UNCOMPRESSED_GRAY = 3;
  6590. TGA_COMPRESSED_RGB = 10;
  6591. TGA_COMPRESSED_GRAY = 11;
  6592. TGA_NONE_COLOR_TABLE = 0;
  6593. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6594. function TglBitmap.LoadTGA(const aStream: TStream): Boolean;
  6595. var
  6596. Header: TTGAHeader;
  6597. ImageData: System.PByte;
  6598. StartPosition: Int64;
  6599. PixelSize, LineSize: Integer;
  6600. tgaFormat: TglBitmapFormat;
  6601. FormatDesc: TFormatDescriptor;
  6602. Counter: packed record
  6603. X, Y: packed record
  6604. low, high, dir: Integer;
  6605. end;
  6606. end;
  6607. const
  6608. CACHE_SIZE = $4000;
  6609. ////////////////////////////////////////////////////////////////////////////////////////
  6610. procedure ReadUncompressed;
  6611. var
  6612. i, j: Integer;
  6613. buf, tmp1, tmp2: System.PByte;
  6614. begin
  6615. buf := nil;
  6616. if (Counter.X.dir < 0) then
  6617. GetMem(buf, LineSize);
  6618. try
  6619. while (Counter.Y.low <> Counter.Y.high + counter.Y.dir) do begin
  6620. tmp1 := ImageData;
  6621. inc(tmp1, (Counter.Y.low * LineSize)); //pointer to LineStart
  6622. if (Counter.X.dir < 0) then begin //flip X
  6623. aStream.Read(buf^, LineSize);
  6624. tmp2 := buf;
  6625. inc(tmp2, LineSize - PixelSize); //pointer to last pixel in line
  6626. for i := 0 to Header.Width-1 do begin //for all pixels in line
  6627. for j := 0 to PixelSize-1 do begin //for all bytes in pixel
  6628. tmp1^ := tmp2^;
  6629. inc(tmp1);
  6630. inc(tmp2);
  6631. end;
  6632. dec(tmp2, 2*PixelSize); //move 2 backwards, because j-loop moved 1 forward
  6633. end;
  6634. end else
  6635. aStream.Read(tmp1^, LineSize);
  6636. inc(Counter.Y.low, Counter.Y.dir); //move to next line index
  6637. end;
  6638. finally
  6639. if Assigned(buf) then
  6640. FreeMem(buf);
  6641. end;
  6642. end;
  6643. ////////////////////////////////////////////////////////////////////////////////////////
  6644. procedure ReadCompressed;
  6645. /////////////////////////////////////////////////////////////////
  6646. var
  6647. TmpData: System.PByte;
  6648. LinePixelsRead: Integer;
  6649. procedure CheckLine;
  6650. begin
  6651. if (LinePixelsRead >= Header.Width) then begin
  6652. LinePixelsRead := 0;
  6653. inc(Counter.Y.low, Counter.Y.dir); //next line index
  6654. TmpData := ImageData;
  6655. inc(TmpData, Counter.Y.low * LineSize); //set line
  6656. if (Counter.X.dir < 0) then //if x flipped then
  6657. inc(TmpData, LineSize - PixelSize); //set last pixel
  6658. end;
  6659. end;
  6660. /////////////////////////////////////////////////////////////////
  6661. var
  6662. Cache: PByte;
  6663. CacheSize, CachePos: Integer;
  6664. procedure CachedRead(out Buffer; Count: Integer);
  6665. var
  6666. BytesRead: Integer;
  6667. begin
  6668. if (CachePos + Count > CacheSize) then begin
  6669. //if buffer overflow save non read bytes
  6670. BytesRead := 0;
  6671. if (CacheSize - CachePos > 0) then begin
  6672. BytesRead := CacheSize - CachePos;
  6673. Move(PByteArray(Cache)^[CachePos], Buffer{%H-}, BytesRead);
  6674. inc(CachePos, BytesRead);
  6675. end;
  6676. //load cache from file
  6677. CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
  6678. aStream.Read(Cache^, CacheSize);
  6679. CachePos := 0;
  6680. //read rest of requested bytes
  6681. if (Count - BytesRead > 0) then begin
  6682. Move(PByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
  6683. inc(CachePos, Count - BytesRead);
  6684. end;
  6685. end else begin
  6686. //if no buffer overflow just read the data
  6687. Move(PByteArray(Cache)^[CachePos], Buffer, Count);
  6688. inc(CachePos, Count);
  6689. end;
  6690. end;
  6691. procedure PixelToBuffer(const aData: PByte; var aBuffer: PByte);
  6692. begin
  6693. case PixelSize of
  6694. 1: begin
  6695. aBuffer^ := aData^;
  6696. inc(aBuffer, Counter.X.dir);
  6697. end;
  6698. 2: begin
  6699. PWord(aBuffer)^ := PWord(aData)^;
  6700. inc(aBuffer, 2 * Counter.X.dir);
  6701. end;
  6702. 3: begin
  6703. PByteArray(aBuffer)^[0] := PByteArray(aData)^[0];
  6704. PByteArray(aBuffer)^[1] := PByteArray(aData)^[1];
  6705. PByteArray(aBuffer)^[2] := PByteArray(aData)^[2];
  6706. inc(aBuffer, 3 * Counter.X.dir);
  6707. end;
  6708. 4: begin
  6709. PCardinal(aBuffer)^ := PCardinal(aData)^;
  6710. inc(aBuffer, 4 * Counter.X.dir);
  6711. end;
  6712. end;
  6713. end;
  6714. var
  6715. TotalPixelsToRead, TotalPixelsRead: Integer;
  6716. Temp: Byte;
  6717. buf: array [0..3] of Byte; //1 pixel is max 32bit long
  6718. PixelRepeat: Boolean;
  6719. PixelsToRead, PixelCount: Integer;
  6720. begin
  6721. CacheSize := 0;
  6722. CachePos := 0;
  6723. TotalPixelsToRead := Header.Width * Header.Height;
  6724. TotalPixelsRead := 0;
  6725. LinePixelsRead := 0;
  6726. GetMem(Cache, CACHE_SIZE);
  6727. try
  6728. TmpData := ImageData;
  6729. inc(TmpData, Counter.Y.low * LineSize); //set line
  6730. if (Counter.X.dir < 0) then //if x flipped then
  6731. inc(TmpData, LineSize - PixelSize); //set last pixel
  6732. repeat
  6733. //read CommandByte
  6734. CachedRead(Temp, 1);
  6735. PixelRepeat := (Temp and $80) > 0;
  6736. PixelsToRead := (Temp and $7F) + 1;
  6737. inc(TotalPixelsRead, PixelsToRead);
  6738. if PixelRepeat then
  6739. CachedRead(buf[0], PixelSize);
  6740. while (PixelsToRead > 0) do begin
  6741. CheckLine;
  6742. PixelCount := Min(Header.Width - LinePixelsRead, PixelsToRead); //max read to EOL or EOF
  6743. while (PixelCount > 0) do begin
  6744. if not PixelRepeat then
  6745. CachedRead(buf[0], PixelSize);
  6746. PixelToBuffer(@buf[0], TmpData);
  6747. inc(LinePixelsRead);
  6748. dec(PixelsToRead);
  6749. dec(PixelCount);
  6750. end;
  6751. end;
  6752. until (TotalPixelsRead >= TotalPixelsToRead);
  6753. finally
  6754. FreeMem(Cache);
  6755. end;
  6756. end;
  6757. function IsGrayFormat: Boolean;
  6758. begin
  6759. result := Header.ImageType in [TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_GRAY];
  6760. end;
  6761. begin
  6762. result := false;
  6763. // reading header to test file and set cursor back to begin
  6764. StartPosition := aStream.Position;
  6765. aStream.Read(Header{%H-}, SizeOf(Header));
  6766. // no colormapped files
  6767. if (Header.ColorMapType = TGA_NONE_COLOR_TABLE) and (Header.ImageType in [
  6768. TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY]) then
  6769. begin
  6770. try
  6771. if Header.ImageID <> 0 then // skip image ID
  6772. aStream.Position := aStream.Position + Header.ImageID;
  6773. tgaFormat := tfEmpty;
  6774. case Header.Bpp of
  6775. 8: if IsGrayFormat then case (Header.ImageDesc and $F) of
  6776. 0: tgaFormat := tfLuminance8ub1;
  6777. 8: tgaFormat := tfAlpha8ub1;
  6778. end;
  6779. 16: if IsGrayFormat then case (Header.ImageDesc and $F) of
  6780. 0: tgaFormat := tfLuminance16us1;
  6781. 8: tgaFormat := tfLuminance8Alpha8ub2;
  6782. end else case (Header.ImageDesc and $F) of
  6783. 0: tgaFormat := tfX1RGB5us1;
  6784. 1: tgaFormat := tfA1RGB5us1;
  6785. 4: tgaFormat := tfARGB4us1;
  6786. end;
  6787. 24: if not IsGrayFormat then case (Header.ImageDesc and $F) of
  6788. 0: tgaFormat := tfBGR8ub3;
  6789. end;
  6790. 32: if IsGrayFormat then case (Header.ImageDesc and $F) of
  6791. 0: tgaFormat := tfDepth32ui1;
  6792. end else case (Header.ImageDesc and $F) of
  6793. 0: tgaFormat := tfX2RGB10ui1;
  6794. 2: tgaFormat := tfA2RGB10ui1;
  6795. 8: tgaFormat := tfARGB8ui1;
  6796. end;
  6797. end;
  6798. if (tgaFormat = tfEmpty) then
  6799. raise EglBitmap.Create('LoadTga - unsupported format');
  6800. FormatDesc := TFormatDescriptor.Get(tgaFormat);
  6801. PixelSize := FormatDesc.GetSize(1, 1);
  6802. LineSize := FormatDesc.GetSize(Header.Width, 1);
  6803. GetMem(ImageData, LineSize * Header.Height);
  6804. try
  6805. //column direction
  6806. if ((Header.ImageDesc and (1 shl 4)) > 0) then begin
  6807. Counter.X.low := Header.Height-1;;
  6808. Counter.X.high := 0;
  6809. Counter.X.dir := -1;
  6810. end else begin
  6811. Counter.X.low := 0;
  6812. Counter.X.high := Header.Height-1;
  6813. Counter.X.dir := 1;
  6814. end;
  6815. // Row direction
  6816. if ((Header.ImageDesc and (1 shl 5)) > 0) then begin
  6817. Counter.Y.low := 0;
  6818. Counter.Y.high := Header.Height-1;
  6819. Counter.Y.dir := 1;
  6820. end else begin
  6821. Counter.Y.low := Header.Height-1;;
  6822. Counter.Y.high := 0;
  6823. Counter.Y.dir := -1;
  6824. end;
  6825. // Read Image
  6826. case Header.ImageType of
  6827. TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY:
  6828. ReadUncompressed;
  6829. TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY:
  6830. ReadCompressed;
  6831. end;
  6832. SetDataPointer(ImageData, tgaFormat, Header.Width, Header.Height); //be careful, Data could be freed by this method
  6833. result := true;
  6834. except
  6835. if Assigned(ImageData) then
  6836. FreeMem(ImageData);
  6837. raise;
  6838. end;
  6839. finally
  6840. aStream.Position := StartPosition;
  6841. end;
  6842. end
  6843. else aStream.Position := StartPosition;
  6844. end;
  6845. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6846. procedure TglBitmap.SaveTGA(const aStream: TStream);
  6847. var
  6848. Header: TTGAHeader;
  6849. Size: Integer;
  6850. FormatDesc: TFormatDescriptor;
  6851. begin
  6852. if not (ftTGA in FormatGetSupportedFiles(Format)) then
  6853. raise EglBitmapUnsupportedFormat.Create(Format);
  6854. //prepare header
  6855. FormatDesc := TFormatDescriptor.Get(Format);
  6856. FillChar(Header{%H-}, SizeOf(Header), 0);
  6857. Header.ImageDesc := CountSetBits(FormatDesc.Range.a) and $F;
  6858. Header.Bpp := FormatDesc.BitsPerPixel;
  6859. Header.Width := Width;
  6860. Header.Height := Height;
  6861. Header.ImageDesc := Header.ImageDesc or $20; //flip y
  6862. if FormatDesc.IsGrayscale or (not FormatDesc.IsGrayscale and not FormatDesc.HasRed and FormatDesc.HasAlpha) then
  6863. Header.ImageType := TGA_UNCOMPRESSED_GRAY
  6864. else
  6865. Header.ImageType := TGA_UNCOMPRESSED_RGB;
  6866. aStream.Write(Header, SizeOf(Header));
  6867. // write Data
  6868. Size := FormatDesc.GetSize(Dimension);
  6869. aStream.Write(Data^, Size);
  6870. end;
  6871. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6872. //DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6873. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6874. const
  6875. DDS_MAGIC: Cardinal = $20534444;
  6876. // DDS_header.dwFlags
  6877. DDSD_CAPS = $00000001;
  6878. DDSD_HEIGHT = $00000002;
  6879. DDSD_WIDTH = $00000004;
  6880. DDSD_PIXELFORMAT = $00001000;
  6881. // DDS_header.sPixelFormat.dwFlags
  6882. DDPF_ALPHAPIXELS = $00000001;
  6883. DDPF_ALPHA = $00000002;
  6884. DDPF_FOURCC = $00000004;
  6885. DDPF_RGB = $00000040;
  6886. DDPF_LUMINANCE = $00020000;
  6887. // DDS_header.sCaps.dwCaps1
  6888. DDSCAPS_TEXTURE = $00001000;
  6889. // DDS_header.sCaps.dwCaps2
  6890. DDSCAPS2_CUBEMAP = $00000200;
  6891. D3DFMT_DXT1 = $31545844;
  6892. D3DFMT_DXT3 = $33545844;
  6893. D3DFMT_DXT5 = $35545844;
  6894. type
  6895. TDDSPixelFormat = packed record
  6896. dwSize: Cardinal;
  6897. dwFlags: Cardinal;
  6898. dwFourCC: Cardinal;
  6899. dwRGBBitCount: Cardinal;
  6900. dwRBitMask: Cardinal;
  6901. dwGBitMask: Cardinal;
  6902. dwBBitMask: Cardinal;
  6903. dwABitMask: Cardinal;
  6904. end;
  6905. TDDSCaps = packed record
  6906. dwCaps1: Cardinal;
  6907. dwCaps2: Cardinal;
  6908. dwDDSX: Cardinal;
  6909. dwReserved: Cardinal;
  6910. end;
  6911. TDDSHeader = packed record
  6912. dwSize: Cardinal;
  6913. dwFlags: Cardinal;
  6914. dwHeight: Cardinal;
  6915. dwWidth: Cardinal;
  6916. dwPitchOrLinearSize: Cardinal;
  6917. dwDepth: Cardinal;
  6918. dwMipMapCount: Cardinal;
  6919. dwReserved: array[0..10] of Cardinal;
  6920. PixelFormat: TDDSPixelFormat;
  6921. Caps: TDDSCaps;
  6922. dwReserved2: Cardinal;
  6923. end;
  6924. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6925. function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
  6926. var
  6927. Header: TDDSHeader;
  6928. Converter: TbmpBitfieldFormat;
  6929. function GetDDSFormat: TglBitmapFormat;
  6930. var
  6931. fd: TFormatDescriptor;
  6932. i: Integer;
  6933. Mask: TglBitmapRec4ul;
  6934. Range: TglBitmapRec4ui;
  6935. match: Boolean;
  6936. begin
  6937. result := tfEmpty;
  6938. with Header.PixelFormat do begin
  6939. // Compresses
  6940. if ((dwFlags and DDPF_FOURCC) > 0) then begin
  6941. case Header.PixelFormat.dwFourCC of
  6942. D3DFMT_DXT1: result := tfS3tcDtx1RGBA;
  6943. D3DFMT_DXT3: result := tfS3tcDtx3RGBA;
  6944. D3DFMT_DXT5: result := tfS3tcDtx5RGBA;
  6945. end;
  6946. end else if ((dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE or DDPF_ALPHA)) > 0) then begin
  6947. // prepare masks
  6948. if ((dwFlags and DDPF_LUMINANCE) = 0) then begin
  6949. Mask.r := dwRBitMask;
  6950. Mask.g := dwGBitMask;
  6951. Mask.b := dwBBitMask;
  6952. end else begin
  6953. Mask.r := dwRBitMask;
  6954. Mask.g := dwRBitMask;
  6955. Mask.b := dwRBitMask;
  6956. end;
  6957. if (dwFlags and DDPF_ALPHAPIXELS > 0) then
  6958. Mask.a := dwABitMask
  6959. else
  6960. Mask.a := 0;;
  6961. //find matching format
  6962. fd := TFormatDescriptor.GetFromMask(Mask, dwRGBBitCount);
  6963. result := fd.Format;
  6964. if (result <> tfEmpty) then
  6965. exit;
  6966. //find format with same Range
  6967. for i := 0 to 3 do
  6968. Range.arr[i] := (2 shl CountSetBits(Mask.arr[i])) - 1;
  6969. for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
  6970. fd := TFormatDescriptor.Get(result);
  6971. match := true;
  6972. for i := 0 to 3 do
  6973. if (fd.Range.arr[i] <> Range.arr[i]) then begin
  6974. match := false;
  6975. break;
  6976. end;
  6977. if match then
  6978. break;
  6979. end;
  6980. //no format with same range found -> use default
  6981. if (result = tfEmpty) then begin
  6982. if (dwABitMask > 0) then
  6983. result := tfRGBA8ui1
  6984. else
  6985. result := tfRGB8ub3;
  6986. end;
  6987. Converter := TbmpBitfieldFormat.Create;
  6988. Converter.SetCustomValues(dwRGBBitCount, glBitmapRec4ul(dwRBitMask, dwGBitMask, dwBBitMask, dwABitMask));
  6989. end;
  6990. end;
  6991. end;
  6992. var
  6993. StreamPos: Int64;
  6994. x, y, LineSize, RowSize, Magic: Cardinal;
  6995. NewImage, TmpData, RowData, SrcData: System.PByte;
  6996. SourceMD, DestMD: Pointer;
  6997. Pixel: TglBitmapPixelData;
  6998. ddsFormat: TglBitmapFormat;
  6999. FormatDesc: TFormatDescriptor;
  7000. begin
  7001. result := false;
  7002. Converter := nil;
  7003. StreamPos := aStream.Position;
  7004. // Magic
  7005. aStream.Read(Magic{%H-}, sizeof(Magic));
  7006. if (Magic <> DDS_MAGIC) then begin
  7007. aStream.Position := StreamPos;
  7008. exit;
  7009. end;
  7010. //Header
  7011. aStream.Read(Header{%H-}, sizeof(Header));
  7012. if (Header.dwSize <> SizeOf(Header)) or
  7013. ((Header.dwFlags and (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) <>
  7014. (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) then
  7015. begin
  7016. aStream.Position := StreamPos;
  7017. exit;
  7018. end;
  7019. if ((Header.Caps.dwCaps1 and DDSCAPS2_CUBEMAP) > 0) then
  7020. raise EglBitmap.Create('LoadDDS - CubeMaps are not supported');
  7021. ddsFormat := GetDDSFormat;
  7022. try
  7023. if (ddsFormat = tfEmpty) then
  7024. raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
  7025. FormatDesc := TFormatDescriptor.Get(ddsFormat);
  7026. LineSize := Trunc(Header.dwWidth * FormatDesc.BytesPerPixel);
  7027. GetMem(NewImage, Header.dwHeight * LineSize);
  7028. try
  7029. TmpData := NewImage;
  7030. //Converter needed
  7031. if Assigned(Converter) then begin
  7032. RowSize := Round(Header.dwWidth * Header.PixelFormat.dwRGBBitCount / 8);
  7033. GetMem(RowData, RowSize);
  7034. SourceMD := Converter.CreateMappingData;
  7035. DestMD := FormatDesc.CreateMappingData;
  7036. try
  7037. for y := 0 to Header.dwHeight-1 do begin
  7038. TmpData := NewImage;
  7039. inc(TmpData, y * LineSize);
  7040. SrcData := RowData;
  7041. aStream.Read(SrcData^, RowSize);
  7042. for x := 0 to Header.dwWidth-1 do begin
  7043. Converter.Unmap(SrcData, Pixel, SourceMD);
  7044. glBitmapConvertPixel(Pixel, Converter, FormatDesc);
  7045. FormatDesc.Map(Pixel, TmpData, DestMD);
  7046. end;
  7047. end;
  7048. finally
  7049. Converter.FreeMappingData(SourceMD);
  7050. FormatDesc.FreeMappingData(DestMD);
  7051. FreeMem(RowData);
  7052. end;
  7053. end else
  7054. // Compressed
  7055. if ((Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0) then begin
  7056. RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
  7057. for Y := 0 to Header.dwHeight-1 do begin
  7058. aStream.Read(TmpData^, RowSize);
  7059. Inc(TmpData, LineSize);
  7060. end;
  7061. end else
  7062. // Uncompressed
  7063. if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0 then begin
  7064. RowSize := (Header.PixelFormat.dwRGBBitCount * Header.dwWidth) shr 3;
  7065. for Y := 0 to Header.dwHeight-1 do begin
  7066. aStream.Read(TmpData^, RowSize);
  7067. Inc(TmpData, LineSize);
  7068. end;
  7069. end else
  7070. raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
  7071. SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight); //be careful, Data could be freed by this method
  7072. result := true;
  7073. except
  7074. if Assigned(NewImage) then
  7075. FreeMem(NewImage);
  7076. raise;
  7077. end;
  7078. finally
  7079. FreeAndNil(Converter);
  7080. end;
  7081. end;
  7082. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7083. procedure TglBitmap.SaveDDS(const aStream: TStream);
  7084. var
  7085. Header: TDDSHeader;
  7086. FormatDesc: TFormatDescriptor;
  7087. begin
  7088. if not (ftDDS in FormatGetSupportedFiles(Format)) then
  7089. raise EglBitmapUnsupportedFormat.Create(Format);
  7090. FormatDesc := TFormatDescriptor.Get(Format);
  7091. // Generell
  7092. FillChar(Header{%H-}, SizeOf(Header), 0);
  7093. Header.dwSize := SizeOf(Header);
  7094. Header.dwFlags := DDSD_WIDTH or DDSD_HEIGHT or DDSD_CAPS or DDSD_PIXELFORMAT;
  7095. Header.dwWidth := Max(1, Width);
  7096. Header.dwHeight := Max(1, Height);
  7097. // Caps
  7098. Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
  7099. // Pixelformat
  7100. Header.PixelFormat.dwSize := sizeof(Header);
  7101. if (FormatDesc.IsCompressed) then begin
  7102. Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_FOURCC;
  7103. case Format of
  7104. tfS3tcDtx1RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT1;
  7105. tfS3tcDtx3RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT3;
  7106. tfS3tcDtx5RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT5;
  7107. end;
  7108. end else if not FormatDesc.HasColor and FormatDesc.HasAlpha then begin
  7109. Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHA;
  7110. Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
  7111. Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
  7112. end else if FormatDesc.IsGrayscale then begin
  7113. Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_LUMINANCE;
  7114. Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
  7115. Header.PixelFormat.dwRBitMask := FormatDesc.Mask.r;
  7116. Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
  7117. end else begin
  7118. Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_RGB;
  7119. Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
  7120. Header.PixelFormat.dwRBitMask := FormatDesc.Mask.r;
  7121. Header.PixelFormat.dwGBitMask := FormatDesc.Mask.g;
  7122. Header.PixelFormat.dwBBitMask := FormatDesc.Mask.b;
  7123. Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
  7124. end;
  7125. if (FormatDesc.HasAlpha) then
  7126. Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
  7127. aStream.Write(DDS_MAGIC, sizeof(DDS_MAGIC));
  7128. aStream.Write(Header, SizeOf(Header));
  7129. aStream.Write(Data^, FormatDesc.GetSize(Dimension));
  7130. end;
  7131. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7132. //TglBitmap1D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7133. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7134. procedure TglBitmap1D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
  7135. const aWidth: Integer; const aHeight: Integer);
  7136. var
  7137. pTemp: pByte;
  7138. Size: Integer;
  7139. begin
  7140. if (aHeight > 1) then begin
  7141. Size := TFormatDescriptor.Get(aFormat).GetSize(aWidth, 1);
  7142. GetMem(pTemp, Size);
  7143. try
  7144. Move(aData^, pTemp^, Size);
  7145. FreeMem(aData);
  7146. aData := nil;
  7147. except
  7148. FreeMem(pTemp);
  7149. raise;
  7150. end;
  7151. end else
  7152. pTemp := aData;
  7153. inherited SetDataPointer(pTemp, aFormat, aWidth);
  7154. end;
  7155. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7156. function TglBitmap1D.FlipHorz: Boolean;
  7157. var
  7158. Col: Integer;
  7159. pTempDest, pDest, pSource: PByte;
  7160. begin
  7161. result := inherited FlipHorz;
  7162. if Assigned(Data) and not TFormatDescriptor.Get(Format).IsCompressed then begin
  7163. pSource := Data;
  7164. GetMem(pDest, fRowSize);
  7165. try
  7166. pTempDest := pDest;
  7167. Inc(pTempDest, fRowSize);
  7168. for Col := 0 to Width-1 do begin
  7169. dec(pTempDest, fPixelSize); //dec before, because ptr is behind last byte of data
  7170. Move(pSource^, pTempDest^, fPixelSize);
  7171. Inc(pSource, fPixelSize);
  7172. end;
  7173. SetDataPointer(pDest, Format, Width); //be careful, Data could be freed by this method
  7174. result := true;
  7175. except
  7176. if Assigned(pDest) then
  7177. FreeMem(pDest);
  7178. raise;
  7179. end;
  7180. end;
  7181. end;
  7182. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7183. procedure TglBitmap1D.UploadData(const aBuildWithGlu: Boolean);
  7184. var
  7185. FormatDesc: TFormatDescriptor;
  7186. begin
  7187. // Upload data
  7188. FormatDesc := TFormatDescriptor.Get(Format);
  7189. if FormatDesc.IsCompressed then begin
  7190. if not Assigned(glCompressedTexImage1D) then
  7191. raise EglBitmap.Create('compressed formats not supported by video adapter');
  7192. glCompressedTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.GetSize(Width, 1), Data)
  7193. end else if aBuildWithGlu then
  7194. gluBuild1DMipmaps(Target, FormatDesc.glInternalFormat, Width, FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
  7195. else
  7196. glTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
  7197. // Free Data
  7198. if (FreeDataAfterGenTexture) then
  7199. FreeData;
  7200. end;
  7201. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7202. procedure TglBitmap1D.GenTexture(const aTestTextureSize: Boolean);
  7203. var
  7204. BuildWithGlu, TexRec: Boolean;
  7205. TexSize: Integer;
  7206. begin
  7207. if Assigned(Data) then begin
  7208. // Check Texture Size
  7209. if (aTestTextureSize) then begin
  7210. glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
  7211. if (Width > TexSize) then
  7212. raise EglBitmapSizeToLarge.Create('TglBitmap1D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
  7213. TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
  7214. (Target = GL_TEXTURE_RECTANGLE);
  7215. if not (IsPowerOfTwo(Width) or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
  7216. raise EglBitmapNonPowerOfTwo.Create('TglBitmap1D.GenTexture - Rendercontex dosn''t support non power of two texture.');
  7217. end;
  7218. CreateId;
  7219. SetupParameters(BuildWithGlu);
  7220. UploadData(BuildWithGlu);
  7221. glAreTexturesResident(1, @fID, @fIsResident);
  7222. end;
  7223. end;
  7224. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7225. procedure TglBitmap1D.AfterConstruction;
  7226. begin
  7227. inherited;
  7228. Target := GL_TEXTURE_1D;
  7229. end;
  7230. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7231. //TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7232. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7233. function TglBitmap2D.GetScanline(const aIndex: Integer): Pointer;
  7234. begin
  7235. if (aIndex >= Low(fLines)) and (aIndex <= High(fLines)) then
  7236. result := fLines[aIndex]
  7237. else
  7238. result := nil;
  7239. end;
  7240. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7241. procedure TglBitmap2D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
  7242. const aWidth: Integer; const aHeight: Integer);
  7243. var
  7244. Idx, LineWidth: Integer;
  7245. begin
  7246. inherited SetDataPointer(aData, aFormat, aWidth, aHeight);
  7247. if not TFormatDescriptor.Get(aFormat).IsCompressed then begin
  7248. // Assigning Data
  7249. if Assigned(Data) then begin
  7250. SetLength(fLines, GetHeight);
  7251. LineWidth := Trunc(GetWidth * TFormatDescriptor.Get(Format).BytesPerPixel);
  7252. for Idx := 0 to GetHeight-1 do begin
  7253. fLines[Idx] := Data;
  7254. Inc(fLines[Idx], Idx * LineWidth);
  7255. end;
  7256. end
  7257. else SetLength(fLines, 0);
  7258. end else begin
  7259. SetLength(fLines, 0);
  7260. end;
  7261. end;
  7262. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7263. procedure TglBitmap2D.UploadData(const aTarget: GLenum; const aBuildWithGlu: Boolean);
  7264. var
  7265. FormatDesc: TFormatDescriptor;
  7266. begin
  7267. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  7268. FormatDesc := TFormatDescriptor.Get(Format);
  7269. if FormatDesc.IsCompressed then begin
  7270. if not Assigned(glCompressedTexImage2D) then
  7271. raise EglBitmap.Create('compressed formats not supported by video adapter');
  7272. glCompressedTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0, FormatDesc.GetSize(fDimension), Data)
  7273. end else if aBuildWithGlu then begin
  7274. gluBuild2DMipmaps(aTarget, FormatDesc.ChannelCount, Width, Height,
  7275. FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
  7276. end else begin
  7277. glTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0,
  7278. FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
  7279. end;
  7280. // Freigeben
  7281. if (FreeDataAfterGenTexture) then
  7282. FreeData;
  7283. end;
  7284. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7285. procedure TglBitmap2D.AfterConstruction;
  7286. begin
  7287. inherited;
  7288. Target := GL_TEXTURE_2D;
  7289. end;
  7290. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7291. procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
  7292. var
  7293. Temp: pByte;
  7294. Size, w, h: Integer;
  7295. FormatDesc: TFormatDescriptor;
  7296. begin
  7297. FormatDesc := TFormatDescriptor.Get(aFormat);
  7298. if FormatDesc.IsCompressed then
  7299. raise EglBitmapUnsupportedFormat.Create(aFormat);
  7300. w := aRight - aLeft;
  7301. h := aBottom - aTop;
  7302. Size := FormatDesc.GetSize(w, h);
  7303. GetMem(Temp, Size);
  7304. try
  7305. glPixelStorei(GL_PACK_ALIGNMENT, 1);
  7306. glReadPixels(aLeft, aTop, w, h, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
  7307. SetDataPointer(Temp, aFormat, w, h); //be careful, Data could be freed by this method
  7308. FlipVert;
  7309. except
  7310. if Assigned(Temp) then
  7311. FreeMem(Temp);
  7312. raise;
  7313. end;
  7314. end;
  7315. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7316. procedure TglBitmap2D.GetDataFromTexture;
  7317. var
  7318. Temp: PByte;
  7319. TempWidth, TempHeight: Integer;
  7320. TempIntFormat: GLint;
  7321. IntFormat: TglBitmapFormat;
  7322. FormatDesc: TFormatDescriptor;
  7323. begin
  7324. Bind;
  7325. // Request Data
  7326. glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
  7327. glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
  7328. glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
  7329. FormatDesc := (TglBitmapFormatDescriptor.GetByFormat(TempIntFormat) as TFormatDescriptor);
  7330. IntFormat := FormatDesc.Format;
  7331. // Getting data from OpenGL
  7332. FormatDesc := TFormatDescriptor.Get(IntFormat);
  7333. GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
  7334. try
  7335. if FormatDesc.IsCompressed then begin
  7336. if not Assigned(glGetCompressedTexImage) then
  7337. raise EglBitmap.Create('compressed formats not supported by video adapter');
  7338. glGetCompressedTexImage(Target, 0, Temp)
  7339. end else
  7340. glGetTexImage(Target, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
  7341. SetDataPointer(Temp, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
  7342. except
  7343. if Assigned(Temp) then
  7344. FreeMem(Temp);
  7345. raise;
  7346. end;
  7347. end;
  7348. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7349. procedure TglBitmap2D.GenTexture(const aTestTextureSize: Boolean);
  7350. var
  7351. BuildWithGlu, PotTex, TexRec: Boolean;
  7352. TexSize: Integer;
  7353. begin
  7354. if Assigned(Data) then begin
  7355. // Check Texture Size
  7356. if (aTestTextureSize) then begin
  7357. glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
  7358. if ((Height > TexSize) or (Width > TexSize)) then
  7359. raise EglBitmapSizeToLarge.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
  7360. PotTex := IsPowerOfTwo(Height) and IsPowerOfTwo(Width);
  7361. TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE);
  7362. if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
  7363. raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
  7364. end;
  7365. CreateId;
  7366. SetupParameters(BuildWithGlu);
  7367. UploadData(Target, BuildWithGlu);
  7368. glAreTexturesResident(1, @fID, @fIsResident);
  7369. end;
  7370. end;
  7371. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7372. function TglBitmap2D.FlipHorz: Boolean;
  7373. var
  7374. Col, Row: Integer;
  7375. TempDestData, DestData, SourceData: PByte;
  7376. ImgSize: Integer;
  7377. begin
  7378. result := inherited FlipHorz;
  7379. if Assigned(Data) then begin
  7380. SourceData := Data;
  7381. ImgSize := Height * fRowSize;
  7382. GetMem(DestData, ImgSize);
  7383. try
  7384. TempDestData := DestData;
  7385. Dec(TempDestData, fRowSize + fPixelSize);
  7386. for Row := 0 to Height -1 do begin
  7387. Inc(TempDestData, fRowSize * 2);
  7388. for Col := 0 to Width -1 do begin
  7389. Move(SourceData^, TempDestData^, fPixelSize);
  7390. Inc(SourceData, fPixelSize);
  7391. Dec(TempDestData, fPixelSize);
  7392. end;
  7393. end;
  7394. SetDataPointer(DestData, Format, Width, Height); //be careful, Data could be freed by this method
  7395. result := true;
  7396. except
  7397. if Assigned(DestData) then
  7398. FreeMem(DestData);
  7399. raise;
  7400. end;
  7401. end;
  7402. end;
  7403. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7404. function TglBitmap2D.FlipVert: Boolean;
  7405. var
  7406. Row: Integer;
  7407. TempDestData, DestData, SourceData: PByte;
  7408. begin
  7409. result := inherited FlipVert;
  7410. if Assigned(Data) then begin
  7411. SourceData := Data;
  7412. GetMem(DestData, Height * fRowSize);
  7413. try
  7414. TempDestData := DestData;
  7415. Inc(TempDestData, Width * (Height -1) * fPixelSize);
  7416. for Row := 0 to Height -1 do begin
  7417. Move(SourceData^, TempDestData^, fRowSize);
  7418. Dec(TempDestData, fRowSize);
  7419. Inc(SourceData, fRowSize);
  7420. end;
  7421. SetDataPointer(DestData, Format, Width, Height); //be careful, Data could be freed by this method
  7422. result := true;
  7423. except
  7424. if Assigned(DestData) then
  7425. FreeMem(DestData);
  7426. raise;
  7427. end;
  7428. end;
  7429. end;
  7430. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7431. //TglBitmap2D - ToNormalMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7432. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7433. type
  7434. TMatrixItem = record
  7435. X, Y: Integer;
  7436. W: Single;
  7437. end;
  7438. PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
  7439. TglBitmapToNormalMapRec = Record
  7440. Scale: Single;
  7441. Heights: array of Single;
  7442. MatrixU : array of TMatrixItem;
  7443. MatrixV : array of TMatrixItem;
  7444. end;
  7445. const
  7446. ONE_OVER_255 = 1 / 255;
  7447. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7448. procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
  7449. var
  7450. Val: Single;
  7451. begin
  7452. with FuncRec do begin
  7453. Val :=
  7454. Source.Data.r * LUMINANCE_WEIGHT_R +
  7455. Source.Data.g * LUMINANCE_WEIGHT_G +
  7456. Source.Data.b * LUMINANCE_WEIGHT_B;
  7457. PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255;
  7458. end;
  7459. end;
  7460. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7461. procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
  7462. begin
  7463. with FuncRec do
  7464. PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
  7465. end;
  7466. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7467. procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
  7468. type
  7469. TVec = Array[0..2] of Single;
  7470. var
  7471. Idx: Integer;
  7472. du, dv: Double;
  7473. Len: Single;
  7474. Vec: TVec;
  7475. function GetHeight(X, Y: Integer): Single;
  7476. begin
  7477. with FuncRec do begin
  7478. X := Max(0, Min(Size.X -1, X));
  7479. Y := Max(0, Min(Size.Y -1, Y));
  7480. result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
  7481. end;
  7482. end;
  7483. begin
  7484. with FuncRec do begin
  7485. with PglBitmapToNormalMapRec(Args)^ do begin
  7486. du := 0;
  7487. for Idx := Low(MatrixU) to High(MatrixU) do
  7488. du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
  7489. dv := 0;
  7490. for Idx := Low(MatrixU) to High(MatrixU) do
  7491. dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
  7492. Vec[0] := -du * Scale;
  7493. Vec[1] := -dv * Scale;
  7494. Vec[2] := 1;
  7495. end;
  7496. // Normalize
  7497. Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
  7498. if Len <> 0 then begin
  7499. Vec[0] := Vec[0] * Len;
  7500. Vec[1] := Vec[1] * Len;
  7501. Vec[2] := Vec[2] * Len;
  7502. end;
  7503. // Farbe zuweisem
  7504. Dest.Data.r := Trunc((Vec[0] + 1) * 127.5);
  7505. Dest.Data.g := Trunc((Vec[1] + 1) * 127.5);
  7506. Dest.Data.b := Trunc((Vec[2] + 1) * 127.5);
  7507. end;
  7508. end;
  7509. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7510. procedure TglBitmap2D.ToNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
  7511. var
  7512. Rec: TglBitmapToNormalMapRec;
  7513. procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
  7514. begin
  7515. if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
  7516. Matrix[Index].X := X;
  7517. Matrix[Index].Y := Y;
  7518. Matrix[Index].W := W;
  7519. end;
  7520. end;
  7521. begin
  7522. if TFormatDescriptor.Get(Format).IsCompressed then
  7523. raise EglBitmapUnsupportedFormat.Create(Format);
  7524. if aScale > 100 then
  7525. Rec.Scale := 100
  7526. else if aScale < -100 then
  7527. Rec.Scale := -100
  7528. else
  7529. Rec.Scale := aScale;
  7530. SetLength(Rec.Heights, Width * Height);
  7531. try
  7532. case aFunc of
  7533. nm4Samples: begin
  7534. SetLength(Rec.MatrixU, 2);
  7535. SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
  7536. SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
  7537. SetLength(Rec.MatrixV, 2);
  7538. SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
  7539. SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
  7540. end;
  7541. nmSobel: begin
  7542. SetLength(Rec.MatrixU, 6);
  7543. SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
  7544. SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
  7545. SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
  7546. SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
  7547. SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
  7548. SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
  7549. SetLength(Rec.MatrixV, 6);
  7550. SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
  7551. SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
  7552. SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
  7553. SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
  7554. SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
  7555. SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
  7556. end;
  7557. nm3x3: begin
  7558. SetLength(Rec.MatrixU, 6);
  7559. SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
  7560. SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
  7561. SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
  7562. SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
  7563. SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
  7564. SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
  7565. SetLength(Rec.MatrixV, 6);
  7566. SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
  7567. SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
  7568. SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
  7569. SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
  7570. SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
  7571. SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
  7572. end;
  7573. nm5x5: begin
  7574. SetLength(Rec.MatrixU, 20);
  7575. SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
  7576. SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
  7577. SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
  7578. SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
  7579. SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
  7580. SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
  7581. SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
  7582. SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
  7583. SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
  7584. SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
  7585. SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
  7586. SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
  7587. SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
  7588. SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
  7589. SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
  7590. SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
  7591. SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
  7592. SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
  7593. SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
  7594. SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
  7595. SetLength(Rec.MatrixV, 20);
  7596. SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
  7597. SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
  7598. SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
  7599. SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
  7600. SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
  7601. SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
  7602. SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
  7603. SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
  7604. SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
  7605. SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
  7606. SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
  7607. SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
  7608. SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
  7609. SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
  7610. SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
  7611. SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
  7612. SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
  7613. SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
  7614. SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
  7615. SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
  7616. end;
  7617. end;
  7618. // Daten Sammeln
  7619. if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
  7620. AddFunc(glBitmapToNormalMapPrepareAlphaFunc, false, @Rec)
  7621. else
  7622. AddFunc(glBitmapToNormalMapPrepareFunc, false, @Rec);
  7623. AddFunc(glBitmapToNormalMapFunc, false, @Rec);
  7624. finally
  7625. SetLength(Rec.Heights, 0);
  7626. end;
  7627. end;
  7628. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7629. //TglBitmapCubeMap////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7630. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7631. procedure TglBitmapCubeMap.GenTexture(const aTestTextureSize: Boolean);
  7632. begin
  7633. Assert(false, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
  7634. end;
  7635. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7636. procedure TglBitmapCubeMap.AfterConstruction;
  7637. begin
  7638. inherited;
  7639. if not (GL_VERSION_1_3 or GL_ARB_texture_cube_map or GL_EXT_texture_cube_map) then
  7640. raise EglBitmap.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
  7641. SetWrap;
  7642. Target := GL_TEXTURE_CUBE_MAP;
  7643. fGenMode := GL_REFLECTION_MAP;
  7644. end;
  7645. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7646. procedure TglBitmapCubeMap.GenerateCubeMap(const aCubeTarget: Cardinal; const aTestTextureSize: Boolean);
  7647. var
  7648. BuildWithGlu: Boolean;
  7649. TexSize: Integer;
  7650. begin
  7651. if (aTestTextureSize) then begin
  7652. glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @TexSize);
  7653. if (Height > TexSize) or (Width > TexSize) then
  7654. raise EglBitmapSizeToLarge.Create('TglBitmapCubeMap.GenTexture - The size for the Cubemap is to large. It''s may be not conform with the Hardware.');
  7655. if not ((IsPowerOfTwo(Height) and IsPowerOfTwo(Width)) or GL_VERSION_2_0 or GL_ARB_texture_non_power_of_two) then
  7656. raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenTexture - Cubemaps dosn''t support non power of two texture.');
  7657. end;
  7658. if (ID = 0) then
  7659. CreateID;
  7660. SetupParameters(BuildWithGlu);
  7661. UploadData(aCubeTarget, BuildWithGlu);
  7662. end;
  7663. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7664. procedure TglBitmapCubeMap.Bind(const aEnableTexCoordsGen: Boolean; const aEnableTextureUnit: Boolean);
  7665. begin
  7666. inherited Bind (aEnableTextureUnit);
  7667. if aEnableTexCoordsGen then begin
  7668. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, fGenMode);
  7669. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, fGenMode);
  7670. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, fGenMode);
  7671. glEnable(GL_TEXTURE_GEN_S);
  7672. glEnable(GL_TEXTURE_GEN_T);
  7673. glEnable(GL_TEXTURE_GEN_R);
  7674. end;
  7675. end;
  7676. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7677. procedure TglBitmapCubeMap.Unbind(const aDisableTexCoordsGen: Boolean; const aDisableTextureUnit: Boolean);
  7678. begin
  7679. inherited Unbind(aDisableTextureUnit);
  7680. if aDisableTexCoordsGen then begin
  7681. glDisable(GL_TEXTURE_GEN_S);
  7682. glDisable(GL_TEXTURE_GEN_T);
  7683. glDisable(GL_TEXTURE_GEN_R);
  7684. end;
  7685. end;
  7686. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7687. //TglBitmapNormalMap//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7688. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7689. type
  7690. TVec = Array[0..2] of Single;
  7691. TglBitmapNormalMapGetVectorFunc = procedure (out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
  7692. PglBitmapNormalMapRec = ^TglBitmapNormalMapRec;
  7693. TglBitmapNormalMapRec = record
  7694. HalfSize : Integer;
  7695. Func: TglBitmapNormalMapGetVectorFunc;
  7696. end;
  7697. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7698. procedure glBitmapNormalMapPosX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
  7699. begin
  7700. aVec[0] := aHalfSize;
  7701. aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
  7702. aVec[2] := - (aPosition.X + 0.5 - aHalfSize);
  7703. end;
  7704. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7705. procedure glBitmapNormalMapNegX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
  7706. begin
  7707. aVec[0] := - aHalfSize;
  7708. aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
  7709. aVec[2] := aPosition.X + 0.5 - aHalfSize;
  7710. end;
  7711. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7712. procedure glBitmapNormalMapPosY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
  7713. begin
  7714. aVec[0] := aPosition.X + 0.5 - aHalfSize;
  7715. aVec[1] := aHalfSize;
  7716. aVec[2] := aPosition.Y + 0.5 - aHalfSize;
  7717. end;
  7718. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7719. procedure glBitmapNormalMapNegY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
  7720. begin
  7721. aVec[0] := aPosition.X + 0.5 - aHalfSize;
  7722. aVec[1] := - aHalfSize;
  7723. aVec[2] := - (aPosition.Y + 0.5 - aHalfSize);
  7724. end;
  7725. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7726. procedure glBitmapNormalMapPosZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
  7727. begin
  7728. aVec[0] := aPosition.X + 0.5 - aHalfSize;
  7729. aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
  7730. aVec[2] := aHalfSize;
  7731. end;
  7732. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7733. procedure glBitmapNormalMapNegZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
  7734. begin
  7735. aVec[0] := - (aPosition.X + 0.5 - aHalfSize);
  7736. aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
  7737. aVec[2] := - aHalfSize;
  7738. end;
  7739. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7740. procedure glBitmapNormalMapFunc(var FuncRec: TglBitmapFunctionRec);
  7741. var
  7742. i: Integer;
  7743. Vec: TVec;
  7744. Len: Single;
  7745. begin
  7746. with FuncRec do begin
  7747. with PglBitmapNormalMapRec(Args)^ do begin
  7748. Func(Vec, Position, HalfSize);
  7749. // Normalize
  7750. Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
  7751. if Len <> 0 then begin
  7752. Vec[0] := Vec[0] * Len;
  7753. Vec[1] := Vec[1] * Len;
  7754. Vec[2] := Vec[2] * Len;
  7755. end;
  7756. // Scale Vector and AddVectro
  7757. Vec[0] := Vec[0] * 0.5 + 0.5;
  7758. Vec[1] := Vec[1] * 0.5 + 0.5;
  7759. Vec[2] := Vec[2] * 0.5 + 0.5;
  7760. end;
  7761. // Set Color
  7762. for i := 0 to 2 do
  7763. Dest.Data.arr[i] := Round(Vec[i] * 255);
  7764. end;
  7765. end;
  7766. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7767. procedure TglBitmapNormalMap.AfterConstruction;
  7768. begin
  7769. inherited;
  7770. fGenMode := GL_NORMAL_MAP;
  7771. end;
  7772. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7773. procedure TglBitmapNormalMap.GenerateNormalMap(const aSize: Integer; const aTestTextureSize: Boolean);
  7774. var
  7775. Rec: TglBitmapNormalMapRec;
  7776. SizeRec: TglBitmapPixelPosition;
  7777. begin
  7778. Rec.HalfSize := aSize div 2;
  7779. FreeDataAfterGenTexture := false;
  7780. SizeRec.Fields := [ffX, ffY];
  7781. SizeRec.X := aSize;
  7782. SizeRec.Y := aSize;
  7783. // Positive X
  7784. Rec.Func := glBitmapNormalMapPosX;
  7785. LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
  7786. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X, aTestTextureSize);
  7787. // Negative X
  7788. Rec.Func := glBitmapNormalMapNegX;
  7789. LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
  7790. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, aTestTextureSize);
  7791. // Positive Y
  7792. Rec.Func := glBitmapNormalMapPosY;
  7793. LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
  7794. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, aTestTextureSize);
  7795. // Negative Y
  7796. Rec.Func := glBitmapNormalMapNegY;
  7797. LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
  7798. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, aTestTextureSize);
  7799. // Positive Z
  7800. Rec.Func := glBitmapNormalMapPosZ;
  7801. LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
  7802. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, aTestTextureSize);
  7803. // Negative Z
  7804. Rec.Func := glBitmapNormalMapNegZ;
  7805. LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
  7806. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, aTestTextureSize);
  7807. end;
  7808. initialization
  7809. glBitmapSetDefaultFormat (tfEmpty);
  7810. glBitmapSetDefaultMipmap (mmMipmap);
  7811. glBitmapSetDefaultFilter (GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
  7812. glBitmapSetDefaultWrap (GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
  7813. glBitmapSetDefaultSwizzle(GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA);
  7814. glBitmapSetDefaultFreeDataAfterGenTexture(true);
  7815. glBitmapSetDefaultDeleteTextureOnFree (true);
  7816. TFormatDescriptor.Init;
  7817. {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
  7818. OpenGLInitialized := false;
  7819. InitOpenGLCS := TCriticalSection.Create;
  7820. {$ENDIF}
  7821. finalization
  7822. TFormatDescriptor.Finalize;
  7823. {$IFDEF GLB_NATIVE_OGL}
  7824. if Assigned(GL_LibHandle) then
  7825. glbFreeLibrary(GL_LibHandle);
  7826. {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
  7827. if Assigned(GLU_LibHandle) then
  7828. glbFreeLibrary(GLU_LibHandle);
  7829. FreeAndNil(InitOpenGLCS);
  7830. {$ENDIF}
  7831. {$ENDIF}
  7832. end.