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

7705 líneas
251 KiB

  1. {***********************************************************
  2. glBitmap by Steffen Xonna aka Lossy eX (2003-2008)
  3. http://www.opengl24.de/index.php?cat=header&file=glbitmap
  4. ------------------------------------------------------------
  5. The contents of this file are used with permission, subject to
  6. the Mozilla Public License Version 1.1 (the "License"); you may
  7. not use this file except in compliance with the License. You may
  8. obtain a copy of the License at
  9. http://www.mozilla.org/MPL/MPL-1.1.html
  10. ------------------------------------------------------------
  11. Version 2.0.3
  12. ------------------------------------------------------------
  13. History
  14. 21-03-2010
  15. - The define GLB_DELPHI dosn't check versions anymore. If you say you are using delphi
  16. then it's your problem if that isn't true. This prevents the unit for incompatibility
  17. with newer versions of Delphi.
  18. - Problems with D2009+ resolved (Thanks noeska and all i forgot)
  19. - GetPixel isn't set if you are loading textures inside the constructor (Thanks Wilson)
  20. 10-08-2008
  21. - AddAlphaFromglBitmap used the custom pointer instead the imagedatapointer (Thanks Wilson)
  22. - Additional Datapointer for functioninterface now has the name CustomData
  23. 24-07-2008
  24. - AssigneAlphaToBitmap overwrites his own palette (Thanks Wilson)
  25. - If you load an texture from an file the property Filename will be set to the name of the file
  26. - Three new properties to attach custom data to the Texture objects
  27. - CustomName (free for use string)
  28. - CustomNameW (free for use widestring)
  29. - CustomDataPointer (free for use pointer to attach other objects or complex structures)
  30. 27-05-2008
  31. - RLE TGAs loaded much faster
  32. 26-05-2008
  33. - fixed some problem with reading RLE TGAs.
  34. 21-05-2008
  35. - function clone now only copys data if it's assigned and now it also copies the ID
  36. - it seems that lazarus dont like comments in comments.
  37. 01-05-2008
  38. - It's possible to set the id of the texture
  39. - define GLB_NO_NATIVE_GL deactivated by default
  40. 27-04-2008
  41. - Now supports the following libraries
  42. - SDL and SDL_image
  43. - libPNG
  44. - libJPEG
  45. - Linux compatibillity via free pascal compatibility (delphi sources optional)
  46. - BMPs now loaded manuel
  47. - Large restructuring
  48. - Property DataPtr now has the name Data
  49. - Functions are more flexible between RGB(A) and BGR(A). RGB can be saved as Bitmap and will be saved as BGR
  50. - Unused Depth removed
  51. - Function FreeData to freeing image data added
  52. 24-10-2007
  53. - ImageID flag of TGAs was ignored. (Thanks Zwoetzen)
  54. 15-11-2006
  55. - Function SetBorderColor implemented (only used by opengl if wrap is set to GL_CLAMP_TO_BORDER)
  56. - Function AddAlphaFromValue implemented to use an fixed Value as Alphachannel
  57. - Function ReadOpenGLExtension is now only intern
  58. 29-06-2006
  59. - pngimage now disabled by default like all other versions.
  60. 26-06-2006
  61. - Setting up an anisotropic filter of 0 isnt allowed by nvidia (Thanks Ogridi)
  62. 22-06-2006
  63. - Fixed some Problem with Delphi 5
  64. - Now uses the newest version of pngimage. Makes saving pngs much easier.
  65. 22-03-2006
  66. - Property IsCompressed and Size removed. Not really supported by Spec (Thanks Ogridi)
  67. 09-03-2006
  68. - Internal Format ifDepth8 added
  69. - function GrabScreen now supports all uncompressed formats
  70. 31-01-2006
  71. - AddAlphaFromglBitmap implemented
  72. 29-12-2005
  73. - LoadFromResource and LoadFromResourceId now needs an Instance and an ResourceType (for ID)
  74. 28-12-2005
  75. - Width, Height and Depth internal changed to TglBitmapPixelPosition.
  76. property Width, Height, Depth are still existing and new property Dimension are avail
  77. 11-12-2005
  78. - Added native OpenGL Support. Breaking the dglOpenGL "barrier".
  79. 19-10-2005
  80. - Added function GrabScreen to class TglBitmap2D
  81. 18-10-2005
  82. - Added support to Save images
  83. - Added function Clone to Clone Instance
  84. 11-10-2005
  85. - Functions now works with Cardinals for each channel. Up to 32 Bits per channel.
  86. Usefull for Future
  87. - Several speed optimizations
  88. 09-10-2005
  89. - Internal structure change. Loading of TGA, PNG and DDS improved.
  90. Data, format and size will now set directly with SetDataPtr.
  91. - AddFunc now works with all Types of Images and Formats
  92. - Some Funtions moved to Baseclass TglBitmap
  93. 06-10-2005
  94. - Added Support to decompress DXT3 and DXT5 compressed Images.
  95. - Added Mapping to convert data from one format into an other.
  96. 05-10-2005
  97. - Added method ConvertTo in Class TglBitmap2D. Method allows to convert every
  98. supported Input format (supported by GetPixel) into any uncompresed Format
  99. - Added Support to decompress DXT1 compressed Images.
  100. - SwapColors replaced by ConvertTo
  101. 04-10-2005
  102. - Added Support for compressed DDSs
  103. - Added new internal formats (DXT1, DXT3, DXT5)
  104. 29-09-2005
  105. - Parameter Components renamed to InternalFormat
  106. 23-09-2005
  107. - Some AllocMem replaced with GetMem (little speed change)
  108. - better exception handling. Better protection from memory leaks.
  109. 22-09-2005
  110. - Added support for Direct Draw Surfaces (.DDS) (uncompressed images only)
  111. - Added new internal formats (RGB8, RGBA8, RGBA4, RGB5A1, RGB10A2, R5G6B5)
  112. 07-09-2005
  113. - Added support for Grayscale textures
  114. - Added internal formats (Alpha, Luminance, LuminanceAlpha, BGR8, BGRA8)
  115. 10-07-2005
  116. - Added support for GL_VERSION_2_0
  117. - Added support for GL_EXT_texture_filter_anisotropic
  118. 04-07-2005
  119. - Function FillWithColor fills the Image with one Color
  120. - Function LoadNormalMap added
  121. 30-06-2005
  122. - ToNormalMap allows to Create an NormalMap from the Alphachannel
  123. - ToNormalMap now supports Sobel (nmSobel) function.
  124. 29-06-2005
  125. - support for RLE Compressed RGB TGAs added
  126. 28-06-2005
  127. - Class TglBitmapNormalMap added to support Normalmap generation
  128. - Added function ToNormalMap in class TglBitmap2D to genereate normal maps from textures.
  129. 3 Filters are supported. (4 Samples, 3x3 and 5x5)
  130. 16-06-2005
  131. - Method LoadCubeMapClass removed
  132. - LoadCubeMap returnvalue is now the Texture paramter. Such as LoadTextures
  133. - virtual abstract method GenTexture in class TglBitmap now is protected
  134. 12-06-2005
  135. - now support DescriptionFlag in LoadTga. Allows vertical flipped images to be loaded as normal
  136. 10-06-2005
  137. - little enhancement for IsPowerOfTwo
  138. - TglBitmap1D.GenTexture now tests NPOT Textures
  139. 06-06-2005
  140. - some little name changes. All properties or function with Texture in name are
  141. now without texture in name. We have allways texture so we dosn't name it.
  142. 03-06-2005
  143. - GenTexture now tests if texture is NPOT and NPOT-Texture are supported or
  144. TextureTarget is GL_TEXTURE_RECTANGLE. Else it raised an exception.
  145. 02-06-2005
  146. - added support for GL_ARB_texture_rectangle, GL_EXT_texture_rectangle and GL_NV_texture_rectangle
  147. 25-04-2005
  148. - Function Unbind added
  149. - call of SetFilter or SetTextureWrap if TextureID exists results in setting properties to opengl texture.
  150. 21-04-2005
  151. - class TglBitmapCubeMap added (allows to Create Cubemaps)
  152. 29-03-2005
  153. - Added Support for PNG Images. (http://pngdelphi.sourceforge.net/)
  154. To Enable png's use the define pngimage
  155. 22-03-2005
  156. - New Functioninterface added
  157. - Function GetPixel added
  158. 27-11-2004
  159. - Property BuildMipMaps renamed to MipMap
  160. 21-11-2004
  161. - property Name removed.
  162. - BuildMipMaps is now a set of 3 values. None, GluBuildMipmaps and SGIS_generate_mipmap
  163. 22-05-2004
  164. - property name added. Only used in glForms!
  165. 26-11-2003
  166. - property FreeDataAfterGenTexture is now available as default (default = true)
  167. - BuildMipmaps now implemented in TglBitmap1D (i've forgotten it)
  168. - function MoveMemory replaced with function Move (little speed change)
  169. - several calculations stored in variables (little speed change)
  170. 29-09-2003
  171. - property BuildMipsMaps added (default = true)
  172. if BuildMipMaps isn't set GenTextures uses glTexImage[12]D else it use gluBuild[12]dMipmaps
  173. - property FreeDataAfterGenTexture added (default = true)
  174. if FreeDataAfterGenTexture is set the texturedata were deleted after the texture was generated.
  175. - parameter DisableOtherTextureUnits of Bind removed
  176. - parameter FreeDataAfterGeneration of GenTextures removed
  177. 12-09-2003
  178. - TglBitmap dosn't delete data if class was destroyed (fixed)
  179. 09-09-2003
  180. - Bind now enables TextureUnits (by params)
  181. - GenTextures can leave data (by param)
  182. - LoadTextures now optimal
  183. 03-09-2003
  184. - Performance optimization in AddFunc
  185. - procedure Bind moved to subclasses
  186. - Added new Class TglBitmap1D to support real OpenGL 1D Textures
  187. 19-08-2003
  188. - Texturefilter and texturewrap now also as defaults
  189. Minfilter = GL_LINEAR_MIPMAP_LINEAR
  190. Magfilter = GL_LINEAR
  191. Wrap(str) = GL_CLAMP_TO_EDGE
  192. - Added new format tfCompressed to create a compressed texture.
  193. - propertys IsCompressed, TextureSize and IsResident added
  194. IsCompressed and TextureSize only contains data from level 0
  195. 18-08-2003
  196. - Added function AddFunc to add PerPixelEffects to Image
  197. - LoadFromFunc now based on AddFunc
  198. - Invert now based on AddFunc
  199. - SwapColors now based on AddFunc
  200. 16-08-2003
  201. - Added function FlipHorz
  202. 15-08-2003
  203. - Added function LaodFromFunc to create images with function
  204. - Added function FlipVert
  205. - Added internal format RGB(A) if GL_EXT_bgra or OpenGL 1.2 isn't supported
  206. 29-07-2003
  207. - Added Alphafunctions to calculate alpha per function
  208. - Added Alpha from ColorKey using alphafunctions
  209. 28-07-2003
  210. - First full functionally Version of glBitmap
  211. - Support for 24Bit and 32Bit TGA Pictures added
  212. 25-07-2003
  213. - begin of programming
  214. ***********************************************************}
  215. unit glBitmap;
  216. {.$MESSAGE warn 'Hey. I''m the glBitmap.pas and i need to be configured. My master tell me your preferences! ;)'}
  217. // Please uncomment the defines below to configure the glBitmap to your preferences.
  218. // If you have configured the unit you can uncomment the warning above.
  219. // ###### Start of preferences ################################################
  220. {$DEFINE GLB_NO_NATIVE_GL}
  221. // To enable the dglOpenGL.pas Header
  222. // With native GL then bindings are staticlly declared to support other headers
  223. // or use the glBitmap inside of DLLs (minimize codesize).
  224. {.$DEFINE GLB_SDL}
  225. // To enable the support for SDL_surfaces
  226. {.$DEFINE GLB_DELPHI}
  227. // To enable the support for TBitmap from Delphi (not lazarus)
  228. // *** image libs ***
  229. {.$DEFINE GLB_SDL_IMAGE}
  230. // To enable the support of SDL_image to load files. (READ ONLY)
  231. // If you enable SDL_image all other libraries will be ignored!
  232. {.$DEFINE GLB_PNGIMAGE}
  233. // to enable png support with the unit pngimage. You can download it from http://pngdelphi.sourceforge.net/
  234. // if you enable pngimage the libPNG will be ignored
  235. {.$DEFINE GLB_LIB_PNG}
  236. // to use the libPNG http://www.libpng.org/
  237. // You will need an aditional header.
  238. // http://www.opengl24.de/index.php?cat=header&file=libpng
  239. {.$DEFINE GLB_DELPHI_JPEG}
  240. // if you enable delphi jpegs the libJPEG will be ignored
  241. {.$DEFINE GLB_LIB_JPEG}
  242. // to use the libJPEG http://www.ijg.org/
  243. // You will need an aditional header.
  244. // http://www.opengl24.de/index.php?cat=header&file=libjpeg
  245. // ###### End of preferences ##################################################
  246. // ###### PRIVATE. Do not change anything. ####################################
  247. // *** old defines for compatibility ***
  248. {$IFDEF NO_NATIVE_GL}
  249. {$DEFINE GLB_NO_NATIVE_GL}
  250. {$ENDIF}
  251. {$IFDEF pngimage}
  252. {$definde GLB_PNGIMAGE}
  253. {$ENDIF}
  254. // *** Delphi Versions ***
  255. {$IFDEF fpc}
  256. {$MODE Delphi}
  257. {$IFDEF CPUI386}
  258. {$DEFINE CPU386}
  259. {$ASMMODE INTEL}
  260. {$ENDIF}
  261. {$IFNDEF WINDOWS}
  262. {$linklib c}
  263. {$ENDIF}
  264. {$ENDIF}
  265. // *** checking define combinations ***
  266. {$IFDEF GLB_SDL_IMAGE}
  267. {$IFNDEF GLB_SDL}
  268. {$MESSAGE warn 'SDL_image won''t work without SDL. SDL will be activated.'}
  269. {$DEFINE GLB_SDL}
  270. {$ENDIF}
  271. {$IFDEF GLB_PNGIMAGE}
  272. {$MESSAGE warn 'The unit pngimage will be ignored because you are using SDL_image.'}
  273. {$undef GLB_PNGIMAGE}
  274. {$ENDIF}
  275. {$IFDEF GLB_DELPHI_JPEG}
  276. {$MESSAGE warn 'The unit JPEG will be ignored because you are using SDL_image.'}
  277. {$undef GLB_DELPHI_JPEG}
  278. {$ENDIF}
  279. {$IFDEF GLB_LIB_PNG}
  280. {$MESSAGE warn 'The library libPNG will be ignored because you are using SDL_image.'}
  281. {$undef GLB_LIB_PNG}
  282. {$ENDIF}
  283. {$IFDEF GLB_LIB_JPEG}
  284. {$MESSAGE warn 'The library libJPEG will be ignored because you are using SDL_image.'}
  285. {$undef GLB_LIB_JPEG}
  286. {$ENDIF}
  287. {$DEFINE GLB_SUPPORT_PNG_READ}
  288. {$DEFINE GLB_SUPPORT_JPEG_READ}
  289. {$ENDIF}
  290. {$IFDEF GLB_PNGIMAGE}
  291. {$IFDEF GLB_LIB_PNG}
  292. {$MESSAGE warn 'The library libPNG will be ignored if you are using pngimage.'}
  293. {$undef GLB_LIB_PNG}
  294. {$ENDIF}
  295. {$DEFINE GLB_SUPPORT_PNG_READ}
  296. {$DEFINE GLB_SUPPORT_PNG_WRITE}
  297. {$ENDIF}
  298. {$IFDEF GLB_LIB_PNG}
  299. {$DEFINE GLB_SUPPORT_PNG_READ}
  300. {$DEFINE GLB_SUPPORT_PNG_WRITE}
  301. {$ENDIF}
  302. {$IFDEF GLB_DELPHI_JPEG}
  303. {$IFDEF GLB_LIB_JPEG}
  304. {$MESSAGE warn 'The library libJPEG will be ignored if you are using the unit JPEG.'}
  305. {$undef GLB_LIB_JPEG}
  306. {$ENDIF}
  307. {$DEFINE GLB_SUPPORT_JPEG_READ}
  308. {$DEFINE GLB_SUPPORT_JPEG_WRITE}
  309. {$ENDIF}
  310. {$IFDEF GLB_LIB_JPEG}
  311. {$DEFINE GLB_SUPPORT_JPEG_READ}
  312. {$DEFINE GLB_SUPPORT_JPEG_WRITE}
  313. {$ENDIF}
  314. // *** general options ***
  315. {$EXTENDEDSYNTAX ON}
  316. {$LONGSTRINGS ON}
  317. {$ALIGN ON}
  318. {$IFNDEF FPC}
  319. {$OPTIMIZATION ON}
  320. {$ENDIF}
  321. interface
  322. uses
  323. {$IFDEF GLB_NO_NATIVE_GL} dglOpenGL, {$ENDIF}
  324. {$IFDEF GLB_SDL} SDL, {$ENDIF}
  325. {$IFDEF GLB_DELPHI} Dialogs, Windows, Graphics, {$ENDIF}
  326. {$IFDEF GLB_SDL_IMAGE} SDL_image, {$ENDIF}
  327. {$IFDEF GLB_PNGIMAGE} pngimage, {$ENDIF}
  328. {$IFDEF GLB_LIB_PNG} libPNG, {$ENDIF}
  329. {$IFDEF GLB_DELPHI_JPEG} JPEG, {$ENDIF}
  330. {$IFDEF GLB_LIB_JPEG} libJPEG, {$ENDIF}
  331. Classes, SysUtils;
  332. {$IFNDEF GLB_DELPHI}
  333. type
  334. HGLRC = Cardinal;
  335. DWORD = Cardinal;
  336. PDWORD = ^DWORD;
  337. TRGBQuad = packed record
  338. rgbBlue: Byte;
  339. rgbGreen: Byte;
  340. rgbRed: Byte;
  341. rgbReserved: Byte;
  342. end;
  343. {$ENDIF}
  344. (* TODO dglOpenGL
  345. {$IFNDEF GLB_NO_NATIVE_GL}
  346. // Native OpenGL Implementation
  347. type
  348. PByteBool = ^ByteBool;
  349. {$IFDEF GLB_DELPHI}
  350. var
  351. gLastContext: HGLRC;
  352. {$ENDIF}
  353. const
  354. // Generell
  355. GL_VERSION = $1F02;
  356. GL_EXTENSIONS = $1F03;
  357. GL_TRUE = 1;
  358. GL_FALSE = 0;
  359. GL_TEXTURE_1D = $0DE0;
  360. GL_TEXTURE_2D = $0DE1;
  361. GL_MAX_TEXTURE_SIZE = $0D33;
  362. GL_PACK_ALIGNMENT = $0D05;
  363. GL_UNPACK_ALIGNMENT = $0CF5;
  364. // Textureformats
  365. GL_RGB = $1907;
  366. GL_RGB4 = $804F;
  367. GL_RGB8 = $8051;
  368. GL_RGBA = $1908;
  369. GL_RGBA4 = $8056;
  370. GL_RGBA8 = $8058;
  371. GL_BGR = $80E0;
  372. GL_BGRA = $80E1;
  373. GL_ALPHA4 = $803B;
  374. GL_ALPHA8 = $803C;
  375. GL_LUMINANCE4 = $803F;
  376. GL_LUMINANCE8 = $8040;
  377. GL_LUMINANCE4_ALPHA4 = $8043;
  378. GL_LUMINANCE8_ALPHA8 = $8045;
  379. GL_DEPTH_COMPONENT = $1902;
  380. GL_UNSIGNED_BYTE = $1401;
  381. GL_ALPHA = $1906;
  382. GL_LUMINANCE = $1909;
  383. GL_LUMINANCE_ALPHA = $190A;
  384. GL_TEXTURE_WIDTH = $1000;
  385. GL_TEXTURE_HEIGHT = $1001;
  386. GL_TEXTURE_INTERNAL_FORMAT = $1003;
  387. GL_TEXTURE_RED_SIZE = $805C;
  388. GL_TEXTURE_GREEN_SIZE = $805D;
  389. GL_TEXTURE_BLUE_SIZE = $805E;
  390. GL_TEXTURE_ALPHA_SIZE = $805F;
  391. GL_TEXTURE_LUMINANCE_SIZE = $8060;
  392. // Dataformats
  393. GL_UNSIGNED_SHORT_5_6_5 = $8363;
  394. GL_UNSIGNED_SHORT_5_6_5_REV = $8364;
  395. GL_UNSIGNED_SHORT_4_4_4_4_REV = $8365;
  396. GL_UNSIGNED_SHORT_1_5_5_5_REV = $8366;
  397. GL_UNSIGNED_INT_2_10_10_10_REV = $8368;
  398. // Filter
  399. GL_NEAREST = $2600;
  400. GL_LINEAR = $2601;
  401. GL_NEAREST_MIPMAP_NEAREST = $2700;
  402. GL_LINEAR_MIPMAP_NEAREST = $2701;
  403. GL_NEAREST_MIPMAP_LINEAR = $2702;
  404. GL_LINEAR_MIPMAP_LINEAR = $2703;
  405. GL_TEXTURE_MAG_FILTER = $2800;
  406. GL_TEXTURE_MIN_FILTER = $2801;
  407. // Wrapmodes
  408. GL_TEXTURE_WRAP_S = $2802;
  409. GL_TEXTURE_WRAP_T = $2803;
  410. GL_CLAMP = $2900;
  411. GL_REPEAT = $2901;
  412. GL_CLAMP_TO_EDGE = $812F;
  413. GL_CLAMP_TO_BORDER = $812D;
  414. GL_TEXTURE_WRAP_R = $8072;
  415. GL_MIRRORED_REPEAT = $8370;
  416. // Border Color
  417. GL_TEXTURE_BORDER_COLOR = $1004;
  418. // Texgen
  419. GL_NORMAL_MAP = $8511;
  420. GL_REFLECTION_MAP = $8512;
  421. GL_S = $2000;
  422. GL_T = $2001;
  423. GL_R = $2002;
  424. GL_TEXTURE_GEN_MODE = $2500;
  425. GL_TEXTURE_GEN_S = $0C60;
  426. GL_TEXTURE_GEN_T = $0C61;
  427. GL_TEXTURE_GEN_R = $0C62;
  428. // Cubemaps
  429. GL_MAX_CUBE_MAP_TEXTURE_SIZE = $851C;
  430. GL_TEXTURE_CUBE_MAP = $8513;
  431. GL_TEXTURE_BINDING_CUBE_MAP = $8514;
  432. GL_TEXTURE_CUBE_MAP_POSITIVE_X = $8515;
  433. GL_TEXTURE_CUBE_MAP_NEGATIVE_X = $8516;
  434. GL_TEXTURE_CUBE_MAP_POSITIVE_Y = $8517;
  435. GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = $8518;
  436. GL_TEXTURE_CUBE_MAP_POSITIVE_Z = $8519;
  437. GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = $851A;
  438. GL_TEXTURE_RECTANGLE_ARB = $84F5;
  439. // GL_SGIS_generate_mipmap
  440. GL_GENERATE_MIPMAP = $8191;
  441. // GL_EXT_texture_compression_s3tc
  442. GL_COMPRESSED_RGB_S3TC_DXT1_EXT = $83F0;
  443. GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = $83F1;
  444. GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = $83F2;
  445. GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = $83F3;
  446. // GL_EXT_texture_filter_anisotropic
  447. GL_TEXTURE_MAX_ANISOTROPY_EXT = $84FE;
  448. GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = $84FF;
  449. // GL_ARB_texture_compression
  450. GL_COMPRESSED_RGB = $84ED;
  451. GL_COMPRESSED_RGBA = $84EE;
  452. GL_COMPRESSED_ALPHA = $84E9;
  453. GL_COMPRESSED_LUMINANCE = $84EA;
  454. GL_COMPRESSED_LUMINANCE_ALPHA = $84EB;
  455. // Extensions
  456. var
  457. GL_VERSION_1_2,
  458. GL_VERSION_1_3,
  459. GL_VERSION_1_4,
  460. GL_VERSION_2_0,
  461. GL_ARB_texture_border_clamp,
  462. GL_ARB_texture_cube_map,
  463. GL_ARB_texture_compression,
  464. GL_ARB_texture_non_power_of_two,
  465. GL_ARB_texture_rectangle,
  466. GL_ARB_texture_mirrored_repeat,
  467. GL_EXT_bgra,
  468. GL_EXT_texture_edge_clamp,
  469. GL_EXT_texture_cube_map,
  470. GL_EXT_texture_compression_s3tc,
  471. GL_EXT_texture_filter_anisotropic,
  472. GL_EXT_texture_rectangle,
  473. GL_NV_texture_rectangle,
  474. GL_IBM_texture_mirrored_repeat,
  475. GL_SGIS_generate_mipmap: Boolean;
  476. const
  477. {$IFDEF LINUX}
  478. libglu = 'libGLU.so.1';
  479. libopengl = 'libGL.so.1';
  480. {$else}
  481. libglu = 'glu32.dll';
  482. libopengl = 'opengl32.dll';
  483. {$ENDIF}
  484. {$IFDEF LINUX}
  485. function glXGetProcAddress(ProcName: PAnsiChar): Pointer; cdecl; external libopengl;
  486. {$else}
  487. function wglGetProcAddress(ProcName: PAnsiChar): Pointer; stdcall; external libopengl;
  488. {$ENDIF}
  489. function glGetString(name: Cardinal): PAnsiChar; {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
  490. procedure glEnable(cap: Cardinal); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
  491. procedure glDisable(cap: Cardinal); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
  492. procedure glGetIntegerv(pname: Cardinal; params: PInteger); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
  493. procedure glTexImage1D(target: Cardinal; level, internalformat, width, border: Integer; format, atype: Cardinal; const pixels: Pointer); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
  494. procedure glTexImage2D(target: Cardinal; level, internalformat, width, height, border: Integer; format, atype: Cardinal; const pixels: Pointer); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
  495. procedure glGenTextures(n: Integer; Textures: PCardinal); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
  496. procedure glBindTexture(target: Cardinal; Texture: Cardinal); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
  497. procedure glDeleteTextures(n: Integer; const textures: PCardinal); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
  498. procedure glReadPixels(x, y: Integer; width, height: Integer; format, atype: Cardinal; pixels: Pointer); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
  499. procedure glPixelStorei(pname: Cardinal; param: Integer); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
  500. procedure glGetTexImage(target: Cardinal; level: Integer; format: Cardinal; _type: Cardinal; pixels: Pointer); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
  501. function glAreTexturesResident(n: Integer; const Textures: PCardinal; residences: PByteBool): ByteBool; {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
  502. procedure glTexParameteri(target: Cardinal; pname: Cardinal; param: Integer); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
  503. procedure glTexParameterfv(target: Cardinal; pname: Cardinal; const params: PSingle); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
  504. procedure glGetTexLevelParameteriv(target: Cardinal; level: Integer; pname: Cardinal; params: PInteger); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
  505. procedure glTexGeni(coord, pname: Cardinal; param: Integer); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
  506. function gluBuild1DMipmaps(Target: Cardinal; Components, Width: Integer; Format, atype: Cardinal; Data: Pointer): Integer; {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libglu;
  507. function gluBuild2DMipmaps(Target: Cardinal; Components, Width, Height: Integer; Format, aType: Cardinal; Data: Pointer): Integer; {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libglu;
  508. var
  509. glCompressedTexImage2D : procedure(target: Cardinal; level: Integer; internalformat: Cardinal; width, height: Integer; border: Integer; imageSize: Integer; const data: Pointer); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF}
  510. glCompressedTexImage1D : procedure(target: Cardinal; level: Integer; internalformat: Cardinal; width: Integer; border: Integer; imageSize: Integer; const data: Pointer); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF}
  511. glGetCompressedTexImage : procedure(target: Cardinal; level: Integer; img: Pointer); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF}
  512. {$ENDIF}
  513. *)
  514. type
  515. ////////////////////////////////////////////////////////////////////////////////////////////////////
  516. EglBitmapException = class(Exception);
  517. EglBitmapSizeToLargeException = class(EglBitmapException);
  518. EglBitmapNonPowerOfTwoException = class(EglBitmapException);
  519. EglBitmapUnsupportedFormatFormat = class(EglBitmapException);
  520. ////////////////////////////////////////////////////////////////////////////////////////////////////
  521. TglBitmapFormat = (
  522. tfEmpty = 0,
  523. tfAlpha4,
  524. tfAlpha8,
  525. tfAlpha12,
  526. tfAlpha16,
  527. tfLuminance4,
  528. tfLuminance8,
  529. tfLuminance12,
  530. tfLuminance16,
  531. tfLuminance4Alpha4,
  532. tfLuminance6Alpha2,
  533. tfLuminance8Alpha8,
  534. tfLuminance12Alpha4,
  535. tfLuminance12Alpha12,
  536. tfLuminance16Alpha16,
  537. tfR3G3B2,
  538. tfRGB4,
  539. tfR5G6B5,
  540. tfRGB5,
  541. tfRGB8,
  542. tfRGB10,
  543. tfRGB12,
  544. tfRGB16,
  545. tfRGBA2,
  546. tfRGBA4,
  547. tfRGB5A1,
  548. tfRGBA8,
  549. tfRGB10A2,
  550. tfRGBA12,
  551. tfRGBA16,
  552. tfBGR4,
  553. tfB5G6R5,
  554. tfBGR5,
  555. tfBGR8,
  556. tfBGR10,
  557. tfBGR12,
  558. tfBGR16,
  559. tfBGRA2,
  560. tfBGRA4,
  561. tfBGR5A1,
  562. tfBGRA8,
  563. tfBGR10A2,
  564. tfBGRA12,
  565. tfBGRA16,
  566. tfDepth16,
  567. tfDepth24,
  568. tfDepth32
  569. );
  570. TglBitmapFileType = (
  571. {$IFDEF GLB_SUPPORT_PNG_WRITE} ftPNG, {$ENDIF}
  572. {$IFDEF GLB_SUPPORT_JPEG_WRITE}ftJPEG, {$ENDIF}
  573. ftDDS,
  574. ftTGA,
  575. ftBMP);
  576. TglBitmapFileTypes = set of TglBitmapFileType;
  577. TglBitmapMipMap = (
  578. mmNone,
  579. mmMipmap,
  580. mmMipmapGlu);
  581. TglBitmapNormalMapFunc = (
  582. nm4Samples,
  583. nmSobel,
  584. nm3x3,
  585. nm5x5);
  586. ////////////////////////////////////////////////////////////////////////////////////////////////////
  587. TglBitmapColorRec = packed record
  588. case Integer of
  589. 0: (r, g, b, a: Cardinal);
  590. 1: (arr: array[0..3] of Cardinal);
  591. end;
  592. TglBitmapPixelData = packed record
  593. Data, Range: TglBitmapColorRec;
  594. Format: TglBitmapFormat;
  595. end;
  596. PglBitmapPixelData = ^TglBitmapPixelData;
  597. ////////////////////////////////////////////////////////////////////////////////////////////////////
  598. TglBitmapPixelPositionFields = set of (ffX, ffY);
  599. TglBitmapPixelPosition = record
  600. Fields : TglBitmapPixelPositionFields;
  601. X : Word;
  602. Y : Word;
  603. end;
  604. ////////////////////////////////////////////////////////////////////////////////////////////////////
  605. TglBitmap = class;
  606. TglBitmapFunctionRec = record
  607. Sender: TglBitmap;
  608. Size: TglBitmapPixelPosition;
  609. Position: TglBitmapPixelPosition;
  610. Source: TglBitmapPixelData;
  611. Dest: TglBitmapPixelData;
  612. Args: PtrInt;
  613. end;
  614. TglBitmapFunction = procedure(var FuncRec: TglBitmapFunctionRec);
  615. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  616. TglBitmap = class
  617. protected
  618. fID: GLuint;
  619. fTarget: GLuint;
  620. fAnisotropic: Integer;
  621. fDeleteTextureOnFree: Boolean;
  622. fFreeDataAfterGenTexture: Boolean;
  623. fData: PByte;
  624. fIsResident: Boolean;
  625. fBorderColor: array[0..3] of Single;
  626. fDimension: TglBitmapPixelPosition;
  627. fMipMap: TglBitmapMipMap;
  628. fFormat: TglBitmapFormat;
  629. // Mapping
  630. fPixelSize: Integer;
  631. fRowSize: Integer;
  632. // Filtering
  633. fFilterMin: Cardinal;
  634. fFilterMag: Cardinal;
  635. // TexturWarp
  636. fWrapS: Cardinal;
  637. fWrapT: Cardinal;
  638. fWrapR: Cardinal;
  639. // CustomData
  640. fFilename: String;
  641. fCustomName: String;
  642. fCustomNameW: WideString;
  643. fCustomData: Pointer;
  644. //Getter
  645. function GetWidth: Integer; virtual;
  646. function GetHeight: Integer; virtual;
  647. function GetFileWidth: Integer; virtual;
  648. function GetFileHeight: Integer; virtual;
  649. //Setter
  650. procedure SetCustomData(const aValue: Pointer);
  651. procedure SetCustomName(const aValue: String);
  652. procedure SetCustomNameW(const aValue: WideString);
  653. procedure SetDeleteTextureOnFree(const aValue: Boolean);
  654. procedure SetFormat(const aValue: TglBitmapFormat);
  655. procedure SetFreeDataAfterGenTexture(const aValue: Boolean);
  656. procedure SetID(const aValue: Cardinal);
  657. procedure SetMipMap(const aValue: TglBitmapMipMap);
  658. procedure SetTarget(const aValue: Cardinal);
  659. procedure SetAnisotropic(const aValue: Integer);
  660. procedure CreateID;
  661. procedure SetupParameters(var aBuildWithGlu: Boolean);
  662. procedure SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
  663. const aWidth: Integer = -1; const aHeight: Integer = -1); virtual;
  664. procedure GenTexture(const aTestTextureSize: Boolean = true); virtual; abstract;
  665. function FlipHorz: Boolean; virtual;
  666. function FlipVert: Boolean; virtual;
  667. property Width: Integer read GetWidth;
  668. property Height: Integer read GetHeight;
  669. property FileWidth: Integer read GetFileWidth;
  670. property FileHeight: Integer read GetFileHeight;
  671. public
  672. //Properties
  673. property ID: Cardinal read fID write SetID;
  674. property Target: Cardinal read fTarget write SetTarget;
  675. property Format: TglBitmapFormat read fFormat write SetFormat;
  676. property MipMap: TglBitmapMipMap read fMipMap write SetMipMap;
  677. property Anisotropic: Integer read fAnisotropic write SetAnisotropic;
  678. property Filename: String read fFilename;
  679. property CustomName: String read fCustomName write SetCustomName;
  680. property CustomNameW: WideString read fCustomNameW write SetCustomNameW;
  681. property CustomData: Pointer read fCustomData write SetCustomData;
  682. property DeleteTextureOnFree: Boolean read fDeleteTextureOnFree write SetDeleteTextureOnFree;
  683. property FreeDataAfterGenTexture: Boolean read fFreeDataAfterGenTexture write SetFreeDataAfterGenTexture;
  684. property Dimension: TglBitmapPixelPosition read fDimension;
  685. property Data: PByte read fData;
  686. property IsResident: Boolean read fIsResident;
  687. procedure AfterConstruction; override;
  688. procedure BeforeDestruction; override;
  689. //Load
  690. procedure LoadFromFile(const aFilename: String);
  691. procedure LoadFromStream(const aStream: TStream); virtual;
  692. procedure LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
  693. const aFormat: TglBitmapFormat; const aArgs: PtrInt = 0);
  694. {$IFDEF GLB_DELPHI}
  695. procedure LoadFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil);
  696. procedure LoadFromResourceID(const sInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
  697. {$ENDIF}
  698. //Save
  699. procedure SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
  700. procedure SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType); virtual;
  701. //Convert
  702. function AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: PtrInt = 0): Boolean; overload;
  703. function AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
  704. const aFormat: TglBitmapFormat; const aArgs: PtrInt = 0): Boolean; overload;
  705. public
  706. //Alpha & Co
  707. {$IFDEF GLB_SDL}
  708. function AssignToSurface(out aSurface: PSDL_Surface): Boolean;
  709. function AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
  710. function AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
  711. function AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil;
  712. const aArgs: PtrInt = 0): Boolean;
  713. {$ENDIF}
  714. {$IFDEF GLB_DELPHI}
  715. function AssignToBitmap(const aBitmap: TBitmap): Boolean;
  716. function AssignFromBitmap(const aBitmap: TBitmap): Boolean;
  717. function AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
  718. function AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction = nil;
  719. const aArgs: PtrInt = 0): Boolean;
  720. function AddAlphaFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil;
  721. const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
  722. function AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
  723. const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
  724. {$ENDIF}
  725. function AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: PtrInt = 0): Boolean; virtual;
  726. function AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
  727. function AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
  728. function AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
  729. function AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte = 0): Boolean;
  730. function AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal = 0): Boolean;
  731. function AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single = 0): Boolean;
  732. function AddAlphaFromValue(const aAlpha: Byte): Boolean;
  733. function AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
  734. function AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
  735. function RemoveAlpha: Boolean; virtual;
  736. public
  737. //Common
  738. function Clone: TglBitmap;
  739. function ConvertTo(const aFormat: TglBitmapFormat): Boolean; virtual;
  740. procedure Invert(const aUseRGB: Boolean = true; const aUseAlpha: Boolean = false);
  741. procedure SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
  742. procedure FreeData;
  743. //ColorFill
  744. procedure FillWithColor(const aRed, aGreen, aBlue: Byte; const aAlpha: Byte = 255);
  745. procedure FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal = $FFFFFFFF);
  746. procedure FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha : Single = 1);
  747. //TexParameters
  748. procedure SetFilter(const aMin, aMag: Cardinal);
  749. procedure SetWrap(
  750. const S: Cardinal = GL_CLAMP_TO_EDGE;
  751. const T: Cardinal = GL_CLAMP_TO_EDGE;
  752. const R: Cardinal = GL_CLAMP_TO_EDGE);
  753. procedure GetPixel(const aPos: TglBitmapPixelPosition; var aPixel: TglBitmapPixelData); virtual;
  754. procedure SetPixel(const aPos: TglBitmapPixelPosition; const aPixel: TglBitmapPixelData); virtual;
  755. procedure Bind(const aEnableTextureUnit: Boolean = true); virtual;
  756. procedure Unbind(const aDisableTextureUnit: Boolean = true); virtual;
  757. //Constructors
  758. constructor Create; overload;
  759. constructor Create(const aFileName: String); overload;
  760. constructor Create(const aStream: TStream); overload;
  761. constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat); overload;
  762. constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: PtrInt = 0); overload;
  763. {$IFDEF GLB_DELPHI}
  764. constructor Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil); overload;
  765. constructor Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar); overload;
  766. {$ENDIF}
  767. private
  768. {$IFDEF GLB_SUPPORT_PNG_READ}
  769. function LoadPNG(const aStream: TStream): Boolean; virtual;
  770. procedure SavePNG(const aStream: TStream); virtual;
  771. {$ENDIF}
  772. {$IFDEF GLB_SUPPORT_JPEG_READ}
  773. function LoadJPEG(const aStream: TStream): Boolean; virtual;
  774. procedure SaveJPEG(const aStream: TStream); virtual;
  775. {$ENDIF}
  776. function LoadBMP(const aStream: TStream): Boolean; virtual;
  777. procedure SaveBMP(const aStream: TStream); virtual;
  778. function LoadTGA(const aStream: TStream): Boolean; virtual;
  779. procedure SaveTGA(const aStream: TStream); virtual;
  780. function LoadDDS(const aStream: TStream): Boolean; virtual;
  781. procedure SaveDDS(const aStream: TStream); virtual;
  782. end;
  783. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  784. TglBitmap2D = class(TglBitmap)
  785. protected
  786. // Bildeinstellungen
  787. fLines: array of PByte;
  788. (* TODO
  789. procedure GetDXTColorBlock(pData: pByte; relX, relY: Integer; var Pixel: TglBitmapPixelData);
  790. procedure GetPixel2DDXT1(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
  791. procedure GetPixel2DDXT3(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
  792. procedure GetPixel2DDXT5(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
  793. procedure GetPixel2DUnmap(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
  794. procedure SetPixel2DUnmap(const Pos: TglBitmapPixelPosition; const Pixel: TglBitmapPixelData);
  795. *)
  796. function GetScanline(const aIndex: Integer): Pointer;
  797. procedure SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
  798. const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
  799. procedure UploadData(const aTarget: Cardinal; const aBuildWithGlu: Boolean);
  800. public
  801. property Width;
  802. property Height;
  803. property Scanline[const aIndex: Integer]: Pointer read GetScanline;
  804. procedure AfterConstruction; override;
  805. procedure GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
  806. procedure GetDataFromTexture;
  807. procedure GenTexture(const aTestTextureSize: Boolean = true); override;
  808. function FlipHorz: Boolean; override;
  809. function FlipVert: Boolean; override;
  810. procedure ToNormalMap(const aFunc: TglBitmapNormalMapFunc = nm3x3;
  811. const aScale: Single = 2; const aUseAlpha: Boolean = false);
  812. end;
  813. (* TODO
  814. TglBitmapCubeMap = class(TglBitmap2D)
  815. protected
  816. fGenMode: Integer;
  817. // Hide GenTexture
  818. procedure GenTexture(TestTextureSize: Boolean = true); reintroduce;
  819. public
  820. procedure AfterConstruction; override;
  821. procedure GenerateCubeMap(CubeTarget: Cardinal; TestTextureSize: Boolean = true);
  822. procedure Unbind(DisableTexCoordsGen: Boolean = true; DisableTextureUnit: Boolean = true); reintroduce; virtual;
  823. procedure Bind(EnableTexCoordsGen: Boolean = true; EnableTextureUnit: Boolean = true); reintroduce; virtual;
  824. end;
  825. TglBitmapNormalMap = class(TglBitmapCubeMap)
  826. public
  827. procedure AfterConstruction; override;
  828. procedure GenerateNormalMap(Size: Integer = 32; TestTextureSize: Boolean = true);
  829. end;
  830. TglBitmap1D = class(TglBitmap)
  831. protected
  832. procedure GetPixel1DUnmap(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
  833. procedure SetDataPointer(Data: pByte; Format: TglBitmapInternalFormat; Width: Integer = -1; Height: Integer = -1); override;
  834. procedure UploadData (Target, Format, InternalFormat, Typ: Cardinal; BuildWithGlu: Boolean);
  835. public
  836. // propertys
  837. property Width;
  838. procedure AfterConstruction; override;
  839. // Other
  840. function FlipHorz: Boolean; override;
  841. // Generation
  842. procedure GenTexture(TestTextureSize: Boolean = true); override;
  843. end;
  844. *)
  845. const
  846. NULL_SIZE: TglBitmapPixelPosition = (Fields: []; X: 0; Y: 0);
  847. procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
  848. procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
  849. procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
  850. procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
  851. procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
  852. procedure glBitmapSetDefaultWrap(
  853. const S: Cardinal = GL_CLAMP_TO_EDGE;
  854. const T: Cardinal = GL_CLAMP_TO_EDGE;
  855. const R: Cardinal = GL_CLAMP_TO_EDGE);
  856. function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
  857. function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
  858. function glBitmapGetDefaultMipmap: TglBitmapMipMap;
  859. function glBitmapGetDefaultFormat: TglBitmapFormat;
  860. procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
  861. procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
  862. function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
  863. function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
  864. var
  865. glBitmapDefaultDeleteTextureOnFree: Boolean;
  866. glBitmapDefaultFreeDataAfterGenTextures: Boolean;
  867. glBitmapDefaultFormat: TglBitmapFormat;
  868. glBitmapDefaultMipmap: TglBitmapMipMap;
  869. glBitmapDefaultFilterMin: Cardinal;
  870. glBitmapDefaultFilterMag: Cardinal;
  871. glBitmapDefaultWrapS: Cardinal;
  872. glBitmapDefaultWrapT: Cardinal;
  873. glBitmapDefaultWrapR: Cardinal;
  874. {$IFDEF GLB_DELPHI}
  875. function CreateGrayPalette: HPALETTE;
  876. {$ENDIF}
  877. implementation
  878. (* TODO
  879. function FormatIsCompressed(Format: TglBitmapInternalFormat): boolean;
  880. function FormatIsUncompressed(Format: TglBitmapInternalFormat): boolean;
  881. function LoadTexture(Filename: String; var Texture: Cardinal{$IFDEF GLB_DELPHI}; LoadFromRes : Boolean; Instance: Cardinal = 0{$ENDIF}): Boolean;
  882. function LoadCubeMap(PositiveX, NegativeX, PositiveY, NegativeY, PositiveZ, NegativeZ: String; var Texture: Cardinal{$IFDEF GLB_DELPHI}; LoadFromRes : Boolean; Instance: Cardinal = 0{$ENDIF}): Boolean;
  883. function LoadNormalMap(Size: Integer; var Texture: Cardinal): Boolean;
  884. *)
  885. uses
  886. Math, syncobjs;
  887. type
  888. ////////////////////////////////////////////////////////////////////////////////////////////////////
  889. TShiftRec = packed record
  890. case Integer of
  891. 0: (r, g, b, a: Byte);
  892. 1: (arr: array[0..3] of Byte);
  893. end;
  894. TFormatDescriptor = class(TObject)
  895. private
  896. function GetRedMask: UInt64;
  897. function GetGreenMask: UInt64;
  898. function GetBlueMask: UInt64;
  899. function GetAlphaMask: UInt64;
  900. protected
  901. fFormat: TglBitmapFormat;
  902. fWithAlpha: TglBitmapFormat;
  903. fWithoutAlpha: TglBitmapFormat;
  904. fPixelSize: Single;
  905. fRange: TglBitmapColorRec;
  906. fShift: TShiftRec;
  907. fglFormat: Cardinal;
  908. fglInternalFormat: Cardinal;
  909. fglDataFormat: Cardinal;
  910. function GetComponents: Integer; virtual;
  911. public
  912. property Format: TglBitmapFormat read fFormat;
  913. property WithAlpha: TglBitmapFormat read fWithAlpha;
  914. property WithoutAlpha: TglBitmapFormat read fWithoutAlpha;
  915. property Components: Integer read GetComponents;
  916. property PixelSize: Single read fPixelSize;
  917. property glFormat: Cardinal read fglFormat;
  918. property glInternalFormat: Cardinal read fglInternalFormat;
  919. property glDataFormat: Cardinal read fglDataFormat;
  920. property Range: TglBitmapColorRec read fRange;
  921. property Shift: TShiftRec read fShift;
  922. property RedMask: UInt64 read GetRedMask;
  923. property GreenMask: UInt64 read GetGreenMask;
  924. property BlueMask: UInt64 read GetBlueMask;
  925. property AlphaMask: UInt64 read GetAlphaMask;
  926. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); virtual; abstract;
  927. procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract;
  928. function GetSize(const aSize: TglBitmapPixelPosition): Integer; virtual; overload;
  929. function GetSize(const aWidth, aHeight: Integer): Integer; virtual; overload;
  930. function CreateMappingData: Pointer; virtual;
  931. procedure FreeMappingData(var aMappingData: Pointer); virtual;
  932. function IsEmpty: Boolean; virtual;
  933. function HasAlpha: Boolean; virtual;
  934. function MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: UInt64): Boolean; virtual;
  935. procedure PreparePixel(var aPixel: TglBitmapPixelData); virtual;
  936. constructor Create; virtual;
  937. public
  938. class procedure Init;
  939. class function Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
  940. class function GetWithAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
  941. class procedure Clear;
  942. class procedure Finalize;
  943. end;
  944. TFormatDescriptorClass = class of TFormatDescriptor;
  945. TfdEmpty = class(TFormatDescriptor);
  946. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  947. TfdAlpha_UB1 = class(TFormatDescriptor) //1* unsigned byte
  948. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  949. procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  950. constructor Create; override;
  951. end;
  952. TfdLuminance_UB1 = class(TFormatDescriptor) //1* unsigned byte
  953. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  954. procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  955. constructor Create; override;
  956. end;
  957. TfdUniversal_UB1 = class(TFormatDescriptor) //1* unsigned byte
  958. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  959. procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  960. constructor Create; override;
  961. end;
  962. TfdLuminanceAlpha_UB2 = class(TfdLuminance_UB1) //2* unsigned byte
  963. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  964. procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  965. constructor Create; override;
  966. end;
  967. TfdRGB_UB3 = class(TFormatDescriptor) //3* unsigned byte
  968. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  969. procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  970. constructor Create; override;
  971. end;
  972. TfdBGR_UB3 = class(TFormatDescriptor) //3* unsigned byte (inverse)
  973. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  974. procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  975. constructor Create; override;
  976. end;
  977. TfdRGBA_UB4 = class(TfdRGB_UB3) //4* unsigned byte
  978. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  979. procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  980. constructor Create; override;
  981. end;
  982. TfdBGRA_UB4 = class(TfdBGR_UB3) //4* unsigned byte (inverse)
  983. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  984. procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  985. constructor Create; override;
  986. end;
  987. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  988. TfdAlpha_US1 = class(TFormatDescriptor) //1* unsigned short
  989. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  990. procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  991. constructor Create; override;
  992. end;
  993. TfdLuminance_US1 = class(TFormatDescriptor) //1* unsigned short
  994. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  995. procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  996. constructor Create; override;
  997. end;
  998. TfdUniversal_US1 = class(TFormatDescriptor) //1* unsigned short
  999. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1000. procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1001. constructor Create; override;
  1002. end;
  1003. TfdDepth_US1 = class(TFormatDescriptor) //1* unsigned short
  1004. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1005. procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1006. constructor Create; override;
  1007. end;
  1008. TfdLuminanceAlpha_US2 = class(TfdLuminance_US1) //2* unsigned short
  1009. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1010. procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1011. constructor Create; override;
  1012. end;
  1013. TfdRGB_US3 = class(TFormatDescriptor) //3* unsigned short
  1014. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1015. procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1016. constructor Create; override;
  1017. end;
  1018. TfdBGR_US3 = class(TFormatDescriptor) //3* unsigned short (inverse)
  1019. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1020. procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1021. constructor Create; override;
  1022. end;
  1023. TfdRGBA_US4 = class(TfdRGB_US3) //4* unsigned short
  1024. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1025. procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1026. constructor Create; override;
  1027. end;
  1028. TfdBGRA_US4 = class(TfdBGR_US3) //4* unsigned short (inverse)
  1029. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1030. procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1031. constructor Create; override;
  1032. end;
  1033. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1034. TfdUniversal_UI1 = class(TFormatDescriptor) //1* unsigned int
  1035. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1036. procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1037. constructor Create; override;
  1038. end;
  1039. TfdDepth_UI1 = class(TFormatDescriptor) //1* unsigned int
  1040. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1041. procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1042. constructor Create; override;
  1043. end;
  1044. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1045. TfdAlpha4 = class(TfdAlpha_UB1)
  1046. constructor Create; override;
  1047. end;
  1048. TfdAlpha8 = class(TfdAlpha_UB1)
  1049. constructor Create; override;
  1050. end;
  1051. TfdAlpha12 = class(TfdAlpha_US1)
  1052. constructor Create; override;
  1053. end;
  1054. TfdAlpha16 = class(TfdAlpha_US1)
  1055. constructor Create; override;
  1056. end;
  1057. TfdLuminance4 = class(TfdLuminance_UB1)
  1058. constructor Create; override;
  1059. end;
  1060. TfdLuminance8 = class(TfdLuminance_UB1)
  1061. constructor Create; override;
  1062. end;
  1063. TfdLuminance12 = class(TfdLuminance_US1)
  1064. constructor Create; override;
  1065. end;
  1066. TfdLuminance16 = class(TfdLuminance_US1)
  1067. constructor Create; override;
  1068. end;
  1069. TfdLuminance4Alpha4 = class(TfdLuminanceAlpha_UB2)
  1070. constructor Create; override;
  1071. end;
  1072. TfdLuminance6Alpha2 = class(TfdLuminanceAlpha_UB2)
  1073. constructor Create; override;
  1074. end;
  1075. TfdLuminance8Alpha8 = class(TfdLuminanceAlpha_UB2)
  1076. constructor Create; override;
  1077. end;
  1078. TfdLuminance12Alpha4 = class(TfdLuminanceAlpha_US2)
  1079. constructor Create; override;
  1080. end;
  1081. TfdLuminance12Alpha12 = class(TfdLuminanceAlpha_US2)
  1082. constructor Create; override;
  1083. end;
  1084. TfdLuminance16Alpha16 = class(TfdLuminanceAlpha_US2)
  1085. constructor Create; override;
  1086. end;
  1087. TfdR3G3B2 = class(TfdUniversal_UB1)
  1088. constructor Create; override;
  1089. end;
  1090. TfdRGB4 = class(TfdUniversal_US1)
  1091. constructor Create; override;
  1092. end;
  1093. TfdR5G6B5 = class(TfdUniversal_US1)
  1094. constructor Create; override;
  1095. end;
  1096. TfdRGB5 = class(TfdUniversal_US1)
  1097. constructor Create; override;
  1098. end;
  1099. TfdRGB8 = class(TfdRGB_UB3)
  1100. constructor Create; override;
  1101. end;
  1102. TfdRGB10 = class(TfdUniversal_UI1)
  1103. constructor Create; override;
  1104. end;
  1105. TfdRGB12 = class(TfdRGB_US3)
  1106. constructor Create; override;
  1107. end;
  1108. TfdRGB16 = class(TfdRGB_US3)
  1109. constructor Create; override;
  1110. end;
  1111. TfdRGBA2 = class(TfdRGBA_UB4)
  1112. constructor Create; override;
  1113. end;
  1114. TfdRGBA4 = class(TfdUniversal_US1)
  1115. constructor Create; override;
  1116. end;
  1117. TfdRGB5A1 = class(TfdUniversal_US1)
  1118. constructor Create; override;
  1119. end;
  1120. TfdRGBA8 = class(TfdRGBA_UB4)
  1121. constructor Create; override;
  1122. end;
  1123. TfdRGB10A2 = class(TfdUniversal_UI1)
  1124. constructor Create; override;
  1125. end;
  1126. TfdRGBA12 = class(TfdRGBA_US4)
  1127. constructor Create; override;
  1128. end;
  1129. TfdRGBA16 = class(TfdRGBA_US4)
  1130. constructor Create; override;
  1131. end;
  1132. TfdBGR4 = class(TfdUniversal_US1)
  1133. constructor Create; override;
  1134. end;
  1135. TfdB5G6R5 = class(TfdUniversal_US1)
  1136. constructor Create; override;
  1137. end;
  1138. TfdBGR5 = class(TfdUniversal_US1)
  1139. constructor Create; override;
  1140. end;
  1141. TfdBGR8 = class(TfdBGR_UB3)
  1142. constructor Create; override;
  1143. end;
  1144. TfdBGR10 = class(TfdUniversal_UI1)
  1145. constructor Create; override;
  1146. end;
  1147. TfdBGR12 = class(TfdBGR_US3)
  1148. constructor Create; override;
  1149. end;
  1150. TfdBGR16 = class(TfdBGR_US3)
  1151. constructor Create; override;
  1152. end;
  1153. TfdBGRA2 = class(TfdBGRA_UB4)
  1154. constructor Create; override;
  1155. end;
  1156. TfdBGRA4 = class(TfdUniversal_US1)
  1157. constructor Create; override;
  1158. end;
  1159. TfdBGR5A1 = class(TfdUniversal_US1)
  1160. constructor Create; override;
  1161. end;
  1162. TfdBGRA8 = class(TfdBGRA_UB4)
  1163. constructor Create; override;
  1164. end;
  1165. TfdBGR10A2 = class(TfdUniversal_UI1)
  1166. constructor Create; override;
  1167. end;
  1168. TfdBGRA12 = class(TfdBGRA_US4)
  1169. constructor Create; override;
  1170. end;
  1171. TfdBGRA16 = class(TfdBGRA_US4)
  1172. constructor Create; override;
  1173. end;
  1174. TfdDepth16 = class(TfdDepth_US1)
  1175. constructor Create; override;
  1176. end;
  1177. TfdDepth24 = class(TfdDepth_UI1)
  1178. constructor Create; override;
  1179. end;
  1180. TfdDepth32 = class(TfdDepth_UI1)
  1181. constructor Create; override;
  1182. end;
  1183. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1184. TBitfieldFormat = class(TFormatDescriptor)
  1185. private
  1186. procedure SetRedMask (const aValue: UInt64);
  1187. procedure SetGreenMask(const aValue: UInt64);
  1188. procedure SetBlueMask (const aValue: UInt64);
  1189. procedure SetAlphaMask(const aValue: UInt64);
  1190. procedure Update(aMask: UInt64; out aRange: Cardinal; out aShift: Byte);
  1191. public
  1192. property RedMask: UInt64 read GetRedMask write SetRedMask;
  1193. property GreenMask: UInt64 read GetGreenMask write SetGreenMask;
  1194. property BlueMask: UInt64 read GetBlueMask write SetBlueMask;
  1195. property AlphaMask: UInt64 read GetAlphaMask write SetAlphaMask;
  1196. property PixelSize: Single read fPixelSize write fPixelSize;
  1197. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1198. procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1199. end;
  1200. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1201. TColorTableEnty = packed record
  1202. b, g, r, a: Byte;
  1203. end;
  1204. TColorTable = array of TColorTableEnty;
  1205. TColorTableFormat = class(TFormatDescriptor)
  1206. private
  1207. fColorTable: TColorTable;
  1208. public
  1209. property PixelSize: Single read fPixelSize write fPixelSize;
  1210. property ColorTable: TColorTable read fColorTable write fColorTable;
  1211. property Range: TglBitmapColorRec read fRange write fRange;
  1212. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1213. procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1214. destructor Destroy; override;
  1215. end;
  1216. const
  1217. LUMINANCE_WEIGHT_R = 0.30;
  1218. LUMINANCE_WEIGHT_G = 0.59;
  1219. LUMINANCE_WEIGHT_B = 0.11;
  1220. ALPHA_WEIGHT_R = 0.30;
  1221. ALPHA_WEIGHT_G = 0.59;
  1222. ALPHA_WEIGHT_B = 0.11;
  1223. DEPTH_WEIGHT_R = 0.333333333;
  1224. DEPTH_WEIGHT_G = 0.333333333;
  1225. DEPTH_WEIGHT_B = 0.333333333;
  1226. UNSUPPORTED_FORMAT = 'the given format isn''t supported by this function.';
  1227. FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
  1228. TfdEmpty,
  1229. TfdAlpha4,
  1230. TfdAlpha8,
  1231. TfdAlpha12,
  1232. TfdAlpha16,
  1233. TfdLuminance4,
  1234. TfdLuminance8,
  1235. TfdLuminance12,
  1236. TfdLuminance16,
  1237. TfdLuminance4Alpha4,
  1238. TfdLuminance6Alpha2,
  1239. TfdLuminance8Alpha8,
  1240. TfdLuminance12Alpha4,
  1241. TfdLuminance12Alpha12,
  1242. TfdLuminance16Alpha16,
  1243. TfdR3G3B2,
  1244. TfdRGB4,
  1245. TfdR5G6B5,
  1246. TfdRGB5,
  1247. TfdRGB8,
  1248. TfdRGB10,
  1249. TfdRGB12,
  1250. TfdRGB16,
  1251. TfdRGBA2,
  1252. TfdRGBA4,
  1253. TfdRGB5A1,
  1254. TfdRGBA8,
  1255. TfdRGB10A2,
  1256. TfdRGBA12,
  1257. TfdRGBA16,
  1258. TfdBGR4,
  1259. TfdB5G6R5,
  1260. TfdBGR5,
  1261. TfdBGR8,
  1262. TfdBGR10,
  1263. TfdBGR12,
  1264. TfdBGR16,
  1265. TfdBGRA2,
  1266. TfdBGRA4,
  1267. TfdBGR5A1,
  1268. TfdBGRA8,
  1269. TfdBGR10A2,
  1270. TfdBGRA12,
  1271. TfdBGRA16,
  1272. TfdDepth16,
  1273. TfdDepth24,
  1274. TfdDepth32
  1275. );
  1276. var
  1277. FormatDescriptorCS: TCriticalSection;
  1278. FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
  1279. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1280. function glBitmapPosition(X, Y: Integer): TglBitmapPixelPosition;
  1281. begin
  1282. result.Fields := [];
  1283. if X >= 0 then
  1284. result.Fields := result.Fields + [ffX];
  1285. if Y >= 0 then
  1286. result.Fields := result.Fields + [ffY];
  1287. result.X := Max(0, X);
  1288. result.Y := Max(0, Y);
  1289. end;
  1290. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1291. function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
  1292. begin
  1293. result.r := r;
  1294. result.g := g;
  1295. result.b := b;
  1296. result.a := a;
  1297. end;
  1298. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1299. function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
  1300. begin
  1301. //TODO Supported File Formats!
  1302. result := [ftDDS, ftTGA, ftBMP];
  1303. (*
  1304. {$IFDEF GLB_SUPPORT_PNG_WRITE}
  1305. if aFormat in [
  1306. tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16,
  1307. tfLuminance4, tfLuminance8, tfLuminance12, tfLuminance16,
  1308. tfuminance4Alpha4, tfLuminance6Alpha2, tfLuminance8Alpha8, tfLuminance12Alpha4, tfLuminance12Alpha12, tfLuminance16Alpha16,
  1309. tfR3G3B2, tfRGB4, tfRGB5, tfRGB8, tfRGB10, tfRGB12, tfRGB16,
  1310. tfRGBA2, tfRGBA4, tfRGB5A1, tfRGBA8, tfRGB10A2, tfRGBA12, tfRGBA16,
  1311. tfDepth16, tfDepth24, tfDepth32]
  1312. then
  1313. result := result + [ftPNG];
  1314. {$ENDIF}
  1315. {$IFDEF GLB_SUPPORT_JPEG_WRITE}
  1316. if Format in [
  1317. tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16,
  1318. tfLuminance4, tfLuminance8, tfLuminance12, tfLuminance16,
  1319. tfR3G3B2, tfRGB4, tfRGB5, tfRGB8, tfRGB10, tfRGB12, tfRGB16,
  1320. tfDepth16, tfDepth24, tfDepth32]
  1321. then
  1322. result := result + [ftJPEG];
  1323. {$ENDIF}
  1324. if aFormat in [
  1325. tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16,
  1326. tfLuminance4, tfLuminance8, tfLuminance12, tfLuminance16,
  1327. tfuminance4Alpha4, tfLuminance6Alpha2, tfLuminance8Alpha8, tfLuminance12Alpha4, tfLuminance12Alpha12, tfLuminance16Alpha16,
  1328. tfR3G3B2, tfRGB4, tfRGB5, tfRGB8, tfRGB10, tfRGB12, tfRGB16,
  1329. tfRGBA2, tfRGBA4, tfRGB5A1, tfRGBA8, tfRGB10A2, tfRGBA12, tfRGBA16,
  1330. tfDepth16, tfDepth24, tfDepth32]
  1331. then
  1332. result := result + [ftDDS, ftTGA, ftBMP];
  1333. *)
  1334. end;
  1335. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1336. function IsPowerOfTwo(aNumber: Integer): Boolean;
  1337. begin
  1338. while (aNumber and 1) = 0 do
  1339. aNumber := aNumber shr 1;
  1340. result := aNumber = 1;
  1341. end;
  1342. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1343. function GetTopMostBit(aBitSet: UInt64): Integer;
  1344. begin
  1345. result := 0;
  1346. while aBitSet > 0 do begin
  1347. inc(result);
  1348. aBitSet := aBitSet shr 1;
  1349. end;
  1350. end;
  1351. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1352. function CountSetBits(aBitSet: UInt64): Integer;
  1353. begin
  1354. result := 0;
  1355. while aBitSet > 0 do begin
  1356. if (aBitSet and 1) = 1 then
  1357. inc(result);
  1358. aBitSet := aBitSet shr 1;
  1359. end;
  1360. end;
  1361. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1362. function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
  1363. begin
  1364. result := Trunc(
  1365. LUMINANCE_WEIGHT_R * aPixel.Data.r +
  1366. LUMINANCE_WEIGHT_G * aPixel.Data.g +
  1367. LUMINANCE_WEIGHT_B * aPixel.Data.b);
  1368. end;
  1369. function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
  1370. begin
  1371. result := Trunc(
  1372. DEPTH_WEIGHT_R * aPixel.Data.r +
  1373. DEPTH_WEIGHT_G * aPixel.Data.g +
  1374. DEPTH_WEIGHT_B * aPixel.Data.b);
  1375. end;
  1376. //TODO check _ARB functions and constants
  1377. (* GLB_NO_NATIVE_GL
  1378. {$IFNDEF GLB_NO_NATIVE_GL}
  1379. procedure ReadOpenGLExtensions;
  1380. var
  1381. {$IFDEF GLB_DELPHI}
  1382. Context: HGLRC;
  1383. {$ENDIF}
  1384. Buffer: AnsiString;
  1385. MajorVersion, MinorVersion: Integer;
  1386. procedure TrimVersionString(Buffer: AnsiString; var Major, Minor: Integer);
  1387. var
  1388. Separator: Integer;
  1389. begin
  1390. Minor := 0;
  1391. Major := 0;
  1392. Separator := Pos(AnsiString('.'), Buffer);
  1393. if (Separator > 1) and (Separator < Length(Buffer)) and
  1394. (Buffer[Separator - 1] in ['0'..'9']) and
  1395. (Buffer[Separator + 1] in ['0'..'9']) then begin
  1396. Dec(Separator);
  1397. while (Separator > 0) and (Buffer[Separator] in ['0'..'9']) do
  1398. Dec(Separator);
  1399. Delete(Buffer, 1, Separator);
  1400. Separator := Pos(AnsiString('.'), Buffer) + 1;
  1401. while (Separator <= Length(Buffer)) and (AnsiChar(Buffer[Separator]) in ['0'..'9']) do
  1402. Inc(Separator);
  1403. Delete(Buffer, Separator, 255);
  1404. Separator := Pos(AnsiString('.'), Buffer);
  1405. Major := StrToInt(Copy(String(Buffer), 1, Separator - 1));
  1406. Minor := StrToInt(Copy(String(Buffer), Separator + 1, 1));
  1407. end;
  1408. end;
  1409. function CheckExtension(const Extension: AnsiString): Boolean;
  1410. var
  1411. ExtPos: Integer;
  1412. begin
  1413. ExtPos := Pos(Extension, Buffer);
  1414. result := ExtPos > 0;
  1415. if result then
  1416. result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
  1417. end;
  1418. function glLoad (aFunc: pAnsiChar): pointer;
  1419. begin
  1420. {$IFDEF LINUX}
  1421. result := glXGetProcAddress(aFunc);
  1422. {$else}
  1423. result := wglGetProcAddress(aFunc);
  1424. {$ENDIF}
  1425. end;
  1426. begin
  1427. {$IFDEF GLB_DELPHI}
  1428. Context := wglGetCurrentContext;
  1429. if Context <> gLastContext then begin
  1430. gLastContext := Context;
  1431. {$ENDIF}
  1432. // Version
  1433. Buffer := glGetString(GL_VERSION);
  1434. TrimVersionString(Buffer, MajorVersion, MinorVersion);
  1435. GL_VERSION_1_2 := false;
  1436. GL_VERSION_1_3 := false;
  1437. GL_VERSION_1_4 := false;
  1438. GL_VERSION_2_0 := false;
  1439. if MajorVersion = 1 then begin
  1440. if MinorVersion >= 1 then begin
  1441. if MinorVersion >= 2 then
  1442. GL_VERSION_1_2 := true;
  1443. if MinorVersion >= 3 then
  1444. GL_VERSION_1_3 := true;
  1445. if MinorVersion >= 4 then
  1446. GL_VERSION_1_4 := true;
  1447. end;
  1448. end;
  1449. if MajorVersion >= 2 then begin
  1450. GL_VERSION_1_2 := true;
  1451. GL_VERSION_1_3 := true;
  1452. GL_VERSION_1_4 := true;
  1453. GL_VERSION_2_0 := true;
  1454. end;
  1455. // Extensions
  1456. Buffer := glGetString(GL_EXTENSIONS);
  1457. GL_ARB_texture_border_clamp := CheckExtension('GL_ARB_texture_border_clamp');
  1458. GL_ARB_texture_cube_map := CheckExtension('GL_ARB_texture_cube_map');
  1459. GL_ARB_texture_compression := CheckExtension('GL_ARB_texture_compression');
  1460. GL_ARB_texture_non_power_of_two := CheckExtension('GL_ARB_texture_non_power_of_two');
  1461. GL_ARB_texture_rectangle := CheckExtension('GL_ARB_texture_rectangle');
  1462. GL_ARB_texture_mirrored_repeat := CheckExtension('GL_ARB_texture_mirrored_repeat');
  1463. GL_EXT_bgra := CheckExtension('GL_EXT_bgra');
  1464. GL_EXT_texture_edge_clamp := CheckExtension('GL_EXT_texture_edge_clamp');
  1465. GL_EXT_texture_cube_map := CheckExtension('GL_EXT_texture_cube_map');
  1466. GL_EXT_texture_compression_s3tc := CheckExtension('GL_EXT_texture_compression_s3tc');
  1467. GL_EXT_texture_filter_anisotropic := CheckExtension('GL_EXT_texture_filter_anisotropic');
  1468. GL_EXT_texture_rectangle := CheckExtension('GL_EXT_texture_rectangle');
  1469. GL_NV_texture_rectangle := CheckExtension('GL_NV_texture_rectangle');
  1470. GL_IBM_texture_mirrored_repeat := CheckExtension('GL_IBM_texture_mirrored_repeat');
  1471. GL_SGIS_generate_mipmap := CheckExtension('GL_SGIS_generate_mipmap');
  1472. // Funtions
  1473. if GL_VERSION_1_3 then begin
  1474. // Loading Core
  1475. glCompressedTexImage1D := glLoad('glCompressedTexImage1D');
  1476. glCompressedTexImage2D := glLoad('glCompressedTexImage2D');
  1477. glGetCompressedTexImage := glLoad('glGetCompressedTexImage');
  1478. end else
  1479. begin
  1480. // Try loading Extension
  1481. glCompressedTexImage1D := glLoad('glCompressedTexImage1DARB');
  1482. glCompressedTexImage2D := glLoad('glCompressedTexImage2DARB');
  1483. glGetCompressedTexImage := glLoad('glGetCompressedTexImageARB');
  1484. end;
  1485. {$IFDEF GLB_DELPHI}
  1486. end;
  1487. {$ENDIF}
  1488. end;
  1489. {$ENDIF}
  1490. *)
  1491. (* TODO GLB_DELPHI
  1492. {$IFDEF GLB_DELPHI}
  1493. function CreateGrayPalette: HPALETTE;
  1494. var
  1495. Idx: Integer;
  1496. Pal: PLogPalette;
  1497. begin
  1498. GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
  1499. Pal.palVersion := $300;
  1500. Pal.palNumEntries := 256;
  1501. {$IFOPT R+}
  1502. {$DEFINE GLB_TEMPRANGECHECK}
  1503. {$R-}
  1504. {$ENDIF}
  1505. for Idx := 0 to 256 - 1 do begin
  1506. Pal.palPalEntry[Idx].peRed := Idx;
  1507. Pal.palPalEntry[Idx].peGreen := Idx;
  1508. Pal.palPalEntry[Idx].peBlue := Idx;
  1509. Pal.palPalEntry[Idx].peFlags := 0;
  1510. end;
  1511. {$IFDEF GLB_TEMPRANGECHECK}
  1512. {$UNDEF GLB_TEMPRANGECHECK}
  1513. {$R+}
  1514. {$ENDIF}
  1515. result := CreatePalette(Pal^);
  1516. FreeMem(Pal);
  1517. end;
  1518. {$ENDIF}
  1519. *)
  1520. (* TODO GLB_SDL_IMAGE
  1521. {$IFDEF GLB_SDL_IMAGE}
  1522. function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
  1523. begin
  1524. result := TStream(context^.unknown.data1).Seek(offset, whence);
  1525. end;
  1526. function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
  1527. begin
  1528. result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
  1529. end;
  1530. function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
  1531. begin
  1532. result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
  1533. end;
  1534. function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
  1535. begin
  1536. result := 0;
  1537. end;
  1538. function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
  1539. begin
  1540. result := SDL_AllocRW;
  1541. if result = nil then
  1542. raise EglBitmapException.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
  1543. result^.seek := glBitmapRWseek;
  1544. result^.read := glBitmapRWread;
  1545. result^.write := glBitmapRWwrite;
  1546. result^.close := glBitmapRWclose;
  1547. result^.unknown.data1 := Stream;
  1548. end;
  1549. {$ENDIF}
  1550. *)
  1551. (* TODO LoadFuncs
  1552. function LoadTexture(Filename: String; var Texture: Cardinal{$IFDEF GLB_DELPHI}; LoadFromRes : Boolean; Instance: Cardinal{$ENDIF}): Boolean;
  1553. var
  1554. glBitmap: TglBitmap2D;
  1555. begin
  1556. result := false;
  1557. Texture := 0;
  1558. {$IFDEF GLB_DELPHI}
  1559. if Instance = 0 then
  1560. Instance := HInstance;
  1561. if (LoadFromRes) then
  1562. glBitmap := TglBitmap2D.CreateFromResourceName(Instance, FileName)
  1563. else
  1564. {$ENDIF}
  1565. glBitmap := TglBitmap2D.Create(FileName);
  1566. try
  1567. glBitmap.DeleteTextureOnFree := false;
  1568. glBitmap.FreeDataAfterGenTexture := false;
  1569. glBitmap.GenTexture(true);
  1570. if (glBitmap.ID > 0) then begin
  1571. Texture := glBitmap.ID;
  1572. result := true;
  1573. end;
  1574. finally
  1575. glBitmap.Free;
  1576. end;
  1577. end;
  1578. function LoadCubeMap(PositiveX, NegativeX, PositiveY, NegativeY, PositiveZ, NegativeZ: String; var Texture: Cardinal{$IFDEF GLB_DELPHI}; LoadFromRes : Boolean; Instance: Cardinal{$ENDIF}): Boolean;
  1579. var
  1580. CM: TglBitmapCubeMap;
  1581. begin
  1582. Texture := 0;
  1583. {$IFDEF GLB_DELPHI}
  1584. if Instance = 0 then
  1585. Instance := HInstance;
  1586. {$ENDIF}
  1587. CM := TglBitmapCubeMap.Create;
  1588. try
  1589. CM.DeleteTextureOnFree := false;
  1590. // Maps
  1591. {$IFDEF GLB_DELPHI}
  1592. if (LoadFromRes) then
  1593. CM.LoadFromResource(Instance, PositiveX)
  1594. else
  1595. {$ENDIF}
  1596. CM.LoadFromFile(PositiveX);
  1597. CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X);
  1598. {$IFDEF GLB_DELPHI}
  1599. if (LoadFromRes) then
  1600. CM.LoadFromResource(Instance, NegativeX)
  1601. else
  1602. {$ENDIF}
  1603. CM.LoadFromFile(NegativeX);
  1604. CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X);
  1605. {$IFDEF GLB_DELPHI}
  1606. if (LoadFromRes) then
  1607. CM.LoadFromResource(Instance, PositiveY)
  1608. else
  1609. {$ENDIF}
  1610. CM.LoadFromFile(PositiveY);
  1611. CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y);
  1612. {$IFDEF GLB_DELPHI}
  1613. if (LoadFromRes) then
  1614. CM.LoadFromResource(Instance, NegativeY)
  1615. else
  1616. {$ENDIF}
  1617. CM.LoadFromFile(NegativeY);
  1618. CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
  1619. {$IFDEF GLB_DELPHI}
  1620. if (LoadFromRes) then
  1621. CM.LoadFromResource(Instance, PositiveZ)
  1622. else
  1623. {$ENDIF}
  1624. CM.LoadFromFile(PositiveZ);
  1625. CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
  1626. {$IFDEF GLB_DELPHI}
  1627. if (LoadFromRes) then
  1628. CM.LoadFromResource(Instance, NegativeZ)
  1629. else
  1630. {$ENDIF}
  1631. CM.LoadFromFile(NegativeZ);
  1632. CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
  1633. Texture := CM.ID;
  1634. result := true;
  1635. finally
  1636. CM.Free;
  1637. end;
  1638. end;
  1639. function LoadNormalMap(Size: Integer; var Texture: Cardinal): Boolean;
  1640. var
  1641. NM: TglBitmapNormalMap;
  1642. begin
  1643. Texture := 0;
  1644. NM := TglBitmapNormalMap.Create;
  1645. try
  1646. NM.DeleteTextureOnFree := false;
  1647. NM.GenerateNormalMap(Size);
  1648. Texture := NM.ID;
  1649. result := true;
  1650. finally
  1651. NM.Free;
  1652. end;
  1653. end;
  1654. *)
  1655. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1656. procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
  1657. begin
  1658. glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
  1659. end;
  1660. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1661. procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
  1662. begin
  1663. glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
  1664. end;
  1665. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1666. procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
  1667. begin
  1668. glBitmapDefaultMipmap := aValue;
  1669. end;
  1670. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1671. procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
  1672. begin
  1673. glBitmapDefaultFormat := aFormat;
  1674. end;
  1675. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1676. procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
  1677. begin
  1678. glBitmapDefaultFilterMin := aMin;
  1679. glBitmapDefaultFilterMag := aMag;
  1680. end;
  1681. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1682. procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
  1683. begin
  1684. glBitmapDefaultWrapS := S;
  1685. glBitmapDefaultWrapT := T;
  1686. glBitmapDefaultWrapR := R;
  1687. end;
  1688. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1689. function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
  1690. begin
  1691. result := glBitmapDefaultDeleteTextureOnFree;
  1692. end;
  1693. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1694. function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
  1695. begin
  1696. result := glBitmapDefaultFreeDataAfterGenTextures;
  1697. end;
  1698. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1699. function glBitmapGetDefaultMipmap: TglBitmapMipMap;
  1700. begin
  1701. result := glBitmapDefaultMipmap;
  1702. end;
  1703. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1704. function glBitmapGetDefaultFormat: TglBitmapFormat;
  1705. begin
  1706. result := glBitmapDefaultFormat;
  1707. end;
  1708. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1709. procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
  1710. begin
  1711. aMin := glBitmapDefaultFilterMin;
  1712. aMag := glBitmapDefaultFilterMag;
  1713. end;
  1714. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1715. procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
  1716. begin
  1717. S := glBitmapDefaultWrapS;
  1718. T := glBitmapDefaultWrapT;
  1719. R := glBitmapDefaultWrapR;
  1720. end;
  1721. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1722. //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1723. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1724. function TFormatDescriptor.GetRedMask: UInt64;
  1725. begin
  1726. result := fRange.r shl fShift.r;
  1727. end;
  1728. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1729. function TFormatDescriptor.GetGreenMask: UInt64;
  1730. begin
  1731. result := fRange.g shl fShift.g;
  1732. end;
  1733. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1734. function TFormatDescriptor.GetBlueMask: UInt64;
  1735. begin
  1736. result := fRange.b shl fShift.b;
  1737. end;
  1738. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1739. function TFormatDescriptor.GetAlphaMask: UInt64;
  1740. begin
  1741. result := fRange.a shl fShift.a;
  1742. end;
  1743. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1744. function TFormatDescriptor.GetComponents: Integer;
  1745. var
  1746. i: Integer;
  1747. begin
  1748. result := 0;
  1749. for i := 0 to 3 do
  1750. if (fRange.arr[i] > 0) then
  1751. inc(result);
  1752. end;
  1753. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1754. function TFormatDescriptor.GetSize(const aSize: TglBitmapPixelPosition): Integer;
  1755. var
  1756. w, h: Integer;
  1757. begin
  1758. if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
  1759. w := Max(1, aSize.X);
  1760. h := Max(1, aSize.Y);
  1761. result := GetSize(w, h);
  1762. end else
  1763. result := 0;
  1764. end;
  1765. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1766. function TFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer;
  1767. begin
  1768. result := 0;
  1769. if (aWidth <= 0) or (aHeight <= 0) then
  1770. exit;
  1771. result := Ceil(aWidth * aHeight * fPixelSize);
  1772. end;
  1773. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1774. function TFormatDescriptor.CreateMappingData: Pointer;
  1775. begin
  1776. result := nil;
  1777. end;
  1778. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1779. procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
  1780. begin
  1781. //DUMMY
  1782. end;
  1783. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1784. function TFormatDescriptor.IsEmpty: Boolean;
  1785. begin
  1786. result := (fFormat = tfEmpty);
  1787. end;
  1788. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1789. function TFormatDescriptor.HasAlpha: Boolean;
  1790. begin
  1791. result := (fRange.a > 0);
  1792. end;
  1793. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1794. function TFormatDescriptor.MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: UInt64): Boolean;
  1795. begin
  1796. result := false;
  1797. if (aRedMask = 0) and (aGreenMask = 0) and (aBlueMask = 0) and (aAlphaMask = 0) then
  1798. raise EglBitmapException.Create('FormatCheckFormat - All Masks are 0');
  1799. if (aRedMask <> RedMask) then
  1800. exit;
  1801. if (aGreenMask <> GreenMask) then
  1802. exit;
  1803. if (aBlueMask <> BlueMask) then
  1804. exit;
  1805. if (aAlphaMask <> AlphaMask) then
  1806. exit;
  1807. result := true;
  1808. end;
  1809. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1810. procedure TFormatDescriptor.PreparePixel(var aPixel: TglBitmapPixelData);
  1811. begin
  1812. FillChar(aPixel, SizeOf(aPixel), 0);
  1813. aPixel.Data := fRange;
  1814. aPixel.Range := fRange;
  1815. aPixel.Format := fFormat;
  1816. end;
  1817. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1818. constructor TFormatDescriptor.Create;
  1819. begin
  1820. inherited Create;
  1821. fFormat := tfEmpty;
  1822. fWithAlpha := tfEmpty;
  1823. fWithoutAlpha := tfEmpty;
  1824. fPixelSize := 0.0;
  1825. fglFormat := 0;
  1826. fglInternalFormat := 0;
  1827. fglDataFormat := 0;
  1828. FillChar(fRange, 0, SizeOf(fRange));
  1829. FillChar(fShift, 0, SizeOf(fShift));
  1830. end;
  1831. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1832. //TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1833. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1834. procedure TfdAlpha_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  1835. begin
  1836. aData^ := aPixel.Data.a;
  1837. inc(aData);
  1838. end;
  1839. procedure TfdAlpha_UB1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  1840. begin
  1841. aPixel.Data.r := 0;
  1842. aPixel.Data.g := 0;
  1843. aPixel.Data.b := 0;
  1844. aPixel.Data.a := aData^;
  1845. inc(aData^);
  1846. end;
  1847. constructor TfdAlpha_UB1.Create;
  1848. begin
  1849. inherited Create;
  1850. fPixelSize := 1.0;
  1851. fRange.a := $FF;
  1852. fglFormat := GL_ALPHA;
  1853. fglDataFormat := GL_UNSIGNED_BYTE;
  1854. end;
  1855. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1856. //TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1857. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1858. procedure TfdLuminance_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  1859. begin
  1860. aData^ := LuminanceWeight(aPixel);
  1861. inc(aData);
  1862. end;
  1863. procedure TfdLuminance_UB1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  1864. begin
  1865. aPixel.Data.r := aData^;
  1866. aPixel.Data.g := aData^;
  1867. aPixel.Data.b := aData^;
  1868. aPixel.Data.a := 0;
  1869. inc(aData);
  1870. end;
  1871. constructor TfdLuminance_UB1.Create;
  1872. begin
  1873. inherited Create;
  1874. fPixelSize := 1.0;
  1875. fRange.r := $FF;
  1876. fRange.g := $FF;
  1877. fRange.b := $FF;
  1878. fglFormat := GL_LUMINANCE;
  1879. fglDataFormat := GL_UNSIGNED_BYTE;
  1880. end;
  1881. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1882. //TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1883. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1884. procedure TfdUniversal_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  1885. var
  1886. i: Integer;
  1887. begin
  1888. aData^ := 0;
  1889. for i := 0 to 3 do
  1890. if (fRange.arr[i] > 0) then
  1891. aData^ := aData^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
  1892. inc(aData);
  1893. end;
  1894. procedure TfdUniversal_UB1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  1895. var
  1896. i: Integer;
  1897. begin
  1898. for i := 0 to 3 do
  1899. aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and fRange.arr[i];
  1900. inc(aData);
  1901. end;
  1902. constructor TfdUniversal_UB1.Create;
  1903. begin
  1904. inherited Create;
  1905. fPixelSize := 1.0;
  1906. end;
  1907. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1908. //TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1909. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1910. procedure TfdLuminanceAlpha_UB2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  1911. begin
  1912. inherited Map(aPixel, aData, aMapData);
  1913. aData^ := aPixel.Data.a;
  1914. inc(aData);
  1915. end;
  1916. procedure TfdLuminanceAlpha_UB2.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  1917. begin
  1918. inherited Unmap(aData, aPixel, aMapData);
  1919. aPixel.Data.a := aData^;
  1920. inc(aData);
  1921. end;
  1922. constructor TfdLuminanceAlpha_UB2.Create;
  1923. begin
  1924. inherited Create;
  1925. fPixelSize := 2.0;
  1926. fRange.a := $FF;
  1927. fShift.a := 8;
  1928. fglFormat := GL_LUMINANCE_ALPHA;
  1929. fglDataFormat := GL_UNSIGNED_BYTE;
  1930. end;
  1931. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1932. //TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1933. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1934. procedure TfdRGB_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  1935. begin
  1936. aData^ := aPixel.Data.r;
  1937. inc(aData);
  1938. aData^ := aPixel.Data.g;
  1939. inc(aData);
  1940. aData^ := aPixel.Data.b;
  1941. inc(aData);
  1942. end;
  1943. procedure TfdRGB_UB3.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  1944. begin
  1945. aPixel.Data.r := aData^;
  1946. inc(aData);
  1947. aPixel.Data.g := aData^;
  1948. inc(aData);
  1949. aPixel.Data.b := aData^;
  1950. inc(aData);
  1951. aPixel.Data.a := 0;
  1952. end;
  1953. constructor TfdRGB_UB3.Create;
  1954. begin
  1955. inherited Create;
  1956. fPixelSize := 3.0;
  1957. fRange.r := $FF;
  1958. fRange.g := $FF;
  1959. fRange.b := $FF;
  1960. fShift.r := 0;
  1961. fShift.g := 8;
  1962. fShift.b := 16;
  1963. fglFormat := GL_RGB;
  1964. fglDataFormat := GL_UNSIGNED_BYTE;
  1965. end;
  1966. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1967. //TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1968. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1969. procedure TfdBGR_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  1970. begin
  1971. aData^ := aPixel.Data.b;
  1972. inc(aData);
  1973. aData^ := aPixel.Data.g;
  1974. inc(aData);
  1975. aData^ := aPixel.Data.r;
  1976. inc(aData);
  1977. end;
  1978. procedure TfdBGR_UB3.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  1979. begin
  1980. aPixel.Data.b := aData^;
  1981. inc(aData);
  1982. aPixel.Data.g := aData^;
  1983. inc(aData);
  1984. aPixel.Data.r := aData^;
  1985. inc(aData);
  1986. aPixel.Data.a := 0;
  1987. end;
  1988. constructor TfdBGR_UB3.Create;
  1989. begin
  1990. fPixelSize := 3.0;
  1991. fRange.r := $FF;
  1992. fRange.g := $FF;
  1993. fRange.b := $FF;
  1994. fShift.r := 16;
  1995. fShift.g := 8;
  1996. fShift.b := 0;
  1997. fglFormat := GL_BGR;
  1998. fglDataFormat := GL_UNSIGNED_BYTE;
  1999. end;
  2000. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2001. //TdfRGBA_UB4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2002. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2003. procedure TfdRGBA_UB4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2004. begin
  2005. inherited Map(aPixel, aData, aMapData);
  2006. aData^ := aPixel.Data.a;
  2007. inc(aData);
  2008. end;
  2009. procedure TfdRGBA_UB4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2010. begin
  2011. inherited Unmap(aData, aPixel, aMapData);
  2012. aPixel.Data.a := aData^;
  2013. inc(aData);
  2014. end;
  2015. constructor TfdRGBA_UB4.Create;
  2016. begin
  2017. inherited Create;
  2018. fPixelSize := 4.0;
  2019. fRange.a := $FF;
  2020. fShift.a := 24;
  2021. fglFormat := GL_RGBA;
  2022. fglDataFormat := GL_UNSIGNED_BYTE;
  2023. end;
  2024. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2025. //TfdBGRA_UB4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2026. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2027. procedure TfdBGRA_UB4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2028. begin
  2029. inherited Map(aPixel, aData, aMapData);
  2030. aData^ := aPixel.Data.a;
  2031. inc(aData);
  2032. end;
  2033. procedure TfdBGRA_UB4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2034. begin
  2035. inherited Unmap(aData, aPixel, aMapData);
  2036. aPixel.Data.a := aData^;
  2037. inc(aData);
  2038. end;
  2039. constructor TfdBGRA_UB4.Create;
  2040. begin
  2041. inherited Create;
  2042. fPixelSize := 4.0;
  2043. fRange.a := $FF;
  2044. fShift.a := 24;
  2045. fglFormat := GL_BGRA;
  2046. fglDataFormat := GL_UNSIGNED_BYTE;
  2047. end;
  2048. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2049. //TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2050. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2051. procedure TfdAlpha_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2052. begin
  2053. PWord(aData)^ := aPixel.Data.a;
  2054. inc(aData, 2);
  2055. end;
  2056. procedure TfdAlpha_US1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2057. begin
  2058. aPixel.Data.r := 0;
  2059. aPixel.Data.g := 0;
  2060. aPixel.Data.b := 0;
  2061. aPixel.Data.a := PWord(aData)^;
  2062. inc(aData, 2);
  2063. end;
  2064. constructor TfdAlpha_US1.Create;
  2065. begin
  2066. inherited Create;
  2067. fPixelSize := 2.0;
  2068. fRange.a := $FFFF;
  2069. fglFormat := GL_ALPHA;
  2070. fglDataFormat := GL_UNSIGNED_SHORT;
  2071. end;
  2072. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2073. //TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2074. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2075. procedure TfdLuminance_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2076. begin
  2077. PWord(aData)^ := LuminanceWeight(aPixel);
  2078. inc(aData, 2);
  2079. end;
  2080. procedure TfdLuminance_US1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2081. begin
  2082. aPixel.Data.r := PWord(aData)^;
  2083. aPixel.Data.g := PWord(aData)^;
  2084. aPixel.Data.b := PWord(aData)^;
  2085. aPixel.Data.a := 0;
  2086. inc(aData, 2);
  2087. end;
  2088. constructor TfdLuminance_US1.Create;
  2089. begin
  2090. inherited Create;
  2091. fPixelSize := 2.0;
  2092. fRange.r := $FFFF;
  2093. fRange.g := $FFFF;
  2094. fRange.b := $FFFF;
  2095. fglFormat := GL_LUMINANCE;
  2096. fglDataFormat := GL_UNSIGNED_SHORT;
  2097. end;
  2098. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2099. //TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2100. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2101. procedure TfdUniversal_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2102. var
  2103. i: Integer;
  2104. begin
  2105. PWord(aData)^ := 0;
  2106. for i := 0 to 3 do
  2107. if (fRange.arr[i] > 0) then
  2108. PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
  2109. inc(aData, 2);
  2110. end;
  2111. procedure TfdUniversal_US1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2112. var
  2113. i: Integer;
  2114. begin
  2115. for i := 0 to 3 do
  2116. aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and fRange.arr[i];
  2117. inc(aData, 2);
  2118. end;
  2119. constructor TfdUniversal_US1.Create;
  2120. begin
  2121. inherited Create;
  2122. fPixelSize := 2.0;
  2123. end;
  2124. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2125. //TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2126. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2127. procedure TfdDepth_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2128. begin
  2129. PWord(aData)^ := DepthWeight(aPixel);
  2130. inc(aData, 2);
  2131. end;
  2132. procedure TfdDepth_US1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2133. begin
  2134. aPixel.Data.r := PWord(aData)^;
  2135. aPixel.Data.g := PWord(aData)^;
  2136. aPixel.Data.b := PWord(aData)^;
  2137. aPixel.Data.a := 0;
  2138. inc(aData, 2);
  2139. end;
  2140. constructor TfdDepth_US1.Create;
  2141. begin
  2142. inherited Create;
  2143. fPixelSize := 2.0;
  2144. fRange.r := $FFFF;
  2145. fRange.g := $FFFF;
  2146. fRange.b := $FFFF;
  2147. fglFormat := GL_DEPTH_COMPONENT;
  2148. fglDataFormat := GL_UNSIGNED_SHORT;
  2149. end;
  2150. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2151. //TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2152. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2153. procedure TfdLuminanceAlpha_US2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2154. begin
  2155. inherited Map(aPixel, aData, aMapData);
  2156. PWord(aData)^ := aPixel.Data.a;
  2157. inc(aData, 2);
  2158. end;
  2159. procedure TfdLuminanceAlpha_US2.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2160. begin
  2161. inherited Unmap(aData, aPixel, aMapData);
  2162. aPixel.Data.a := PWord(aData)^;
  2163. inc(aData, 2);
  2164. end;
  2165. constructor TfdLuminanceAlpha_US2.Create;
  2166. begin
  2167. inherited Create;
  2168. fPixelSize := 4.0;
  2169. fRange.a := $FFFF;
  2170. fShift.a := 16;
  2171. fglFormat := GL_LUMINANCE_ALPHA;
  2172. fglDataFormat := GL_UNSIGNED_SHORT;
  2173. end;
  2174. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2175. //TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2176. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2177. procedure TfdRGB_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2178. begin
  2179. PWord(aData)^ := aPixel.Data.r;
  2180. inc(aData, 2);
  2181. PWord(aData)^ := aPixel.Data.g;
  2182. inc(aData, 2);
  2183. PWord(aData)^ := aPixel.Data.b;
  2184. inc(aData, 2);
  2185. end;
  2186. procedure TfdRGB_US3.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2187. begin
  2188. aPixel.Data.r := PWord(aData)^;
  2189. inc(aData, 2);
  2190. aPixel.Data.g := PWord(aData)^;
  2191. inc(aData, 2);
  2192. aPixel.Data.b := PWord(aData)^;
  2193. inc(aData, 2);
  2194. aPixel.Data.a := 0;
  2195. end;
  2196. constructor TfdRGB_US3.Create;
  2197. begin
  2198. inherited Create;
  2199. fPixelSize := 6.0;
  2200. fRange.r := $FFFF;
  2201. fRange.g := $FFFF;
  2202. fRange.b := $FFFF;
  2203. fShift.r := 0;
  2204. fShift.g := 16;
  2205. fShift.b := 32;
  2206. fglFormat := GL_RGB;
  2207. fglDataFormat := GL_UNSIGNED_SHORT;
  2208. end;
  2209. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2210. //TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2211. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2212. procedure TfdBGR_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2213. begin
  2214. PWord(aData)^ := aPixel.Data.b;
  2215. inc(aData, 2);
  2216. PWord(aData)^ := aPixel.Data.g;
  2217. inc(aData, 2);
  2218. PWord(aData)^ := aPixel.Data.r;
  2219. inc(aData, 2);
  2220. end;
  2221. procedure TfdBGR_US3.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2222. begin
  2223. aPixel.Data.b := PWord(aData)^;
  2224. inc(aData, 2);
  2225. aPixel.Data.g := PWord(aData)^;
  2226. inc(aData, 2);
  2227. aPixel.Data.r := PWord(aData)^;
  2228. inc(aData, 2);
  2229. aPixel.Data.a := 0;
  2230. end;
  2231. constructor TfdBGR_US3.Create;
  2232. begin
  2233. inherited Create;
  2234. fPixelSize := 6.0;
  2235. fRange.r := $FFFF;
  2236. fRange.g := $FFFF;
  2237. fRange.b := $FFFF;
  2238. fShift.r := 32;
  2239. fShift.g := 16;
  2240. fShift.b := 0;
  2241. fglFormat := GL_BGR;
  2242. fglDataFormat := GL_UNSIGNED_SHORT;
  2243. end;
  2244. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2245. //TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2246. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2247. procedure TfdRGBA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2248. begin
  2249. inherited Map(aPixel, aData, aMapData);
  2250. PWord(aData)^ := aPixel.Data.a;
  2251. inc(aData, 2);
  2252. end;
  2253. procedure TfdRGBA_US4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2254. begin
  2255. inherited Unmap(aData, aPixel, aMapData);
  2256. aPixel.Data.a := PWord(aData)^;
  2257. inc(aData, 2);
  2258. end;
  2259. constructor TfdRGBA_US4.Create;
  2260. begin
  2261. inherited Create;
  2262. fPixelSize := 8.0;
  2263. fRange.a := $FFFF;
  2264. fShift.a := 48;
  2265. fglFormat := GL_RGBA;
  2266. fglDataFormat := GL_UNSIGNED_SHORT;
  2267. end;
  2268. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2269. //TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2270. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2271. procedure TfdBGRA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2272. begin
  2273. inherited Map(aPixel, aData, aMapData);
  2274. PWord(aData)^ := aPixel.Data.a;
  2275. inc(aData, 2);
  2276. end;
  2277. procedure TfdBGRA_US4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2278. begin
  2279. inherited Unmap(aData, aPixel, aMapData);
  2280. aPixel.Data.a := PWord(aData)^;
  2281. inc(aData, 2);
  2282. end;
  2283. constructor TfdBGRA_US4.Create;
  2284. begin
  2285. inherited Create;
  2286. fPixelSize := 8.0;
  2287. fRange.a := $FFFF;
  2288. fShift.a := 48;
  2289. fglFormat := GL_BGRA;
  2290. fglDataFormat := GL_UNSIGNED_SHORT;
  2291. end;
  2292. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2293. //TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2294. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2295. procedure TfdUniversal_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2296. var
  2297. i: Integer;
  2298. begin
  2299. PCardinal(aData)^ := 0;
  2300. for i := 0 to 3 do
  2301. if (fRange.arr[i] > 0) then
  2302. PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
  2303. inc(aData, 4);
  2304. end;
  2305. procedure TfdUniversal_UI1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2306. var
  2307. i: Integer;
  2308. begin
  2309. for i := 0 to 3 do
  2310. aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and fRange.arr[i];
  2311. inc(aData, 2);
  2312. end;
  2313. constructor TfdUniversal_UI1.Create;
  2314. begin
  2315. inherited Create;
  2316. fPixelSize := 4.0;
  2317. end;
  2318. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2319. //TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2320. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2321. procedure TfdDepth_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2322. begin
  2323. PCardinal(aData)^ := DepthWeight(aPixel);
  2324. inc(aData, 4);
  2325. end;
  2326. procedure TfdDepth_UI1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2327. begin
  2328. aPixel.Data.r := PCardinal(aData)^;
  2329. aPixel.Data.g := PCardinal(aData)^;
  2330. aPixel.Data.b := PCardinal(aData)^;
  2331. aPixel.Data.a := 0;
  2332. inc(aData, 4);
  2333. end;
  2334. constructor TfdDepth_UI1.Create;
  2335. begin
  2336. inherited Create;
  2337. fPixelSize := 4.0;
  2338. fRange.r := $FFFFFFFF;
  2339. fRange.g := $FFFFFFFF;
  2340. fRange.b := $FFFFFFFF;
  2341. fglFormat := GL_DEPTH_COMPONENT;
  2342. fglDataFormat := GL_UNSIGNED_INT;
  2343. end;
  2344. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2345. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2346. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2347. constructor TfdAlpha4.Create;
  2348. begin
  2349. inherited Create;
  2350. fFormat := tfAlpha4;
  2351. fWithAlpha := tfAlpha4;
  2352. fglInternalFormat := GL_ALPHA4;
  2353. end;
  2354. constructor TfdAlpha8.Create;
  2355. begin
  2356. inherited Create;
  2357. fFormat := tfAlpha8;
  2358. fWithAlpha := tfAlpha8;
  2359. fglInternalFormat := GL_ALPHA8;
  2360. end;
  2361. constructor TfdAlpha12.Create;
  2362. begin
  2363. inherited Create;
  2364. fFormat := tfAlpha12;
  2365. fWithAlpha := tfAlpha12;
  2366. fglInternalFormat := GL_ALPHA12;
  2367. end;
  2368. constructor TfdAlpha16.Create;
  2369. begin
  2370. inherited Create;
  2371. fFormat := tfAlpha16;
  2372. fWithAlpha := tfAlpha16;
  2373. fglInternalFormat := GL_ALPHA16;
  2374. end;
  2375. constructor TfdLuminance4.Create;
  2376. begin
  2377. inherited Create;
  2378. fFormat := tfLuminance4;
  2379. fWithAlpha := tfLuminance4Alpha4;
  2380. fWithoutAlpha := tfLuminance4;
  2381. fglInternalFormat := GL_LUMINANCE4;
  2382. end;
  2383. constructor TfdLuminance8.Create;
  2384. begin
  2385. inherited Create;
  2386. fFormat := tfLuminance8;
  2387. fWithAlpha := tfLuminance8Alpha8;
  2388. fWithoutAlpha := tfLuminance8;
  2389. fglInternalFormat := GL_LUMINANCE8;
  2390. end;
  2391. constructor TfdLuminance12.Create;
  2392. begin
  2393. inherited Create;
  2394. fFormat := tfLuminance12;
  2395. fWithAlpha := tfLuminance12Alpha12;
  2396. fWithoutAlpha := tfLuminance12;
  2397. fglInternalFormat := GL_LUMINANCE12;
  2398. end;
  2399. constructor TfdLuminance16.Create;
  2400. begin
  2401. inherited Create;
  2402. fFormat := tfLuminance16;
  2403. fWithAlpha := tfLuminance16Alpha16;
  2404. fWithoutAlpha := tfLuminance16;
  2405. fglInternalFormat := GL_LUMINANCE16;
  2406. end;
  2407. constructor TfdLuminance4Alpha4.Create;
  2408. begin
  2409. inherited Create;
  2410. fFormat := tfLuminance4Alpha4;
  2411. fWithAlpha := tfLuminance4Alpha4;
  2412. fWithoutAlpha := tfLuminance4;
  2413. fglInternalFormat := GL_LUMINANCE4_ALPHA4;
  2414. end;
  2415. constructor TfdLuminance6Alpha2.Create;
  2416. begin
  2417. inherited Create;
  2418. fFormat := tfLuminance6Alpha2;
  2419. fWithAlpha := tfLuminance6Alpha2;
  2420. fWithoutAlpha := tfLuminance8;
  2421. fglInternalFormat := GL_LUMINANCE6_ALPHA2;
  2422. end;
  2423. constructor TfdLuminance8Alpha8.Create;
  2424. begin
  2425. inherited Create;
  2426. fFormat := tfLuminance8Alpha8;
  2427. fWithAlpha := tfLuminance8Alpha8;
  2428. fWithoutAlpha := tfLuminance8;
  2429. fglInternalFormat := GL_LUMINANCE8_ALPHA8;
  2430. end;
  2431. constructor TfdLuminance12Alpha4.Create;
  2432. begin
  2433. inherited Create;
  2434. fFormat := tfLuminance12Alpha4;
  2435. fWithAlpha := tfLuminance12Alpha4;
  2436. fWithoutAlpha := tfLuminance12;
  2437. fglInternalFormat := GL_LUMINANCE12_ALPHA4;
  2438. end;
  2439. constructor TfdLuminance12Alpha12.Create;
  2440. begin
  2441. inherited Create;
  2442. fFormat := tfLuminance12Alpha12;
  2443. fWithAlpha := tfLuminance12Alpha12;
  2444. fWithoutAlpha := tfLuminance12;
  2445. fglInternalFormat := GL_LUMINANCE12_ALPHA12;
  2446. end;
  2447. constructor TfdLuminance16Alpha16.Create;
  2448. begin
  2449. inherited Create;
  2450. fFormat := tfLuminance16Alpha16;
  2451. fWithAlpha := tfLuminance16Alpha16;
  2452. fWithoutAlpha := tfLuminance16;
  2453. fglInternalFormat := GL_LUMINANCE16_ALPHA16;
  2454. end;
  2455. constructor TfdR3G3B2.Create;
  2456. begin
  2457. inherited Create;
  2458. fFormat := tfR3G3B2;
  2459. fWithAlpha := tfRGBA2;
  2460. fWithoutAlpha := tfR3G3B2;
  2461. fRange.r := $7;
  2462. fRange.g := $7;
  2463. fRange.b := $3;
  2464. fShift.r := 0;
  2465. fShift.g := 3;
  2466. fShift.b := 6;
  2467. fglFormat := GL_RGB;
  2468. fglInternalFormat := GL_R3_G3_B2;
  2469. fglDataFormat := GL_UNSIGNED_BYTE_2_3_3_REV;
  2470. end;
  2471. constructor TfdRGB4.Create;
  2472. begin
  2473. inherited Create;
  2474. fFormat := tfRGB4;
  2475. fWithAlpha := tfRGBA4;
  2476. fWithoutAlpha := tfRGB4;
  2477. fRange.r := $F;
  2478. fRange.g := $F;
  2479. fRange.b := $F;
  2480. fShift.r := 0;
  2481. fShift.g := 4;
  2482. fShift.b := 8;
  2483. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2484. fglInternalFormat := GL_RGB4;
  2485. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
  2486. end;
  2487. constructor TfdR5G6B5.Create;
  2488. begin
  2489. inherited Create;
  2490. fFormat := tfR5G6B5;
  2491. fWithAlpha := tfRGBA4;
  2492. fWithoutAlpha := tfR5G6B5;
  2493. fRange.r := $1F;
  2494. fRange.g := $3F;
  2495. fRange.b := $1F;
  2496. fShift.r := 0;
  2497. fShift.g := 5;
  2498. fShift.b := 11;
  2499. fglFormat := GL_RGB;
  2500. fglInternalFormat := GL_RGB565;
  2501. fglDataFormat := GL_UNSIGNED_SHORT_5_6_5_REV;
  2502. end;
  2503. constructor TfdRGB5.Create;
  2504. begin
  2505. inherited Create;
  2506. fFormat := tfRGB5;
  2507. fWithAlpha := tfRGB5A1;
  2508. fWithoutAlpha := tfRGB5;
  2509. fRange.r := $1F;
  2510. fRange.g := $1F;
  2511. fRange.b := $1F;
  2512. fShift.r := 0;
  2513. fShift.g := 5;
  2514. fShift.b := 10;
  2515. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2516. fglInternalFormat := GL_RGB5;
  2517. fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
  2518. end;
  2519. constructor TfdRGB8.Create;
  2520. begin
  2521. inherited Create;
  2522. fFormat := tfRGB8;
  2523. fWithAlpha := tfRGBA8;
  2524. fWithoutAlpha := tfRGB8;
  2525. fglInternalFormat := GL_RGB8;
  2526. end;
  2527. constructor TfdRGB10.Create;
  2528. begin
  2529. inherited Create;
  2530. fFormat := tfRGB10;
  2531. fWithAlpha := tfRGB10A2;
  2532. fWithoutAlpha := tfRGB10;
  2533. fRange.r := $3FF;
  2534. fRange.g := $3FF;
  2535. fRange.b := $3FF;
  2536. fShift.r := 0;
  2537. fShift.g := 10;
  2538. fShift.b := 20;
  2539. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2540. fglInternalFormat := GL_RGB10;
  2541. fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
  2542. end;
  2543. constructor TfdRGB12.Create;
  2544. begin
  2545. inherited Create;
  2546. fFormat := tfRGB12;
  2547. fWithAlpha := tfRGBA12;
  2548. fWithoutAlpha := tfRGB12;
  2549. fglInternalFormat := GL_RGB12;
  2550. end;
  2551. constructor TfdRGB16.Create;
  2552. begin
  2553. inherited Create;
  2554. fFormat := tfRGB16;
  2555. fWithAlpha := tfRGBA16;
  2556. fWithoutAlpha := tfRGB16;
  2557. fglInternalFormat := GL_RGB16;
  2558. end;
  2559. constructor TfdRGBA2.Create;
  2560. begin
  2561. inherited Create;
  2562. fFormat := tfRGBA2;
  2563. fWithAlpha := tfRGBA2;
  2564. fWithoutAlpha := tfR3G3B2;
  2565. fglInternalFormat := GL_RGBA2;
  2566. end;
  2567. constructor TfdRGBA4.Create;
  2568. begin
  2569. inherited Create;
  2570. fFormat := tfRGBA4;
  2571. fWithAlpha := tfRGBA4;
  2572. fWithoutAlpha := tfRGB4;
  2573. fRange.r := $F;
  2574. fRange.g := $F;
  2575. fRange.b := $F;
  2576. fRange.a := $F;
  2577. fShift.r := 0;
  2578. fShift.g := 4;
  2579. fShift.b := 8;
  2580. fShift.a := 12;
  2581. fglFormat := GL_RGBA;
  2582. fglInternalFormat := GL_RGBA4;
  2583. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
  2584. end;
  2585. constructor TfdRGB5A1.Create;
  2586. begin
  2587. inherited Create;
  2588. fFormat := tfRGB5A1;
  2589. fWithAlpha := tfRGB5A1;
  2590. fWithoutAlpha := tfRGB5;
  2591. fRange.r := $1F;
  2592. fRange.g := $1F;
  2593. fRange.b := $1F;
  2594. fRange.a := $01;
  2595. fShift.r := 0;
  2596. fShift.g := 5;
  2597. fShift.b := 10;
  2598. fShift.a := 15;
  2599. fglFormat := GL_RGBA;
  2600. fglInternalFormat := GL_RGB5_A1;
  2601. fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
  2602. end;
  2603. constructor TfdRGBA8.Create;
  2604. begin
  2605. inherited Create;
  2606. fFormat := tfRGBA8;
  2607. fWithAlpha := tfRGBA8;
  2608. fWithoutAlpha := tfRGB8;
  2609. fglInternalFormat := GL_RGBA8;
  2610. end;
  2611. constructor TfdRGB10A2.Create;
  2612. begin
  2613. inherited Create;
  2614. fFormat := tfRGB10A2;
  2615. fWithAlpha := tfRGB10A2;
  2616. fWithoutAlpha := tfRGB10;
  2617. fRange.r := $3FF;
  2618. fRange.g := $3FF;
  2619. fRange.b := $3FF;
  2620. fRange.a := $003;
  2621. fShift.r := 0;
  2622. fShift.g := 10;
  2623. fShift.b := 20;
  2624. fShift.a := 30;
  2625. fglFormat := GL_RGBA;
  2626. fglInternalFormat := GL_RGB10_A2;
  2627. fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
  2628. end;
  2629. constructor TfdRGBA12.Create;
  2630. begin
  2631. inherited Create;
  2632. fFormat := tfRGBA12;
  2633. fWithAlpha := tfRGBA12;
  2634. fWithoutAlpha := tfRGB12;
  2635. fglInternalFormat := GL_RGBA12;
  2636. end;
  2637. constructor TfdRGBA16.Create;
  2638. begin
  2639. inherited Create;
  2640. fFormat := tfRGBA16;
  2641. fWithAlpha := tfRGBA16;
  2642. fWithoutAlpha := tfRGB16;
  2643. fglInternalFormat := GL_RGBA16;
  2644. end;
  2645. constructor TfdBGR4.Create;
  2646. begin
  2647. inherited Create;
  2648. fPixelSize := 2.0;
  2649. fFormat := tfBGR4;
  2650. fWithAlpha := tfBGRA4;
  2651. fWithoutAlpha := tfBGR4;
  2652. fRange.r := $F;
  2653. fRange.g := $F;
  2654. fRange.b := $F;
  2655. fRange.a := $0;
  2656. fShift.r := 8;
  2657. fShift.g := 4;
  2658. fShift.b := 0;
  2659. fShift.a := 0;
  2660. fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2661. fglInternalFormat := GL_RGB4;
  2662. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
  2663. end;
  2664. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2665. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2666. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2667. constructor TfdB5G6R5.Create;
  2668. begin
  2669. inherited Create;
  2670. fFormat := tfB5G6R5;
  2671. fWithAlpha := tfBGRA4;
  2672. fWithoutAlpha := tfB5G6R5;
  2673. fRange.r := $1F;
  2674. fRange.g := $3F;
  2675. fRange.b := $1F;
  2676. fShift.r := 11;
  2677. fShift.g := 5;
  2678. fShift.b := 0;
  2679. fglFormat := GL_RGB; //B5G6R5 is only possible as R5G6B5 -> use reverted dataformat
  2680. fglInternalFormat := GL_RGB8;
  2681. fglDataFormat := GL_UNSIGNED_SHORT_5_6_5;
  2682. end;
  2683. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2684. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2685. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2686. constructor TfdBGR5.Create;
  2687. begin
  2688. inherited Create;
  2689. fPixelSize := 2.0;
  2690. fFormat := tfBGR5;
  2691. fWithAlpha := tfBGR5A1;
  2692. fWithoutAlpha := tfBGR5;
  2693. fRange.r := $1F;
  2694. fRange.g := $1F;
  2695. fRange.b := $1F;
  2696. fRange.a := $00;
  2697. fShift.r := 10;
  2698. fShift.g := 5;
  2699. fShift.b := 0;
  2700. fShift.a := 0;
  2701. fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2702. fglInternalFormat := GL_RGB5;
  2703. fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
  2704. end;
  2705. constructor TfdBGR8.Create;
  2706. begin
  2707. inherited Create;
  2708. fFormat := tfBGR8;
  2709. fWithAlpha := tfBGRA8;
  2710. fWithoutAlpha := tfBGR8;
  2711. fglInternalFormat := GL_RGB8;
  2712. end;
  2713. constructor TfdBGR10.Create;
  2714. begin
  2715. inherited Create;
  2716. fFormat := tfBGR10;
  2717. fWithAlpha := tfBGR10A2;
  2718. fWithoutAlpha := tfBGR10;
  2719. fRange.r := $3FF;
  2720. fRange.g := $3FF;
  2721. fRange.b := $3FF;
  2722. fRange.a := $000;
  2723. fShift.r := 20;
  2724. fShift.g := 10;
  2725. fShift.b := 0;
  2726. fShift.a := 0;
  2727. fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2728. fglInternalFormat := GL_RGB10;
  2729. fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
  2730. end;
  2731. constructor TfdBGR12.Create;
  2732. begin
  2733. inherited Create;
  2734. fFormat := tfBGR12;
  2735. fWithAlpha := tfBGRA12;
  2736. fWithoutAlpha := tfBGR12;
  2737. fglInternalFormat := GL_RGB12;
  2738. end;
  2739. constructor TfdBGR16.Create;
  2740. begin
  2741. inherited Create;
  2742. fFormat := tfBGR16;
  2743. fWithAlpha := tfBGRA16;
  2744. fWithoutAlpha := tfBGR16;
  2745. fglInternalFormat := GL_RGB16;
  2746. end;
  2747. constructor TfdBGRA2.Create;
  2748. begin
  2749. inherited Create;
  2750. fFormat := tfBGRA2;
  2751. fWithAlpha := tfBGRA4;
  2752. fWithoutAlpha := tfBGR4;
  2753. fglInternalFormat := GL_RGBA2;
  2754. end;
  2755. constructor TfdBGRA4.Create;
  2756. begin
  2757. inherited Create;
  2758. fFormat := tfBGRA4;
  2759. fWithAlpha := tfBGRA4;
  2760. fWithoutAlpha := tfBGR4;
  2761. fRange.r := $F;
  2762. fRange.g := $F;
  2763. fRange.b := $F;
  2764. fRange.a := $F;
  2765. fShift.r := 8;
  2766. fShift.g := 4;
  2767. fShift.b := 0;
  2768. fShift.a := 12;
  2769. fglFormat := GL_BGRA;
  2770. fglInternalFormat := GL_RGBA4;
  2771. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
  2772. end;
  2773. constructor TfdBGR5A1.Create;
  2774. begin
  2775. inherited Create;
  2776. fFormat := tfBGR5A1;
  2777. fWithAlpha := tfBGR5A1;
  2778. fWithoutAlpha := tfBGR5;
  2779. fRange.r := $1F;
  2780. fRange.g := $1F;
  2781. fRange.b := $1F;
  2782. fRange.a := $01;
  2783. fShift.r := 10;
  2784. fShift.g := 5;
  2785. fShift.b := 0;
  2786. fShift.a := 15;
  2787. fglFormat := GL_BGRA;
  2788. fglInternalFormat := GL_RGB5_A1;
  2789. fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
  2790. end;
  2791. constructor TfdBGRA8.Create;
  2792. begin
  2793. inherited Create;
  2794. fFormat := tfBGRA8;
  2795. fWithAlpha := tfBGRA8;
  2796. fWithoutAlpha := tfBGR8;
  2797. fglInternalFormat := GL_RGBA8;
  2798. end;
  2799. constructor TfdBGR10A2.Create;
  2800. begin
  2801. inherited Create;
  2802. fFormat := tfBGR10A2;
  2803. fWithAlpha := tfBGR10A2;
  2804. fWithoutAlpha := tfBGR10;
  2805. fRange.r := $3FF;
  2806. fRange.g := $3FF;
  2807. fRange.b := $3FF;
  2808. fRange.a := $003;
  2809. fShift.r := 20;
  2810. fShift.g := 10;
  2811. fShift.b := 0;
  2812. fShift.a := 30;
  2813. fglFormat := GL_BGRA;
  2814. fglInternalFormat := GL_RGB10_A2;
  2815. fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
  2816. end;
  2817. constructor TfdBGRA12.Create;
  2818. begin
  2819. inherited Create;
  2820. fFormat := tfBGRA12;
  2821. fWithAlpha := tfBGRA12;
  2822. fWithoutAlpha := tfBGR12;
  2823. fglInternalFormat := GL_RGBA12;
  2824. end;
  2825. constructor TfdBGRA16.Create;
  2826. begin
  2827. inherited Create;
  2828. fFormat := tfBGRA16;
  2829. fWithAlpha := tfBGRA16;
  2830. fWithoutAlpha := tfBGR16;
  2831. fglInternalFormat := GL_RGBA16;
  2832. end;
  2833. constructor TfdDepth16.Create;
  2834. begin
  2835. inherited Create;
  2836. fFormat := tfDepth16;
  2837. fWithAlpha := tfEmpty;
  2838. fWithoutAlpha := tfDepth16;
  2839. fglInternalFormat := GL_DEPTH_COMPONENT16;
  2840. end;
  2841. constructor TfdDepth24.Create;
  2842. begin
  2843. inherited Create;
  2844. fFormat := tfDepth24;
  2845. fWithAlpha := tfEmpty;
  2846. fWithoutAlpha := tfDepth24;
  2847. fglInternalFormat := GL_DEPTH_COMPONENT24;
  2848. end;
  2849. constructor TfdDepth32.Create;
  2850. begin
  2851. inherited Create;
  2852. fFormat := tfDepth32;
  2853. fWithAlpha := tfEmpty;
  2854. fWithoutAlpha := tfDepth32;
  2855. fglInternalFormat := GL_DEPTH_COMPONENT32;
  2856. end;
  2857. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2858. //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2859. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2860. class procedure TFormatDescriptor.Init;
  2861. begin
  2862. if not Assigned(FormatDescriptorCS) then
  2863. FormatDescriptorCS := TCriticalSection.Create;
  2864. end;
  2865. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2866. class function TFormatDescriptor.Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
  2867. begin
  2868. FormatDescriptorCS.Enter;
  2869. try
  2870. result := FormatDescriptors[aFormat];
  2871. if not Assigned(result) then begin
  2872. result := FORMAT_DESCRIPTOR_CLASSES[aFormat].Create;
  2873. FormatDescriptors[aFormat] := result;
  2874. end;
  2875. finally
  2876. FormatDescriptorCS.Leave;
  2877. end;
  2878. end;
  2879. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2880. class function TFormatDescriptor.GetWithAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
  2881. begin
  2882. result := Get(Get(aFormat).WithAlpha);
  2883. end;
  2884. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2885. class procedure TFormatDescriptor.Clear;
  2886. var
  2887. f: TglBitmapFormat;
  2888. begin
  2889. FormatDescriptorCS.Enter;
  2890. try
  2891. for f := low(FormatDescriptors) to high(FormatDescriptors) do
  2892. FreeAndNil(FormatDescriptors[f]);
  2893. finally
  2894. FormatDescriptorCS.Leave;
  2895. end;
  2896. end;
  2897. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2898. class procedure TFormatDescriptor.Finalize;
  2899. begin
  2900. Clear;
  2901. FreeAndNil(FormatDescriptorCS);
  2902. end;
  2903. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2904. //TBitfieldFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2905. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2906. procedure TBitfieldFormat.SetRedMask(const aValue: UInt64);
  2907. begin
  2908. Update(aValue, fRange.r, fShift.r);
  2909. end;
  2910. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2911. procedure TBitfieldFormat.SetGreenMask(const aValue: UInt64);
  2912. begin
  2913. Update(aValue, fRange.g, fShift.g);
  2914. end;
  2915. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2916. procedure TBitfieldFormat.SetBlueMask(const aValue: UInt64);
  2917. begin
  2918. Update(aValue, fRange.b, fShift.b);
  2919. end;
  2920. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2921. procedure TBitfieldFormat.SetAlphaMask(const aValue: UInt64);
  2922. begin
  2923. Update(aValue, fRange.a, fShift.a);
  2924. end;
  2925. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2926. procedure TBitfieldFormat.Update(aMask: UInt64; out aRange: Cardinal; out
  2927. aShift: Byte);
  2928. begin
  2929. aShift := 0;
  2930. aRange := 0;
  2931. if (aMask = 0) then
  2932. exit;
  2933. while (aMask > 0) and ((aMask and 1) = 0) do begin
  2934. inc(aShift);
  2935. aMask := aMask shr 1;
  2936. end;
  2937. aRange := 1;
  2938. while (aMask > 0) do begin
  2939. aRange := aRange shl 1;
  2940. aMask := aMask shr 1;
  2941. end;
  2942. dec(aRange);
  2943. fPixelSize := Round(GetTopMostBit(RedMask or GreenMask or BlueMask or AlphaMask) / 8);
  2944. end;
  2945. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2946. procedure TBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2947. var
  2948. data: UInt64;
  2949. s: Integer;
  2950. type
  2951. PUInt64 = ^UInt64;
  2952. begin
  2953. data :=
  2954. ((aPixel.Data.r and fRange.r) shl fShift.r) or
  2955. ((aPixel.Data.g and fRange.g) shl fShift.g) or
  2956. ((aPixel.Data.b and fRange.b) shl fShift.b) or
  2957. ((aPixel.Data.a and fRange.a) shl fShift.a);
  2958. s := Round(fPixelSize);
  2959. case s of
  2960. 1: aData^ := data;
  2961. 2: PWord(aData)^ := data;
  2962. 4: PCardinal(aData)^ := data;
  2963. 8: PUInt64(aData)^ := data;
  2964. else
  2965. raise EglBitmapException.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
  2966. end;
  2967. inc(aData, s);
  2968. end;
  2969. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2970. procedure TBitfieldFormat.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2971. var
  2972. data: UInt64;
  2973. s, i: Integer;
  2974. type
  2975. PUInt64 = ^UInt64;
  2976. begin
  2977. s := Round(fPixelSize);
  2978. case s of
  2979. 1: data := aData^;
  2980. 2: data := PWord(aData)^;
  2981. 4: data := PCardinal(aData)^;
  2982. 8: data := PUInt64(aData)^;
  2983. else
  2984. raise EglBitmapException.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
  2985. end;
  2986. for i := 0 to 3 do
  2987. aPixel.Data.arr[i] := (data shr fShift.arr[i]) and fRange.arr[i];
  2988. inc(aData, s);
  2989. end;
  2990. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2991. //TColorTableFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2992. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2993. procedure TColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2994. begin
  2995. raise EglBitmapException.Create('mapping of color table formats is not supported');
  2996. end;
  2997. procedure TColorTableFormat.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2998. type
  2999. PUInt64 = ^UInt64;
  3000. var
  3001. idx: UInt64;
  3002. s: Integer;
  3003. bits: Byte;
  3004. f: Single;
  3005. begin
  3006. s := Trunc(fPixelSize);
  3007. f := fPixelSize - s;
  3008. bits := Round(8 * f);
  3009. case s of
  3010. 0: idx := (aData^ shr (8 - bits - PtrInt(aMapData))) and ((1 shl bits) - 1);
  3011. 1: idx := aData^;
  3012. 2: idx := PWord(aData)^;
  3013. 4: idx := PCardinal(aData)^;
  3014. 8: idx := PUInt64(aData)^;
  3015. else
  3016. raise EglBitmapException.CreateFmt('invalid pixel size: %.3f', [fPixelSize]);
  3017. end;
  3018. if (idx >= Length(fColorTable)) then
  3019. raise EglBitmapException.CreateFmt('invalid color index: %d', [idx]);
  3020. with fColorTable[idx] do begin
  3021. aPixel.Data.r := r;
  3022. aPixel.Data.g := g;
  3023. aPixel.Data.b := b;
  3024. aPixel.Data.a := a;
  3025. end;
  3026. inc(aMapData, bits);
  3027. if (PtrInt(aMapData) >= 8) then begin
  3028. inc(aData, 1);
  3029. dec(aMapData, 8);
  3030. end;
  3031. inc(aData, s);
  3032. end;
  3033. destructor TColorTableFormat.Destroy;
  3034. begin
  3035. SetLength(fColorTable, 0);
  3036. inherited Destroy;
  3037. end;
  3038. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3039. //TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3040. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3041. procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
  3042. begin
  3043. with aFuncRec do begin
  3044. if (Source.Range.r > 0) then
  3045. Dest.Data.r := Source.Data.r;
  3046. if (Source.Range.g > 0) then
  3047. Dest.Data.g := Source.Data.g;
  3048. if (Source.Range.b > 0) then
  3049. Dest.Data.b := Source.Data.b;
  3050. if (Source.Range.a > 0) then
  3051. Dest.Data.a := Source.Data.a;
  3052. end;
  3053. end;
  3054. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3055. procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
  3056. var
  3057. i: Integer;
  3058. begin
  3059. with aFuncRec do begin
  3060. for i := 0 to 3 do
  3061. if (Source.Range.arr[i] > 0) then
  3062. Dest.Data.arr[i] := Round(Dest.Range.arr[i] * Source.Data.arr[i] / Source.Range.arr[i]);
  3063. end;
  3064. end;
  3065. type
  3066. TShiftData = packed record
  3067. case Integer of
  3068. 0: (r, g, b, a: SmallInt);
  3069. 1: (arr: array[0..3] of SmallInt);
  3070. end;
  3071. PShiftData = ^TShiftData;
  3072. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3073. procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
  3074. var
  3075. i: Integer;
  3076. begin
  3077. with aFuncRec do
  3078. for i := 0 to 3 do
  3079. if (Source.Range.arr[i] > 0) then
  3080. Dest.Data.arr[i] := Source.Data.arr[i] shr PShiftData(Args)^.arr[i];
  3081. end;
  3082. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3083. procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
  3084. begin
  3085. with aFuncRec do begin
  3086. Dest.Data.r := Source.Data.r;
  3087. Dest.Data.g := Source.Data.g;
  3088. Dest.Data.b := Source.Data.b;
  3089. Dest.Data.a := Source.Data.a;
  3090. if (Args and $1 > 0) then begin
  3091. Dest.Data.r := Dest.Data.r xor Dest.Range.r;
  3092. Dest.Data.g := Dest.Data.g xor Dest.Range.g;
  3093. Dest.Data.b := Dest.Data.b xor Dest.Range.b;
  3094. end;
  3095. if (Args and $2 > 0) then begin
  3096. Dest.Data.a := Dest.Data.a xor Dest.Range.a;
  3097. end;
  3098. end;
  3099. end;
  3100. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3101. procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
  3102. var
  3103. i: Integer;
  3104. begin
  3105. with aFuncRec do begin
  3106. for i := 0 to 3 do
  3107. Dest.Data.arr[i] := PglBitmapPixelData(Args)^.Data.arr[i];
  3108. end;
  3109. end;
  3110. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3111. procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
  3112. var
  3113. Temp: Single;
  3114. begin
  3115. with FuncRec do begin
  3116. if (FuncRec.Args = 0) then begin //source has no alpha
  3117. Temp :=
  3118. Source.Data.r / Source.Range.r * ALPHA_WEIGHT_R +
  3119. Source.Data.g / Source.Range.g * ALPHA_WEIGHT_G +
  3120. Source.Data.b / Source.Range.b * ALPHA_WEIGHT_B;
  3121. Dest.Data.a := Round(Dest.Range.a * Temp);
  3122. end else
  3123. Dest.Data.a := Round(Source.Data.a / Source.Range.a * Dest.Range.a);
  3124. end;
  3125. end;
  3126. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3127. procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
  3128. type
  3129. PglBitmapPixelData = ^TglBitmapPixelData;
  3130. begin
  3131. with FuncRec do begin
  3132. Dest.Data.r := Source.Data.r;
  3133. Dest.Data.g := Source.Data.g;
  3134. Dest.Data.b := Source.Data.b;
  3135. with PglBitmapPixelData(Args)^ do
  3136. if ((Dest.Data.r <= Data.r) and (Dest.Data.r >= Range.r) and
  3137. (Dest.Data.g <= Data.g) and (Dest.Data.g >= Range.g) and
  3138. (Dest.Data.b <= Data.b) and (Dest.Data.b >= Range.b)) then
  3139. Dest.Data.a := 0
  3140. else
  3141. Dest.Data.a := Dest.Range.a;
  3142. end;
  3143. end;
  3144. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3145. procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
  3146. type
  3147. PglBitmapPixelData = ^TglBitmapPixelData;
  3148. begin
  3149. with FuncRec do begin
  3150. Dest.Data.r := Source.Data.r;
  3151. Dest.Data.g := Source.Data.g;
  3152. Dest.Data.b := Source.Data.b;
  3153. Dest.Data.a := PCardinal(Args)^;
  3154. end;
  3155. end;
  3156. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3157. procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
  3158. type
  3159. PRGBPix = ^TRGBPix;
  3160. TRGBPix = array [0..2] of byte;
  3161. var
  3162. Temp: Byte;
  3163. begin
  3164. while aWidth > 0 do begin
  3165. Temp := PRGBPix(aData)^[0];
  3166. PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
  3167. PRGBPix(aData)^[2] := Temp;
  3168. if aHasAlpha then
  3169. Inc(aData, 4)
  3170. else
  3171. Inc(aData, 3);
  3172. dec(aWidth);
  3173. end;
  3174. end;
  3175. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3176. //TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3177. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3178. function TglBitmap.GetWidth: Integer;
  3179. begin
  3180. if (ffX in fDimension.Fields) then
  3181. result := fDimension.X
  3182. else
  3183. result := -1;
  3184. end;
  3185. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3186. function TglBitmap.GetHeight: Integer;
  3187. begin
  3188. if (ffY in fDimension.Fields) then
  3189. result := fDimension.Y
  3190. else
  3191. result := -1;
  3192. end;
  3193. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3194. function TglBitmap.GetFileWidth: Integer;
  3195. begin
  3196. result := Max(1, Width);
  3197. end;
  3198. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3199. function TglBitmap.GetFileHeight: Integer;
  3200. begin
  3201. result := Max(1, Height);
  3202. end;
  3203. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3204. procedure TglBitmap.SetCustomData(const aValue: Pointer);
  3205. begin
  3206. if fCustomData = aValue then
  3207. exit;
  3208. fCustomData := aValue;
  3209. end;
  3210. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3211. procedure TglBitmap.SetCustomName(const aValue: String);
  3212. begin
  3213. if fCustomName = aValue then
  3214. exit;
  3215. fCustomName := aValue;
  3216. end;
  3217. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3218. procedure TglBitmap.SetCustomNameW(const aValue: WideString);
  3219. begin
  3220. if fCustomNameW = aValue then
  3221. exit;
  3222. fCustomNameW := aValue;
  3223. end;
  3224. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3225. procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
  3226. begin
  3227. if fDeleteTextureOnFree = aValue then
  3228. exit;
  3229. fDeleteTextureOnFree := aValue;
  3230. end;
  3231. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3232. procedure TglBitmap.SetFormat(const aValue: TglBitmapFormat);
  3233. begin
  3234. if fFormat = aValue then
  3235. exit;
  3236. if TFormatDescriptor.Get(Format).PixelSize <> TFormatDescriptor.Get(aValue).PixelSize then
  3237. raise EglBitmapUnsupportedFormatFormat.Create('SetInternalFormat - ' + UNSUPPORTED_FORMAT);
  3238. SetDataPointer(Data, aValue, Width, Height);
  3239. end;
  3240. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3241. procedure TglBitmap.SetFreeDataAfterGenTexture(const aValue: Boolean);
  3242. begin
  3243. if fFreeDataAfterGenTexture = aValue then
  3244. exit;
  3245. fFreeDataAfterGenTexture := aValue;
  3246. end;
  3247. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3248. procedure TglBitmap.SetID(const aValue: Cardinal);
  3249. begin
  3250. if fID = aValue then
  3251. exit;
  3252. fID := aValue;
  3253. end;
  3254. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3255. procedure TglBitmap.SetMipMap(const aValue: TglBitmapMipMap);
  3256. begin
  3257. if fMipMap = aValue then
  3258. exit;
  3259. fMipMap := aValue;
  3260. end;
  3261. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3262. procedure TglBitmap.SetTarget(const aValue: Cardinal);
  3263. begin
  3264. if fTarget = aValue then
  3265. exit;
  3266. fTarget := aValue;
  3267. end;
  3268. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3269. procedure TglBitmap.SetAnisotropic(const aValue: Integer);
  3270. var
  3271. MaxAnisotropic: Integer;
  3272. begin
  3273. fAnisotropic := aValue;
  3274. if (ID > 0) then begin
  3275. if GL_EXT_texture_filter_anisotropic then begin
  3276. if fAnisotropic > 0 then begin
  3277. Bind(false);
  3278. glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
  3279. if aValue > MaxAnisotropic then
  3280. fAnisotropic := MaxAnisotropic;
  3281. glTexParameteri(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, fAnisotropic);
  3282. end;
  3283. end else begin
  3284. fAnisotropic := 0;
  3285. end;
  3286. end;
  3287. end;
  3288. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3289. procedure TglBitmap.CreateID;
  3290. begin
  3291. if (ID <> 0) then
  3292. glDeleteTextures(1, @fID);
  3293. glGenTextures(1, @fID);
  3294. Bind(false);
  3295. end;
  3296. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3297. procedure TglBitmap.SetupParameters(var aBuildWithGlu: Boolean);
  3298. begin
  3299. // Set Up Parameters
  3300. SetWrap(fWrapS, fWrapT, fWrapR);
  3301. SetFilter(fFilterMin, fFilterMag);
  3302. SetAnisotropic(fAnisotropic);
  3303. SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
  3304. // Mip Maps Generation Mode
  3305. aBuildWithGlu := false;
  3306. if (MipMap = mmMipmap) then begin
  3307. if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
  3308. glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
  3309. else
  3310. aBuildWithGlu := true;
  3311. end else if (MipMap = mmMipmapGlu) then
  3312. aBuildWithGlu := true;
  3313. end;
  3314. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3315. procedure TglBitmap.SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
  3316. const aWidth: Integer; const aHeight: Integer);
  3317. var
  3318. s: Single;
  3319. begin
  3320. if (Data <> aData) then begin
  3321. if (Assigned(Data)) then
  3322. FreeMem(Data);
  3323. fData := aData;
  3324. end;
  3325. FillChar(fDimension, SizeOf(fDimension), 0);
  3326. if not Assigned(fData) then begin
  3327. fFormat := tfEmpty;
  3328. fPixelSize := 0;
  3329. fRowSize := 0;
  3330. end else begin
  3331. if aWidth <> -1 then begin
  3332. fDimension.Fields := fDimension.Fields + [ffX];
  3333. fDimension.X := aWidth;
  3334. end;
  3335. if aHeight <> -1 then begin
  3336. fDimension.Fields := fDimension.Fields + [ffY];
  3337. fDimension.Y := aHeight;
  3338. end;
  3339. s := TFormatDescriptor.Get(aFormat).PixelSize;
  3340. fFormat := aFormat;
  3341. fPixelSize := Ceil(s);
  3342. fRowSize := Ceil(s * aWidth);
  3343. end;
  3344. end;
  3345. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3346. function TglBitmap.FlipHorz: Boolean;
  3347. begin
  3348. result := false;
  3349. end;
  3350. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3351. function TglBitmap.FlipVert: Boolean;
  3352. begin
  3353. result := false;
  3354. end;
  3355. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3356. //TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3357. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3358. procedure TglBitmap.AfterConstruction;
  3359. begin
  3360. inherited AfterConstruction;
  3361. fID := 0;
  3362. fTarget := 0;
  3363. fIsResident := false;
  3364. fFormat := glBitmapGetDefaultFormat;
  3365. fMipMap := glBitmapDefaultMipmap;
  3366. fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
  3367. fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
  3368. glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
  3369. glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
  3370. end;
  3371. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3372. procedure TglBitmap.BeforeDestruction;
  3373. begin
  3374. SetDataPointer(nil, tfEmpty);
  3375. if (fID > 0) and fDeleteTextureOnFree then
  3376. glDeleteTextures(1, @fID);
  3377. inherited BeforeDestruction;
  3378. end;
  3379. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3380. procedure TglBitmap.LoadFromFile(const aFilename: String);
  3381. var
  3382. fs: TFileStream;
  3383. begin
  3384. fFilename := aFilename;
  3385. fs := TFileStream.Create(fFilename, fmOpenRead);
  3386. try
  3387. fs.Position := 0;
  3388. LoadFromStream(fs);
  3389. finally
  3390. fs.Free;
  3391. end;
  3392. end;
  3393. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3394. procedure TglBitmap.LoadFromStream(const aStream: TStream);
  3395. begin
  3396. {$IFDEF GLB_SUPPORT_PNG_READ}
  3397. if not LoadPNG(aStream) then
  3398. {$ENDIF}
  3399. {$IFDEF GLB_SUPPORT_JPEG_READ}
  3400. if not LoadJPEG(aStream) then
  3401. {$ENDIF}
  3402. if not LoadDDS(aStream) then
  3403. if not LoadTGA(aStream) then
  3404. if not LoadBMP(aStream) then
  3405. raise EglBitmapException.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
  3406. end;
  3407. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3408. procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
  3409. const aFormat: TglBitmapFormat; const aArgs: PtrInt);
  3410. var
  3411. tmpData: PByte;
  3412. size: Integer;
  3413. begin
  3414. size := TFormatDescriptor.Get(aFormat).GetSize(aSize);
  3415. GetMem(tmpData, size);
  3416. try
  3417. FillChar(tmpData^, size, #$FF);
  3418. SetDataPointer(tmpData, aFormat, aSize.X, aSize.Y);
  3419. except
  3420. FreeMem(tmpData);
  3421. raise;
  3422. end;
  3423. AddFunc(Self, aFunc, false, Format, aArgs);
  3424. end;
  3425. {$IFDEF GLB_DELPHI}
  3426. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3427. procedure TglBitmap.LoadFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil);
  3428. var
  3429. rs: TResourceStream;
  3430. TempPos: Integer;
  3431. ResTypeStr: String;
  3432. TempResType: PChar;
  3433. begin
  3434. if not Assigned(ResType) then begin
  3435. TempPos := Pos('.', Resource);
  3436. ResTypeStr := UpperCase(Copy(Resource, TempPos + 1, Length(Resource) - TempPos));
  3437. Resource := UpperCase(Copy(Resource, 0, TempPos -1));
  3438. TempResType := PChar(ResTypeStr);
  3439. end else
  3440. TempResType := ResType
  3441. rs := TResourceStream.Create(Instance, Resource, TempResType);
  3442. try
  3443. LoadFromStream(rs);
  3444. finally
  3445. rs.Free;
  3446. end;
  3447. end;
  3448. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3449. procedure TglBitmap.LoadFromResourceID(const sInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
  3450. var
  3451. rs: TResourceStream;
  3452. begin
  3453. rs := TResourceStream.CreateFromID(Instance, ResourceID, ResType);
  3454. try
  3455. LoadFromStream(rs);
  3456. finally
  3457. rs.Free;
  3458. end;
  3459. end;
  3460. {$ENDIF}
  3461. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3462. procedure TglBitmap.SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
  3463. var
  3464. fs: TFileStream;
  3465. begin
  3466. fs := TFileStream.Create(aFileName, fmCreate);
  3467. try
  3468. fs.Position := 0;
  3469. SaveToStream(fs, aFileType);
  3470. finally
  3471. fs.Free;
  3472. end;
  3473. end;
  3474. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3475. procedure TglBitmap.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
  3476. begin
  3477. case aFileType of
  3478. {$IFDEF GLB_SUPPORT_PNG_WRITE}
  3479. ftPNG: SavePng(aStream);
  3480. {$ENDIF}
  3481. {$IFDEF GLB_SUPPORT_JPEG_WRITE}
  3482. ftJPEG: SaveJPEG(aStream);
  3483. {$ENDIF}
  3484. ftDDS: SaveDDS(aStream);
  3485. ftTGA: SaveTGA(aStream);
  3486. ftBMP: SaveBMP(aStream);
  3487. end;
  3488. end;
  3489. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3490. function TglBitmap.AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: PtrInt): Boolean;
  3491. begin
  3492. result := AddFunc(Self, aFunc, aCreateTemp, Format, aArgs);
  3493. end;
  3494. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3495. function TglBitmap.AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
  3496. const aFormat: TglBitmapFormat; const aArgs: PtrInt): Boolean;
  3497. var
  3498. DestData, TmpData, SourceData: pByte;
  3499. TempHeight, TempWidth: Integer;
  3500. SourceFD, DestFD: TFormatDescriptor;
  3501. SourceMD, DestMD: Pointer;
  3502. FuncRec: TglBitmapFunctionRec;
  3503. begin
  3504. Assert(Assigned(Data));
  3505. Assert(Assigned(aSource));
  3506. Assert(Assigned(aSource.Data));
  3507. result := false;
  3508. if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
  3509. SourceFD := TFormatDescriptor.Get(aSource.Format);
  3510. DestFD := TFormatDescriptor.Get(aFormat);
  3511. // inkompatible Formats so CreateTemp
  3512. if (SourceFD.PixelSize <> DestFD.PixelSize) then
  3513. aCreateTemp := true;
  3514. // Values
  3515. TempHeight := Max(1, aSource.Height);
  3516. TempWidth := Max(1, aSource.Width);
  3517. FuncRec.Sender := Self;
  3518. FuncRec.Args := aArgs;
  3519. TmpData := nil;
  3520. if aCreateTemp then begin
  3521. GetMem(TmpData, TFormatDescriptor.Get(aFormat).GetSize(TempWidth, TempHeight));
  3522. DestData := TmpData;
  3523. end else
  3524. DestData := Data;
  3525. try
  3526. SourceFD.PreparePixel(FuncRec.Source);
  3527. DestFD.PreparePixel (FuncRec.Dest);
  3528. SourceMD := SourceFD.CreateMappingData;
  3529. DestMD := DestFD.CreateMappingData;
  3530. FuncRec.Size := aSource.Dimension;
  3531. FuncRec.Position.Fields := FuncRec.Size.Fields;
  3532. try
  3533. SourceData := aSource.Data;
  3534. FuncRec.Position.Y := 0;
  3535. while FuncRec.Position.Y < TempHeight do begin
  3536. FuncRec.Position.X := 0;
  3537. while FuncRec.Position.X < TempWidth do begin
  3538. SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
  3539. aFunc(FuncRec);
  3540. DestFD.Map(FuncRec.Dest, DestData, DestMD);
  3541. inc(FuncRec.Position.X);
  3542. end;
  3543. inc(FuncRec.Position.Y);
  3544. end;
  3545. // Updating Image or InternalFormat
  3546. if aCreateTemp then
  3547. SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height)
  3548. else if (aFormat <> fFormat) then
  3549. Format := aFormat;
  3550. result := true;
  3551. finally
  3552. SourceFD.FreeMappingData(SourceMD);
  3553. DestFD.FreeMappingData(DestMD);
  3554. end;
  3555. except
  3556. if aCreateTemp then
  3557. FreeMem(TmpData);
  3558. raise;
  3559. end;
  3560. end;
  3561. end;
  3562. {$IFDEF GLB_SDL}
  3563. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3564. function TglBitmap.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
  3565. var
  3566. Row, RowSize: Integer;
  3567. SourceData, TmpData: PByte;
  3568. TempDepth: Integer;
  3569. Pix: TglBitmapPixelData;
  3570. FormatDesc: TglBitmapFormatDescriptor;
  3571. function GetRowPointer(Row: Integer): pByte;
  3572. begin
  3573. result := Surface.pixels;
  3574. Inc(result, Row * RowSize);
  3575. end;
  3576. begin
  3577. result := false;
  3578. (* TODO
  3579. if not FormatIsUncompressed(InternalFormat) then
  3580. raise EglBitmapUnsupportedInternalFormat.Create('AssignToSurface - ' + UNSUPPORTED_INTERNAL_FORMAT);
  3581. *)
  3582. FormatDesc := FORMAT_DESCRIPTORS[Format];
  3583. if Assigned(Data) then begin
  3584. case Trunc(FormatDesc.GetSize) of
  3585. 1: TempDepth := 8;
  3586. 2: TempDepth := 16;
  3587. 3: TempDepth := 24;
  3588. 4: TempDepth := 32;
  3589. else
  3590. raise EglBitmapException.Create('AssignToSurface - ' + UNSUPPORTED_INTERNAL_FORMAT);
  3591. end;
  3592. FormatDesc.PreparePixel(Pix);
  3593. with Pix.PixelDesc do
  3594. Surface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
  3595. RedRange shl RedShift, GreenRange shl GreenShift, BlueRange shl BlueShift, AlphaRange shl AlphaShift);
  3596. SourceData := Data;
  3597. RowSize := Ceil(FileWidth * FormatDesc.GetSize);
  3598. for Row := 0 to FileHeight -1 do begin
  3599. TmpData := GetRowPointer(Row);
  3600. if Assigned(TmpData) then begin
  3601. Move(SourceData^, TmpData^, RowSize);
  3602. inc(SourceData, RowSize);
  3603. end;
  3604. end;
  3605. result := true;
  3606. end;
  3607. end;
  3608. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3609. function TglBitmap.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
  3610. var
  3611. pSource, pData, pTempData: PByte;
  3612. Row, RowSize, TempWidth, TempHeight: Integer;
  3613. IntFormat, f: TglBitmapInternalFormat;
  3614. FormatDesc: TglBitmapFormatDescriptor;
  3615. function GetRowPointer(Row: Integer): pByte;
  3616. begin
  3617. result := Surface^.pixels;
  3618. Inc(result, Row * RowSize);
  3619. end;
  3620. begin
  3621. result := false;
  3622. if (Assigned(Surface)) then begin
  3623. with Surface^.format^ do begin
  3624. IntFormat := tfEmpty;
  3625. for f := Low(f) to High(f) do begin
  3626. if FORMAT_DESCRIPTORS[f].MaskMatch(RMask, GMask, BMask, AMask) then begin
  3627. IntFormat := f;
  3628. break;
  3629. end;
  3630. end;
  3631. if (IntFormat = tfEmpty) then
  3632. raise EglBitmapException.Create('AssignFromSurface - Invalid Pixelformat.');
  3633. end;
  3634. FormatDesc := FORMAT_DESCRIPTORS[IntFormat];
  3635. TempWidth := Surface^.w;
  3636. TempHeight := Surface^.h;
  3637. RowSize := Trunc(TempWidth * FormatDesc.GetSize);
  3638. GetMem(pData, TempHeight * RowSize);
  3639. try
  3640. pTempData := pData;
  3641. for Row := 0 to TempHeight -1 do begin
  3642. pSource := GetRowPointer(Row);
  3643. if (Assigned(pSource)) then begin
  3644. Move(pSource^, pTempData^, RowSize);
  3645. Inc(pTempData, RowSize);
  3646. end;
  3647. end;
  3648. SetDataPointer(pData, IntFormat, TempWidth, TempHeight);
  3649. result := true;
  3650. except
  3651. FreeMem(pData);
  3652. raise;
  3653. end;
  3654. end;
  3655. end;
  3656. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3657. function TglBitmap.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
  3658. var
  3659. Row, Col, AlphaInterleave: Integer;
  3660. pSource, pDest: PByte;
  3661. function GetRowPointer(Row: Integer): pByte;
  3662. begin
  3663. result := aSurface.pixels;
  3664. Inc(result, Row * Width);
  3665. end;
  3666. begin
  3667. result := false;
  3668. if Assigned(Data) then begin
  3669. if Format in [tfAlpha8, tfLuminance8Alpha8, tfBGRA8, tfRGBA8] then begin
  3670. aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
  3671. AlphaInterleave := 0;
  3672. case Format of
  3673. ifLuminance8Alpha8:
  3674. AlphaInterleave := 1;
  3675. ifBGRA8, ifRGBA8:
  3676. AlphaInterleave := 3;
  3677. end;
  3678. pSource := Data;
  3679. for Row := 0 to Height -1 do begin
  3680. pDest := GetRowPointer(Row);
  3681. if Assigned(pDest) then begin
  3682. for Col := 0 to Width -1 do begin
  3683. Inc(pSource, AlphaInterleave);
  3684. pDest^ := pSource^;
  3685. Inc(pDest);
  3686. Inc(pSource);
  3687. end;
  3688. end;
  3689. end;
  3690. result := true;
  3691. end;
  3692. end;
  3693. end;
  3694. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3695. function TglBitmap.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
  3696. var
  3697. bmp: TglBitmap2D;
  3698. begin
  3699. bmp := TglBitmap2D.Create;
  3700. try
  3701. bmp.AssignFromSurface(Surface);
  3702. result := AddAlphaFromGlBitmap(bmp, Func, CustomData);
  3703. finally
  3704. bmp.Free;
  3705. end;
  3706. end;
  3707. {$ENDIF}
  3708. {$IFDEF GLB_DELPHI}
  3709. //TODO rework & test
  3710. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3711. function TglBitmap.AssignToBitmap(const aBitmap: TBitmap): Boolean;
  3712. var
  3713. Row: Integer;
  3714. pSource, pData: PByte;
  3715. begin
  3716. result := false;
  3717. if Assigned(Data) then begin
  3718. if Assigned(aBitmap) then begin
  3719. aBitmap.Width := Width;
  3720. aBitmap.Height := Height;
  3721. case Format of
  3722. tfAlpha8, ifLuminance, ifDepth8:
  3723. begin
  3724. Bitmap.PixelFormat := pf8bit;
  3725. Bitmap.Palette := CreateGrayPalette;
  3726. end;
  3727. ifRGB5A1:
  3728. Bitmap.PixelFormat := pf15bit;
  3729. ifR5G6B5:
  3730. Bitmap.PixelFormat := pf16bit;
  3731. ifRGB8, ifBGR8:
  3732. Bitmap.PixelFormat := pf24bit;
  3733. ifRGBA8, ifBGRA8:
  3734. Bitmap.PixelFormat := pf32bit;
  3735. else
  3736. raise EglBitmapException.Create('AssignToBitmap - Invalid Pixelformat.');
  3737. end;
  3738. pSource := Data;
  3739. for Row := 0 to FileHeight -1 do begin
  3740. pData := Bitmap.Scanline[Row];
  3741. Move(pSource^, pData^, fRowSize);
  3742. Inc(pSource, fRowSize);
  3743. // swap RGB(A) to BGR(A)
  3744. if InternalFormat in [ifRGB8, ifRGBA8] then
  3745. SwapRGB(pData, FileWidth, InternalFormat = ifRGBA8);
  3746. end;
  3747. result := true;
  3748. end;
  3749. end;
  3750. end;
  3751. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3752. function TglBitmap.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
  3753. var
  3754. pSource, pData, pTempData: PByte;
  3755. Row, RowSize, TempWidth, TempHeight: Integer;
  3756. IntFormat: TglBitmapInternalFormat;
  3757. begin
  3758. result := false;
  3759. if (Assigned(Bitmap)) then begin
  3760. case Bitmap.PixelFormat of
  3761. pf8bit:
  3762. IntFormat := ifLuminance;
  3763. pf15bit:
  3764. IntFormat := ifRGB5A1;
  3765. pf16bit:
  3766. IntFormat := ifR5G6B5;
  3767. pf24bit:
  3768. IntFormat := ifBGR8;
  3769. pf32bit:
  3770. IntFormat := ifBGRA8;
  3771. else
  3772. raise EglBitmapException.Create('AssignFromBitmap - Invalid Pixelformat.');
  3773. end;
  3774. TempWidth := Bitmap.Width;
  3775. TempHeight := Bitmap.Height;
  3776. RowSize := Trunc(TempWidth * FormatGetSize(IntFormat));
  3777. GetMem(pData, TempHeight * RowSize);
  3778. try
  3779. pTempData := pData;
  3780. for Row := 0 to TempHeight -1 do begin
  3781. pSource := Bitmap.Scanline[Row];
  3782. if (Assigned(pSource)) then begin
  3783. Move(pSource^, pTempData^, RowSize);
  3784. Inc(pTempData, RowSize);
  3785. end;
  3786. end;
  3787. SetDataPointer(pData, IntFormat, TempWidth, TempHeight);
  3788. result := true;
  3789. except
  3790. FreeMem(pData);
  3791. raise;
  3792. end;
  3793. end;
  3794. end;
  3795. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3796. function TglBitmap.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
  3797. var
  3798. Row, Col, AlphaInterleave: Integer;
  3799. pSource, pDest: PByte;
  3800. begin
  3801. result := false;
  3802. if Assigned(Data) then begin
  3803. if InternalFormat in [ifAlpha, ifLuminanceAlpha, ifRGBA8, ifBGRA8] then begin
  3804. if Assigned(Bitmap) then begin
  3805. Bitmap.PixelFormat := pf8bit;
  3806. Bitmap.Palette := CreateGrayPalette;
  3807. Bitmap.Width := Width;
  3808. Bitmap.Height := Height;
  3809. case InternalFormat of
  3810. ifLuminanceAlpha:
  3811. AlphaInterleave := 1;
  3812. ifRGBA8, ifBGRA8:
  3813. AlphaInterleave := 3;
  3814. else
  3815. AlphaInterleave := 0;
  3816. end;
  3817. // Copy Data
  3818. pSource := Data;
  3819. for Row := 0 to Height -1 do begin
  3820. pDest := Bitmap.Scanline[Row];
  3821. if Assigned(pDest) then begin
  3822. for Col := 0 to Width -1 do begin
  3823. Inc(pSource, AlphaInterleave);
  3824. pDest^ := pSource^;
  3825. Inc(pDest);
  3826. Inc(pSource);
  3827. end;
  3828. end;
  3829. end;
  3830. result := true;
  3831. end;
  3832. end;
  3833. end;
  3834. end;
  3835. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3836. function TglBitmap.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
  3837. var
  3838. tex: TglBitmap2D;
  3839. begin
  3840. tex := TglBitmap2D.Create;
  3841. try
  3842. tex.AssignFromBitmap(Bitmap);
  3843. result := AddAlphaFromglBitmap(tex, Func, CustomData);
  3844. finally
  3845. tex.Free;
  3846. end;
  3847. end;
  3848. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3849. function TglBitmap.AddAlphaFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar;
  3850. const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
  3851. var
  3852. RS: TResourceStream;
  3853. TempPos: Integer;
  3854. ResTypeStr: String;
  3855. TempResType: PChar;
  3856. begin
  3857. if Assigned(ResType) then
  3858. TempResType := ResType
  3859. else
  3860. begin
  3861. TempPos := Pos('.', Resource);
  3862. ResTypeStr := UpperCase(Copy(Resource, TempPos + 1, Length(Resource) - TempPos));
  3863. Resource := UpperCase(Copy(Resource, 0, TempPos -1));
  3864. TempResType := PChar(ResTypeStr);
  3865. end;
  3866. RS := TResourceStream.Create(Instance, Resource, TempResType);
  3867. try
  3868. result := AddAlphaFromStream(RS, Func, CustomData);
  3869. finally
  3870. RS.Free;
  3871. end;
  3872. end;
  3873. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3874. function TglBitmap.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
  3875. const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
  3876. var
  3877. RS: TResourceStream;
  3878. begin
  3879. RS := TResourceStream.CreateFromID(Instance, ResourceID, ResType);
  3880. try
  3881. result := AddAlphaFromStream(RS, Func, CustomData);
  3882. finally
  3883. RS.Free;
  3884. end;
  3885. end;
  3886. {$ENDIF}
  3887. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3888. function TglBitmap.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
  3889. begin
  3890. (* TODO
  3891. if not FormatIsUncompressed(InternalFormat) then
  3892. raise EglBitmapUnsupportedFormatFormat.Create('AddAlphaFromFunc - ' + UNSUPPORTED_FORMAT);
  3893. *)
  3894. result := AddFunc(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs);
  3895. end;
  3896. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3897. function TglBitmap.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
  3898. var
  3899. FS: TFileStream;
  3900. begin
  3901. FS := TFileStream.Create(FileName, fmOpenRead);
  3902. try
  3903. result := AddAlphaFromStream(FS, aFunc, aArgs);
  3904. finally
  3905. FS.Free;
  3906. end;
  3907. end;
  3908. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3909. function TglBitmap.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
  3910. var
  3911. tex: TglBitmap2D;
  3912. begin
  3913. tex := TglBitmap2D.Create(aStream);
  3914. try
  3915. result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
  3916. finally
  3917. tex.Free;
  3918. end;
  3919. end;
  3920. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3921. function TglBitmap.AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
  3922. var
  3923. DestData, DestData2, SourceData: pByte;
  3924. TempHeight, TempWidth: Integer;
  3925. SourceFD, DestFD: TFormatDescriptor;
  3926. SourceMD, DestMD, DestMD2: Pointer;
  3927. FuncRec: TglBitmapFunctionRec;
  3928. begin
  3929. result := false;
  3930. Assert(Assigned(Data));
  3931. Assert(Assigned(aBitmap));
  3932. Assert(Assigned(aBitmap.Data));
  3933. if ((aBitmap.Width = Width) and (aBitmap.Height = Height)) then begin
  3934. result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
  3935. if not Assigned(aFunc) then
  3936. aFunc := glBitmapAlphaFunc;
  3937. SourceFD := TFormatDescriptor.Get(aBitmap.Format);
  3938. DestFD := TFormatDescriptor.Get(Format);
  3939. // Values
  3940. TempHeight := aBitmap.FileHeight;
  3941. TempWidth := aBitmap.FileWidth;
  3942. FuncRec.Sender := Self;
  3943. FuncRec.Args := aArgs;
  3944. FuncRec.Size := Dimension;
  3945. FuncRec.Position.Fields := FuncRec.Size.Fields;
  3946. FuncRec.Args := PtrInt(SourceFD.HasAlpha) and 1;
  3947. DestData := Data;
  3948. DestData2 := Data;
  3949. SourceData := aBitmap.Data;
  3950. // Mapping
  3951. SourceFD.PreparePixel(FuncRec.Source);
  3952. DestFD.PreparePixel (FuncRec.Dest);
  3953. SourceMD := SourceFD.CreateMappingData;
  3954. DestMD := DestFD.CreateMappingData;
  3955. DestMD2 := DestFD.CreateMappingData;
  3956. try
  3957. FuncRec.Position.Y := 0;
  3958. while FuncRec.Position.Y < TempHeight do begin
  3959. FuncRec.Position.X := 0;
  3960. while FuncRec.Position.X < TempWidth do begin
  3961. SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
  3962. DestFD.Unmap (DestData, FuncRec.Dest, DestMD);
  3963. aFunc(FuncRec);
  3964. DestFD.Map(FuncRec.Dest, DestData2, DestMD2);
  3965. inc(FuncRec.Position.X);
  3966. end;
  3967. inc(FuncRec.Position.Y);
  3968. end;
  3969. finally
  3970. SourceFD.FreeMappingData(SourceMD);
  3971. DestFD.FreeMappingData(DestMD);
  3972. DestFD.FreeMappingData(DestMD2);
  3973. end;
  3974. end;
  3975. end;
  3976. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3977. function TglBitmap.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
  3978. begin
  3979. result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
  3980. end;
  3981. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3982. function TglBitmap.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
  3983. var
  3984. PixelData: TglBitmapPixelData;
  3985. begin
  3986. TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
  3987. result := AddAlphaFromColorKeyFloat(
  3988. aRed / PixelData.Range.r,
  3989. aGreen / PixelData.Range.g,
  3990. aBlue / PixelData.Range.b,
  3991. aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b)));
  3992. end;
  3993. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3994. function TglBitmap.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
  3995. var
  3996. values: array[0..2] of Single;
  3997. tmp: Cardinal;
  3998. i: Integer;
  3999. PixelData: TglBitmapPixelData;
  4000. begin
  4001. TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
  4002. with PixelData do begin
  4003. values[0] := aRed;
  4004. values[1] := aGreen;
  4005. values[2] := aBlue;
  4006. for i := 0 to 2 do begin
  4007. tmp := Trunc(Range.arr[i] * aDeviation);
  4008. Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp));
  4009. Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp));
  4010. end;
  4011. Data.a := 0;
  4012. Range.a := 0;
  4013. end;
  4014. result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, PtrInt(@PixelData));
  4015. end;
  4016. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4017. function TglBitmap.AddAlphaFromValue(const aAlpha: Byte): Boolean;
  4018. begin
  4019. result := AddAlphaFromValueFloat(aAlpha / $FF);
  4020. end;
  4021. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4022. function TglBitmap.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
  4023. var
  4024. PixelData: TglBitmapPixelData;
  4025. begin
  4026. TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
  4027. result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
  4028. end;
  4029. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4030. function TglBitmap.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
  4031. var
  4032. PixelData: TglBitmapPixelData;
  4033. begin
  4034. TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
  4035. with PixelData do
  4036. Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
  4037. result := AddAlphaFromFunc(glBitmapValueAlphaFunc, PtrInt(@PixelData.Data.a));
  4038. end;
  4039. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4040. function TglBitmap.RemoveAlpha: Boolean;
  4041. var
  4042. FormatDesc: TFormatDescriptor;
  4043. begin
  4044. result := false;
  4045. FormatDesc := TFormatDescriptor.Get(Format);
  4046. if Assigned(Data) then begin
  4047. if not ({FormatDesc.IsUncompressed or }FormatDesc.HasAlpha) then
  4048. raise EglBitmapUnsupportedFormatFormat.Create('RemoveAlpha - ' + UNSUPPORTED_FORMAT);
  4049. result := ConvertTo(FormatDesc.WithoutAlpha);
  4050. end;
  4051. end;
  4052. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4053. function TglBitmap.Clone: TglBitmap;
  4054. var
  4055. Temp: TglBitmap;
  4056. TempPtr: PByte;
  4057. Size: Integer;
  4058. begin
  4059. result := nil;
  4060. Temp := (ClassType.Create as TglBitmap);
  4061. try
  4062. // copy texture data if assigned
  4063. if Assigned(Data) then begin
  4064. Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
  4065. GetMem(TempPtr, Size);
  4066. try
  4067. Move(Data^, TempPtr^, Size);
  4068. Temp.SetDataPointer(TempPtr, Format, Width, Height);
  4069. except
  4070. FreeMem(TempPtr);
  4071. raise;
  4072. end;
  4073. end else
  4074. Temp.SetDataPointer(nil, Format, Width, Height);
  4075. // copy properties
  4076. Temp.fID := ID;
  4077. Temp.fTarget := Target;
  4078. Temp.fFormat := Format;
  4079. Temp.fMipMap := MipMap;
  4080. Temp.fAnisotropic := Anisotropic;
  4081. Temp.fBorderColor := fBorderColor;
  4082. Temp.fDeleteTextureOnFree := DeleteTextureOnFree;
  4083. Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
  4084. Temp.fFilterMin := fFilterMin;
  4085. Temp.fFilterMag := fFilterMag;
  4086. Temp.fWrapS := fWrapS;
  4087. Temp.fWrapT := fWrapT;
  4088. Temp.fWrapR := fWrapR;
  4089. Temp.fFilename := fFilename;
  4090. Temp.fCustomName := fCustomName;
  4091. Temp.fCustomNameW := fCustomNameW;
  4092. Temp.fCustomData := fCustomData;
  4093. result := Temp;
  4094. except
  4095. FreeAndNil(Temp);
  4096. raise;
  4097. end;
  4098. end;
  4099. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4100. function TglBitmap.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
  4101. var
  4102. SourceFD, DestFD: TFormatDescriptor;
  4103. SourcePD, DestPD: TglBitmapPixelData;
  4104. ShiftData: TShiftData;
  4105. function CanCopyDirect: Boolean;
  4106. begin
  4107. result :=
  4108. ((SourcePD.Range.r = DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
  4109. ((SourcePD.Range.g = DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
  4110. ((SourcePD.Range.b = DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
  4111. ((SourcePD.Range.a = DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
  4112. end;
  4113. function CanShift: Boolean;
  4114. begin
  4115. result :=
  4116. ((SourcePD.Range.r >= DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
  4117. ((SourcePD.Range.g >= DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
  4118. ((SourcePD.Range.b >= DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
  4119. ((SourcePD.Range.a >= DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
  4120. end;
  4121. function GetShift(aSource, aDest: Cardinal) : ShortInt;
  4122. begin
  4123. result := 0;
  4124. while (aSource > aDest) and (aSource > 0) do begin
  4125. inc(result);
  4126. aSource := aSource shr 1;
  4127. end;
  4128. end;
  4129. begin
  4130. if (aFormat <> fFormat) and (aFormat <> tfEmpty) then begin
  4131. SourceFD := TFormatDescriptor.Get(Format);
  4132. DestFD := TFormatDescriptor.Get(aFormat);
  4133. SourceFD.PreparePixel(SourcePD);
  4134. DestFD.PreparePixel (DestPD);
  4135. if CanCopyDirect then
  4136. result := AddFunc(Self, glBitmapConvertCopyFunc, false, aFormat)
  4137. else if CanShift then begin
  4138. ShiftData.r := GetShift(SourcePD.Range.r, DestPD.Range.r);
  4139. ShiftData.g := GetShift(SourcePD.Range.g, DestPD.Range.g);
  4140. ShiftData.b := GetShift(SourcePD.Range.b, DestPD.Range.b);
  4141. ShiftData.a := GetShift(SourcePD.Range.a, DestPD.Range.a);
  4142. result := AddFunc(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, PtrInt(@ShiftData));
  4143. end else
  4144. result := AddFunc(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
  4145. end else
  4146. result := true;
  4147. end;
  4148. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4149. procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
  4150. begin
  4151. if aUseRGB or aUseAlpha then
  4152. AddFunc(glBitmapInvertFunc, false, ((PtrInt(aUseAlpha) and 1) shl 1) or (PtrInt(aUseRGB) and 1));
  4153. end;
  4154. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4155. procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
  4156. begin
  4157. fBorderColor[0] := aRed;
  4158. fBorderColor[1] := aGreen;
  4159. fBorderColor[2] := aBlue;
  4160. fBorderColor[3] := aAlpha;
  4161. if (ID > 0) then begin
  4162. Bind(false);
  4163. glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
  4164. end;
  4165. end;
  4166. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4167. procedure TglBitmap.FreeData;
  4168. begin
  4169. SetDataPointer(nil, tfEmpty);
  4170. end;
  4171. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4172. procedure TglBitmap.FillWithColor(const aRed, aGreen, aBlue: Byte;
  4173. const aAlpha: Byte);
  4174. begin
  4175. FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
  4176. end;
  4177. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4178. procedure TglBitmap.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
  4179. var
  4180. PixelData: TglBitmapPixelData;
  4181. begin
  4182. TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
  4183. FillWithColorFloat(
  4184. aRed / PixelData.Range.r,
  4185. aGreen / PixelData.Range.g,
  4186. aBlue / PixelData.Range.b,
  4187. aAlpha / PixelData.Range.a);
  4188. end;
  4189. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4190. procedure TglBitmap.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
  4191. var
  4192. PixelData: TglBitmapPixelData;
  4193. begin
  4194. TFormatDescriptor.Get(Format).PreparePixel(PixelData);
  4195. with PixelData do begin
  4196. Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed)));
  4197. Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen)));
  4198. Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue)));
  4199. Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha)));
  4200. end;
  4201. AddFunc(glBitmapFillWithColorFunc, false, PtrInt(@PixelData));
  4202. end;
  4203. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4204. procedure TglBitmap.SetFilter(const aMin, aMag: Cardinal);
  4205. begin
  4206. //check MIN filter
  4207. case aMin of
  4208. GL_NEAREST:
  4209. fFilterMin := GL_NEAREST;
  4210. GL_LINEAR:
  4211. fFilterMin := GL_LINEAR;
  4212. GL_NEAREST_MIPMAP_NEAREST:
  4213. fFilterMin := GL_NEAREST_MIPMAP_NEAREST;
  4214. GL_LINEAR_MIPMAP_NEAREST:
  4215. fFilterMin := GL_LINEAR_MIPMAP_NEAREST;
  4216. GL_NEAREST_MIPMAP_LINEAR:
  4217. fFilterMin := GL_NEAREST_MIPMAP_LINEAR;
  4218. GL_LINEAR_MIPMAP_LINEAR:
  4219. fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
  4220. else
  4221. raise EglBitmapException.Create('SetFilter - Unknow MIN filter.');
  4222. end;
  4223. //check MAG filter
  4224. case aMag of
  4225. GL_NEAREST:
  4226. fFilterMag := GL_NEAREST;
  4227. GL_LINEAR:
  4228. fFilterMag := GL_LINEAR;
  4229. else
  4230. raise EglBitmapException.Create('SetFilter - Unknow MAG filter.');
  4231. end;
  4232. //apply filter
  4233. if (ID > 0) then begin
  4234. Bind(false);
  4235. glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
  4236. if (MipMap = mmNone) or (Target = GL_TEXTURE_RECTANGLE) then begin
  4237. case fFilterMin of
  4238. GL_NEAREST, GL_LINEAR:
  4239. glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
  4240. GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR:
  4241. glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  4242. GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR:
  4243. glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  4244. end;
  4245. end else
  4246. glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
  4247. end;
  4248. end;
  4249. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4250. procedure TglBitmap.SetWrap(const S: Cardinal; const T: Cardinal; const R: Cardinal);
  4251. procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
  4252. begin
  4253. case aValue of
  4254. GL_CLAMP:
  4255. aTarget := GL_CLAMP;
  4256. GL_REPEAT:
  4257. aTarget := GL_REPEAT;
  4258. GL_CLAMP_TO_EDGE: begin
  4259. if GL_VERSION_1_2 or GL_EXT_texture_edge_clamp then
  4260. aTarget := GL_CLAMP_TO_EDGE
  4261. else
  4262. aTarget := GL_CLAMP;
  4263. end;
  4264. GL_CLAMP_TO_BORDER: begin
  4265. if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
  4266. aTarget := GL_CLAMP_TO_BORDER
  4267. else
  4268. aTarget := GL_CLAMP;
  4269. end;
  4270. GL_MIRRORED_REPEAT: begin
  4271. if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
  4272. aTarget := GL_MIRRORED_REPEAT
  4273. else
  4274. raise EglBitmapException.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
  4275. end;
  4276. else
  4277. raise EglBitmapException.Create('SetWrap - Unknow Texturewrap (S).');
  4278. end;
  4279. end;
  4280. begin
  4281. CheckAndSetWrap(S, fWrapS);
  4282. CheckAndSetWrap(T, fWrapT);
  4283. CheckAndSetWrap(R, fWrapR);
  4284. if (ID > 0) then begin
  4285. Bind(false);
  4286. glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
  4287. glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
  4288. glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
  4289. end;
  4290. end;
  4291. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4292. procedure TglBitmap.GetPixel(const aPos: TglBitmapPixelPosition; var aPixel: TglBitmapPixelData);
  4293. begin
  4294. { TODO delete?
  4295. if Assigned (fGetPixelFunc) then
  4296. fGetPixelFunc(aPos, aPixel);
  4297. }
  4298. end;
  4299. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4300. procedure TglBitmap.SetPixel(const aPos: TglBitmapPixelPosition; const aPixel: TglBitmapPixelData);
  4301. begin
  4302. {TODO delete?
  4303. if Assigned (fSetPixelFunc) then
  4304. fSetPixelFuc(aPos, aPixel);
  4305. }
  4306. end;
  4307. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4308. procedure TglBitmap.Bind(const aEnableTextureUnit: Boolean);
  4309. begin
  4310. if aEnableTextureUnit then
  4311. glEnable(Target);
  4312. if (ID > 0) then
  4313. glBindTexture(Target, ID);
  4314. end;
  4315. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4316. procedure TglBitmap.Unbind(const aDisableTextureUnit: Boolean);
  4317. begin
  4318. if aDisableTextureUnit then
  4319. glDisable(Target);
  4320. glBindTexture(Target, 0);
  4321. end;
  4322. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4323. constructor TglBitmap.Create;
  4324. begin
  4325. {$IFNDEF GLB_NO_NATIVE_GL}
  4326. ReadOpenGLExtensions;
  4327. {$ENDIF}
  4328. if (ClassType = TglBitmap) then
  4329. raise EglBitmapException.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
  4330. inherited Create;
  4331. end;
  4332. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4333. constructor TglBitmap.Create(const aFileName: String);
  4334. begin
  4335. Create;
  4336. LoadFromFile(FileName);
  4337. end;
  4338. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4339. constructor TglBitmap.Create(const aStream: TStream);
  4340. begin
  4341. Create;
  4342. LoadFromStream(aStream);
  4343. end;
  4344. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4345. constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat);
  4346. var
  4347. Image: PByte;
  4348. ImageSize: Integer;
  4349. begin
  4350. Create;
  4351. TFormatDescriptor.Get(aFormat).GetSize(aSize);
  4352. GetMem(Image, ImageSize);
  4353. try
  4354. FillChar(Image^, ImageSize, #$FF);
  4355. SetDataPointer(Image, aFormat, aSize.X, aSize.Y);
  4356. except
  4357. FreeMem(Image);
  4358. raise;
  4359. end;
  4360. end;
  4361. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4362. constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat;
  4363. const aFunc: TglBitmapFunction; const aArgs: PtrInt);
  4364. begin
  4365. Create;
  4366. LoadFromFunc(aSize, aFunc, aFormat, aArgs);
  4367. end;
  4368. {$IFDEF GLB_DELPHI}
  4369. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4370. constructor TglBitmap.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
  4371. begin
  4372. Create;
  4373. LoadFromResource(aInstance, aResource, aResType);
  4374. end;
  4375. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4376. constructor TglBitmap.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
  4377. begin
  4378. Create;
  4379. LoadFromResourceID(aInstance, aResourceID, aResType);
  4380. end;
  4381. {$ENDIF}
  4382. {$IFDEF GLB_SUPPORT_PNG_READ}
  4383. {$IF DEFINED(GLB_SDL_IMAGE)}
  4384. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4385. //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4386. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4387. function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
  4388. var
  4389. Surface: PSDL_Surface;
  4390. RWops: PSDL_RWops;
  4391. begin
  4392. result := false;
  4393. RWops := glBitmapCreateRWops(aStream);
  4394. try
  4395. if IMG_isPNG(RWops) > 0 then begin
  4396. Surface := IMG_LoadPNG_RW(RWops);
  4397. try
  4398. AssignFromSurface(Surface);
  4399. Rresult := true;
  4400. finally
  4401. SDL_FreeSurface(Surface);
  4402. end;
  4403. end;
  4404. finally
  4405. SDL_FreeRW(RWops);
  4406. end;
  4407. end;
  4408. {$ELSEIF DEFINED(GLB_LIB_PNG)}
  4409. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4410. procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
  4411. begin
  4412. TStream(png_get_io_ptr(png)).Read(buffer^, size);
  4413. end;
  4414. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4415. function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
  4416. var
  4417. StreamPos: Int64;
  4418. signature: array [0..7] of byte;
  4419. png: png_structp;
  4420. png_info: png_infop;
  4421. TempHeight, TempWidth: Integer;
  4422. Format: TglBitmapInternalFormat;
  4423. png_data: pByte;
  4424. png_rows: array of pByte;
  4425. Row, LineSize: Integer;
  4426. begin
  4427. result := false;
  4428. if not init_libPNG then
  4429. raise Exception.Create('LoadPNG - unable to initialize libPNG.');
  4430. try
  4431. // signature
  4432. StreamPos := Stream.Position;
  4433. Stream.Read(signature, 8);
  4434. Stream.Position := StreamPos;
  4435. if png_check_sig(@signature, 8) <> 0 then begin
  4436. // png read struct
  4437. png := png_create_read_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
  4438. if png = nil then
  4439. raise EglBitmapException.Create('LoadPng - couldn''t create read struct.');
  4440. // png info
  4441. png_info := png_create_info_struct(png);
  4442. if png_info = nil then begin
  4443. png_destroy_read_struct(@png, nil, nil);
  4444. raise EglBitmapException.Create('LoadPng - couldn''t create info struct.');
  4445. end;
  4446. // set read callback
  4447. png_set_read_fn(png, stream, glBitmap_libPNG_read_func);
  4448. // read informations
  4449. png_read_info(png, png_info);
  4450. // size
  4451. TempHeight := png_get_image_height(png, png_info);
  4452. TempWidth := png_get_image_width(png, png_info);
  4453. // format
  4454. case png_get_color_type(png, png_info) of
  4455. PNG_COLOR_TYPE_GRAY:
  4456. Format := tfLuminance8;
  4457. PNG_COLOR_TYPE_GRAY_ALPHA:
  4458. Format := tfLuminance8Alpha8;
  4459. PNG_COLOR_TYPE_RGB:
  4460. Format := tfRGB8;
  4461. PNG_COLOR_TYPE_RGB_ALPHA:
  4462. Format := tfRGBA8;
  4463. else
  4464. raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
  4465. end;
  4466. // cut upper 8 bit from 16 bit formats
  4467. if png_get_bit_depth(png, png_info) > 8 then
  4468. png_set_strip_16(png);
  4469. // expand bitdepth smaller than 8
  4470. if png_get_bit_depth(png, png_info) < 8 then
  4471. png_set_expand(png);
  4472. // allocating mem for scanlines
  4473. LineSize := png_get_rowbytes(png, png_info);
  4474. GetMem(png_data, TempHeight * LineSize);
  4475. try
  4476. SetLength(png_rows, TempHeight);
  4477. for Row := Low(png_rows) to High(png_rows) do begin
  4478. png_rows[Row] := png_data;
  4479. Inc(png_rows[Row], Row * LineSize);
  4480. end;
  4481. // read complete image into scanlines
  4482. png_read_image(png, @png_rows[0]);
  4483. // read end
  4484. png_read_end(png, png_info);
  4485. // destroy read struct
  4486. png_destroy_read_struct(@png, @png_info, nil);
  4487. SetLength(png_rows, 0);
  4488. // set new data
  4489. SetDataPointer(png_data, Format, TempWidth, TempHeight);
  4490. result := true;
  4491. except
  4492. FreeMem(png_data);
  4493. raise;
  4494. end;
  4495. end;
  4496. finally
  4497. quit_libPNG;
  4498. end;
  4499. end;
  4500. {$ELSEIF DEFINED(GLB_PNGIMAGE)}
  4501. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4502. function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
  4503. var
  4504. StreamPos: Int64;
  4505. Png: TPNGObject;
  4506. Header: Array[0..7] of Byte;
  4507. Row, Col, PixSize, LineSize: Integer;
  4508. NewImage, pSource, pDest, pAlpha: pByte;
  4509. Format: TglBitmapInternalFormat;
  4510. const
  4511. PngHeader: Array[0..7] of Byte = (#137, #80, #78, #71, #13, #10, #26, #10);
  4512. begin
  4513. result := false;
  4514. StreamPos := Stream.Position;
  4515. Stream.Read(Header[0], SizeOf(Header));
  4516. Stream.Position := StreamPos;
  4517. {Test if the header matches}
  4518. if Header = PngHeader then begin
  4519. Png := TPNGObject.Create;
  4520. try
  4521. Png.LoadFromStream(Stream);
  4522. case Png.Header.ColorType of
  4523. COLOR_GRAYSCALE:
  4524. Format := ifLuminance;
  4525. COLOR_GRAYSCALEALPHA:
  4526. Format := ifLuminanceAlpha;
  4527. COLOR_RGB:
  4528. Format := ifBGR8;
  4529. COLOR_RGBALPHA:
  4530. Format := ifBGRA8;
  4531. else
  4532. raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
  4533. end;
  4534. PixSize := Trunc(FormatGetSize(Format));
  4535. LineSize := Integer(Png.Header.Width) * PixSize;
  4536. GetMem(NewImage, LineSize * Integer(Png.Header.Height));
  4537. try
  4538. pDest := NewImage;
  4539. case Png.Header.ColorType of
  4540. COLOR_RGB, COLOR_GRAYSCALE:
  4541. begin
  4542. for Row := 0 to Png.Height -1 do begin
  4543. Move (Png.Scanline[Row]^, pDest^, LineSize);
  4544. Inc(pDest, LineSize);
  4545. end;
  4546. end;
  4547. COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA:
  4548. begin
  4549. PixSize := PixSize -1;
  4550. for Row := 0 to Png.Height -1 do begin
  4551. pSource := Png.Scanline[Row];
  4552. pAlpha := pByte(Png.AlphaScanline[Row]);
  4553. for Col := 0 to Png.Width -1 do begin
  4554. Move (pSource^, pDest^, PixSize);
  4555. Inc(pSource, PixSize);
  4556. Inc(pDest, PixSize);
  4557. pDest^ := pAlpha^;
  4558. inc(pAlpha);
  4559. Inc(pDest);
  4560. end;
  4561. end;
  4562. end;
  4563. else
  4564. raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
  4565. end;
  4566. SetDataPointer(NewImage, Format, Png.Header.Width, Png.Header.Height);
  4567. result := true;
  4568. except
  4569. FreeMem(NewImage);
  4570. raise;
  4571. end;
  4572. finally
  4573. Png.Free;
  4574. end;
  4575. end;
  4576. end;
  4577. {$IFEND}
  4578. {$ENDIF}
  4579. {$IFDEF GLB_SUPPORT_PNG_WRITE}
  4580. {$IFDEF GLB_LIB_PNG}
  4581. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4582. procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
  4583. begin
  4584. TStream(png_get_io_ptr(png)).Write(buffer^, size);
  4585. end;
  4586. {$ENDIF}
  4587. {$IF DEFINED(GLB_LIB_PNG)}
  4588. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4589. procedure TglBitmap.SavePNG(const aStream: TStream);
  4590. var
  4591. png: png_structp;
  4592. png_info: png_infop;
  4593. png_rows: array of pByte;
  4594. LineSize: Integer;
  4595. ColorType: Integer;
  4596. Row: Integer;
  4597. begin
  4598. if not (ftPNG in FormatGetSupportedFiles (InternalFormat)) then
  4599. raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
  4600. if not init_libPNG then
  4601. raise Exception.Create('SavePNG - unable to initialize libPNG.');
  4602. try
  4603. case FInternalFormat of
  4604. ifAlpha, ifLuminance, ifDepth8:
  4605. ColorType := PNG_COLOR_TYPE_GRAY;
  4606. ifLuminanceAlpha:
  4607. ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
  4608. ifBGR8, ifRGB8:
  4609. ColorType := PNG_COLOR_TYPE_RGB;
  4610. ifBGRA8, ifRGBA8:
  4611. ColorType := PNG_COLOR_TYPE_RGBA;
  4612. else
  4613. raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
  4614. end;
  4615. LineSize := Trunc(FormatGetSize(FInternalFormat) * Width);
  4616. // creating array for scanline
  4617. SetLength(png_rows, Height);
  4618. try
  4619. for Row := 0 to Height - 1 do begin
  4620. png_rows[Row] := Data;
  4621. Inc(png_rows[Row], Row * LineSize)
  4622. end;
  4623. // write struct
  4624. png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
  4625. if png = nil then
  4626. raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
  4627. // create png info
  4628. png_info := png_create_info_struct(png);
  4629. if png_info = nil then begin
  4630. png_destroy_write_struct(@png, nil);
  4631. raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
  4632. end;
  4633. // set read callback
  4634. png_set_write_fn(png, stream, glBitmap_libPNG_write_func, nil);
  4635. // set compression
  4636. png_set_compression_level(png, 6);
  4637. if InternalFormat in [ifBGR8, ifBGRA8] then
  4638. png_set_bgr(png);
  4639. png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
  4640. png_write_info(png, png_info);
  4641. png_write_image(png, @png_rows[0]);
  4642. png_write_end(png, png_info);
  4643. png_destroy_write_struct(@png, @png_info);
  4644. finally
  4645. SetLength(png_rows, 0);
  4646. end;
  4647. finally
  4648. quit_libPNG;
  4649. end;
  4650. end;
  4651. {$ELSEIF DEFINED(GLB_PNGIMAGE)}
  4652. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4653. procedure TglBitmap.SavePNG(const aStream: TStream);
  4654. var
  4655. Png: TPNGObject;
  4656. pSource, pDest: pByte;
  4657. X, Y, PixSize: Integer;
  4658. ColorType: Cardinal;
  4659. Alpha: Boolean;
  4660. pTemp: pByte;
  4661. Temp: Byte;
  4662. begin
  4663. if not (ftPNG in FormatGetSupportedFiles (InternalFormat)) then
  4664. raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
  4665. case FInternalFormat of
  4666. ifAlpha, ifLuminance, ifDepth8: begin
  4667. ColorType := COLOR_GRAYSCALE;
  4668. PixSize := 1;
  4669. Alpha := false;
  4670. end;
  4671. ifLuminanceAlpha: begin
  4672. ColorType := COLOR_GRAYSCALEALPHA;
  4673. PixSize := 1;
  4674. Alpha := true;
  4675. end;
  4676. ifBGR8, ifRGB8: begin
  4677. ColorType := COLOR_RGB;
  4678. PixSize := 3;
  4679. Alpha := false;
  4680. end;
  4681. ifBGRA8, ifRGBA8: begin
  4682. ColorType := COLOR_RGBALPHA;
  4683. PixSize := 3;
  4684. Alpha := true
  4685. end;
  4686. else
  4687. raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
  4688. end;
  4689. Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
  4690. try
  4691. // Copy ImageData
  4692. pSource := Data;
  4693. for Y := 0 to Height -1 do begin
  4694. pDest := png.ScanLine[Y];
  4695. for X := 0 to Width -1 do begin
  4696. Move(pSource^, pDest^, PixSize);
  4697. Inc(pDest, PixSize);
  4698. Inc(pSource, PixSize);
  4699. if Alpha then begin
  4700. png.AlphaScanline[Y]^[X] := pSource^;
  4701. Inc(pSource);
  4702. end;
  4703. end;
  4704. // convert RGB line to BGR
  4705. if InternalFormat in [ifRGB8, ifRGBA8] then begin
  4706. pTemp := png.ScanLine[Y];
  4707. for X := 0 to Width -1 do begin
  4708. Temp := pByteArray(pTemp)^[0];
  4709. pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
  4710. pByteArray(pTemp)^[2] := Temp;
  4711. Inc(pTemp, 3);
  4712. end;
  4713. end;
  4714. end;
  4715. // Save to Stream
  4716. Png.CompressionLevel := 6;
  4717. Png.SaveToStream(Stream);
  4718. finally
  4719. FreeAndNil(Png);
  4720. end;
  4721. end;
  4722. {$IFEND}
  4723. {$ENDIF}
  4724. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4725. //JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4726. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4727. {$IFDEF GLB_LIB_JPEG}
  4728. type
  4729. glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
  4730. glBitmap_libJPEG_source_mgr = record
  4731. pub: jpeg_source_mgr;
  4732. SrcStream: TStream;
  4733. SrcBuffer: array [1..4096] of byte;
  4734. end;
  4735. glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
  4736. glBitmap_libJPEG_dest_mgr = record
  4737. pub: jpeg_destination_mgr;
  4738. DestStream: TStream;
  4739. DestBuffer: array [1..4096] of byte;
  4740. end;
  4741. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4742. {
  4743. procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
  4744. var
  4745. Msg: String;
  4746. begin
  4747. SetLength(Msg, 256);
  4748. cinfo^.err^.format_message(cinfo, pChar(Msg));
  4749. Writeln('ERROR [' + IntToStr(cinfo^.err^.msg_code) + '] ' + Msg);
  4750. cinfo^.global_state := 0;
  4751. jpeg_abort(cinfo);
  4752. end;
  4753. }
  4754. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4755. {
  4756. procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
  4757. var
  4758. Msg: String;
  4759. begin
  4760. SetLength(Msg, 256);
  4761. cinfo^.err^.format_message(cinfo, pChar(Msg));
  4762. Writeln('OUTPUT [' + IntToStr(cinfo^.err^.msg_code) + '] ' + Msg);
  4763. cinfo^.global_state := 0;
  4764. end;
  4765. }
  4766. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4767. {
  4768. procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
  4769. begin
  4770. end;
  4771. }
  4772. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4773. function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
  4774. var
  4775. src: glBitmap_libJPEG_source_mgr_ptr;
  4776. bytes: integer;
  4777. begin
  4778. src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
  4779. bytes := src^.SrcStream.Read(src^.SrcBuffer[1], 4096);
  4780. if (bytes <= 0) then begin
  4781. src^.SrcBuffer[1] := $FF;
  4782. src^.SrcBuffer[2] := JPEG_EOI;
  4783. bytes := 2;
  4784. end;
  4785. src^.pub.next_input_byte := @(src^.SrcBuffer[1]);
  4786. src^.pub.bytes_in_buffer := bytes;
  4787. result := true;
  4788. end;
  4789. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4790. procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
  4791. var
  4792. src: glBitmap_libJPEG_source_mgr_ptr;
  4793. begin
  4794. src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
  4795. if num_bytes > 0 then begin
  4796. // wanted byte isn't in buffer so set stream position and read buffer
  4797. if num_bytes > src^.pub.bytes_in_buffer then begin
  4798. src^.SrcStream.Position := src^.SrcStream.Position + num_bytes - src^.pub.bytes_in_buffer;
  4799. src^.pub.fill_input_buffer(cinfo);
  4800. end else begin
  4801. // wanted byte is in buffer so only skip
  4802. inc(src^.pub.next_input_byte, num_bytes);
  4803. dec(src^.pub.bytes_in_buffer, num_bytes);
  4804. end;
  4805. end;
  4806. end;
  4807. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4808. {
  4809. procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
  4810. begin
  4811. end;
  4812. }
  4813. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4814. {
  4815. procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
  4816. begin
  4817. end;
  4818. }
  4819. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4820. function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
  4821. var
  4822. dest: glBitmap_libJPEG_dest_mgr_ptr;
  4823. begin
  4824. dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
  4825. if dest^.pub.free_in_buffer < Cardinal(Length(dest^.DestBuffer)) then begin
  4826. // write complete buffer
  4827. dest^.DestStream.Write(dest^.DestBuffer[1], SizeOf(dest^.DestBuffer));
  4828. // reset buffer
  4829. dest^.pub.next_output_byte := @dest^.DestBuffer[1];
  4830. dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
  4831. end;
  4832. result := true;
  4833. end;
  4834. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4835. procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
  4836. var
  4837. Idx: Integer;
  4838. dest: glBitmap_libJPEG_dest_mgr_ptr;
  4839. begin
  4840. dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
  4841. for Idx := Low(dest^.DestBuffer) to High(dest^.DestBuffer) do begin
  4842. // check for endblock
  4843. if (Idx < High(dest^.DestBuffer)) and (dest^.DestBuffer[Idx] = $FF) and (dest^.DestBuffer[Idx +1] = JPEG_EOI) then begin
  4844. // write endblock
  4845. dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
  4846. // leave
  4847. break;
  4848. end else
  4849. dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
  4850. end;
  4851. end;
  4852. {$ENDIF}
  4853. {$IFDEF GLB_SUPPORT_JPEG_READ}
  4854. {$IF DEFINED(GLB_SDL_IMAGE)}
  4855. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4856. function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
  4857. var
  4858. Surface: PSDL_Surface;
  4859. RWops: PSDL_RWops;
  4860. begin
  4861. result := false;
  4862. RWops := glBitmapCreateRWops(Stream);
  4863. try
  4864. if IMG_isJPG(RWops) > 0 then begin
  4865. Surface := IMG_LoadJPG_RW(RWops);
  4866. try
  4867. AssignFromSurface(Surface);
  4868. result := true;
  4869. finally
  4870. SDL_FreeSurface(Surface);
  4871. end;
  4872. end;
  4873. finally
  4874. SDL_FreeRW(RWops);
  4875. end;
  4876. end;
  4877. {$ELSEIF DEFINED(GLB_LIB_JPEG)}
  4878. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4879. function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
  4880. var
  4881. StreamPos: Int64;
  4882. Temp: array[0..1]of Byte;
  4883. jpeg: jpeg_decompress_struct;
  4884. jpeg_err: jpeg_error_mgr;
  4885. IntFormat: TglBitmapInternalFormat;
  4886. pImage: pByte;
  4887. TempHeight, TempWidth: Integer;
  4888. pTemp: pByte;
  4889. Row: Integer;
  4890. begin
  4891. result := false;
  4892. if not init_libJPEG then
  4893. raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
  4894. try
  4895. // reading first two bytes to test file and set cursor back to begin
  4896. StreamPos := Stream.Position;
  4897. Stream.Read(Temp[0], 2);
  4898. Stream.Position := StreamPos;
  4899. // if Bitmap then read file.
  4900. if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
  4901. FillChar(jpeg, SizeOf(jpeg_decompress_struct), $00);
  4902. FillChar(jpeg_err, SizeOf(jpeg_error_mgr), $00);
  4903. // error managment
  4904. jpeg.err := jpeg_std_error(@jpeg_err);
  4905. jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
  4906. jpeg_err.output_message := glBitmap_libJPEG_output_message;
  4907. // decompression struct
  4908. jpeg_create_decompress(@jpeg);
  4909. // allocation space for streaming methods
  4910. jpeg.src := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_source_mgr));
  4911. // seeting up custom functions
  4912. with glBitmap_libJPEG_source_mgr_ptr(jpeg.src)^ do begin
  4913. pub.init_source := glBitmap_libJPEG_init_source;
  4914. pub.fill_input_buffer := glBitmap_libJPEG_fill_input_buffer;
  4915. pub.skip_input_data := glBitmap_libJPEG_skip_input_data;
  4916. pub.resync_to_restart := jpeg_resync_to_restart; // use default method
  4917. pub.term_source := glBitmap_libJPEG_term_source;
  4918. pub.bytes_in_buffer := 0; // forces fill_input_buffer on first read
  4919. pub.next_input_byte := nil; // until buffer loaded
  4920. SrcStream := Stream;
  4921. end;
  4922. // set global decoding state
  4923. jpeg.global_state := DSTATE_START;
  4924. // read header of jpeg
  4925. jpeg_read_header(@jpeg, false);
  4926. // setting output parameter
  4927. case jpeg.jpeg_color_space of
  4928. JCS_GRAYSCALE:
  4929. begin
  4930. jpeg.out_color_space := JCS_GRAYSCALE;
  4931. IntFormat := ifLuminance;
  4932. end;
  4933. else
  4934. jpeg.out_color_space := JCS_RGB;
  4935. IntFormat := ifRGB8;
  4936. end;
  4937. // reading image
  4938. jpeg_start_decompress(@jpeg);
  4939. TempHeight := jpeg.output_height;
  4940. TempWidth := jpeg.output_width;
  4941. // creating new image
  4942. GetMem(pImage, FormatGetImageSize(glBitmapPosition(TempWidth, TempHeight), IntFormat));
  4943. try
  4944. pTemp := pImage;
  4945. for Row := 0 to TempHeight -1 do begin
  4946. jpeg_read_scanlines(@jpeg, @pTemp, 1);
  4947. Inc(pTemp, Trunc(FormatGetSize(IntFormat) * TempWidth));
  4948. end;
  4949. // finish decompression
  4950. jpeg_finish_decompress(@jpeg);
  4951. // destroy decompression
  4952. jpeg_destroy_decompress(@jpeg);
  4953. SetDataPointer(pImage, IntFormat, TempWidth, TempHeight);
  4954. result := true;
  4955. except
  4956. FreeMem(pImage);
  4957. raise;
  4958. end;
  4959. end;
  4960. finally
  4961. quit_libJPEG;
  4962. end;
  4963. end;
  4964. {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
  4965. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4966. function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
  4967. var
  4968. bmp: TBitmap;
  4969. jpg: TJPEGImage;
  4970. StreamPos: Int64;
  4971. Temp: array[0..1]of Byte;
  4972. begin
  4973. result := false;
  4974. // reading first two bytes to test file and set cursor back to begin
  4975. StreamPos := Stream.Position;
  4976. Stream.Read(Temp[0], 2);
  4977. Stream.Position := StreamPos;
  4978. // if Bitmap then read file.
  4979. if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
  4980. bmp := TBitmap.Create;
  4981. try
  4982. jpg := TJPEGImage.Create;
  4983. try
  4984. jpg.LoadFromStream(Stream);
  4985. bmp.Assign(jpg);
  4986. result := AssignFromBitmap(bmp);
  4987. finally
  4988. jpg.Free;
  4989. end;
  4990. finally
  4991. bmp.Free;
  4992. end;
  4993. end;
  4994. end;
  4995. {$IFEND}
  4996. {$ENDIF}
  4997. {$IFDEF GLB_SUPPORT_JPEG_WRITE}
  4998. {$IF DEFEFINED(GLB_LIB_JPEG)}
  4999. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5000. procedure TglBitmap.SaveJPEG(Stream: TStream);
  5001. var
  5002. jpeg: jpeg_compress_struct;
  5003. jpeg_err: jpeg_error_mgr;
  5004. Row: Integer;
  5005. pTemp, pTemp2: pByte;
  5006. procedure CopyRow(pDest, pSource: pByte);
  5007. var
  5008. X: Integer;
  5009. begin
  5010. for X := 0 to Width - 1 do begin
  5011. pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
  5012. pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
  5013. pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
  5014. Inc(pDest, 3);
  5015. Inc(pSource, 3);
  5016. end;
  5017. end;
  5018. begin
  5019. if not (ftJPEG in FormatGetSupportedFiles(Format)) then
  5020. raise EglBitmapUnsupportedInternalFormat.Create('SaveJpg - ' + UNSUPPORTED_INTERNAL_FORMAT);
  5021. if not init_libJPEG then
  5022. raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
  5023. try
  5024. FillChar(jpeg, SizeOf(jpeg_compress_struct), $00);
  5025. FillChar(jpeg_err, SizeOf(jpeg_error_mgr), $00);
  5026. // error managment
  5027. jpeg.err := jpeg_std_error(@jpeg_err);
  5028. jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
  5029. jpeg_err.output_message := glBitmap_libJPEG_output_message;
  5030. // compression struct
  5031. jpeg_create_compress(@jpeg);
  5032. // allocation space for streaming methods
  5033. jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
  5034. // seeting up custom functions
  5035. with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
  5036. pub.init_destination := glBitmap_libJPEG_init_destination;
  5037. pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
  5038. pub.term_destination := glBitmap_libJPEG_term_destination;
  5039. pub.next_output_byte := @DestBuffer[1];
  5040. pub.free_in_buffer := Length(DestBuffer);
  5041. DestStream := Stream;
  5042. end;
  5043. // very important state
  5044. jpeg.global_state := CSTATE_START;
  5045. jpeg.image_width := Width;
  5046. jpeg.image_height := Height;
  5047. case InternalFormat of
  5048. ifAlpha, ifLuminance, ifDepth8: begin
  5049. jpeg.input_components := 1;
  5050. jpeg.in_color_space := JCS_GRAYSCALE;
  5051. end;
  5052. ifRGB8, ifBGR8: begin
  5053. jpeg.input_components := 3;
  5054. jpeg.in_color_space := JCS_RGB;
  5055. end;
  5056. end;
  5057. jpeg_set_defaults(@jpeg);
  5058. jpeg_set_quality(@jpeg, 95, true);
  5059. jpeg_start_compress(@jpeg, true);
  5060. pTemp := Data;
  5061. if InternalFormat = ifBGR8 then
  5062. GetMem(pTemp2, fRowSize)
  5063. else
  5064. pTemp2 := pTemp;
  5065. try
  5066. for Row := 0 to jpeg.image_height -1 do begin
  5067. // prepare row
  5068. if InternalFormat = ifBGR8 then
  5069. CopyRow(pTemp2, pTemp)
  5070. else
  5071. pTemp2 := pTemp;
  5072. // write row
  5073. jpeg_write_scanlines(@jpeg, @pTemp2, 1);
  5074. inc(pTemp, fRowSize);
  5075. end;
  5076. finally
  5077. // free memory
  5078. if InternalFormat = ifBGR8 then
  5079. FreeMem(pTemp2);
  5080. end;
  5081. jpeg_finish_compress(@jpeg);
  5082. jpeg_destroy_compress(@jpeg);
  5083. finally
  5084. quit_libJPEG;
  5085. end;
  5086. end;
  5087. {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
  5088. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5089. procedure TglBitmap.SaveJPEG(Stream: TStream);
  5090. var
  5091. Bmp: TBitmap;
  5092. Jpg: TJPEGImage;
  5093. begin
  5094. if not (ftJPEG in FormatGetSupportedFiles (InternalFormat)) then
  5095. raise EglBitmapUnsupportedInternalFormat.Create('SaveJpg - ' + UNSUPPORTED_INTERNAL_FORMAT);
  5096. Bmp := TBitmap.Create;
  5097. try
  5098. Jpg := TJPEGImage.Create;
  5099. try
  5100. AssignToBitmap(Bmp);
  5101. if FInternalFormat in [ifAlpha, ifLuminance, ifDepth8] then begin
  5102. Jpg.Grayscale := true;
  5103. Jpg.PixelFormat := jf8Bit;
  5104. end;
  5105. Jpg.Assign(Bmp);
  5106. Jpg.SaveToStream(Stream);
  5107. finally
  5108. FreeAndNil(Jpg);
  5109. end;
  5110. finally
  5111. FreeAndNil(Bmp);
  5112. end;
  5113. end;
  5114. {$ENDIF}
  5115. {$ENDIF}
  5116. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5117. //BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5118. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5119. const
  5120. BMP_MAGIC = $4D42;
  5121. BMP_COMP_RGB = 0;
  5122. BMP_COMP_RLE8 = 1;
  5123. BMP_COMP_RLE4 = 2;
  5124. BMP_COMP_BITFIELDS = 3;
  5125. type
  5126. TBMPHeader = packed record
  5127. bfType: Word;
  5128. bfSize: Cardinal;
  5129. bfReserved1: Word;
  5130. bfReserved2: Word;
  5131. bfOffBits: Cardinal;
  5132. end;
  5133. TBMPInfo = packed record
  5134. biSize: Cardinal;
  5135. biWidth: Longint;
  5136. biHeight: Longint;
  5137. biPlanes: Word;
  5138. biBitCount: Word;
  5139. biCompression: Cardinal;
  5140. biSizeImage: Cardinal;
  5141. biXPelsPerMeter: Longint;
  5142. biYPelsPerMeter: Longint;
  5143. biClrUsed: Cardinal;
  5144. biClrImportant: Cardinal;
  5145. end;
  5146. (* TODO: delete?
  5147. TBMPInfoOS = packed record
  5148. biSize: Cardinal;
  5149. biWidth: Longint;
  5150. biHeight: Longint;
  5151. biPlanes: Word;
  5152. biBitCount: Word;
  5153. end;
  5154. *)
  5155. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5156. function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
  5157. //////////////////////////////////////////////////////////////////////////////////////////////////
  5158. function ReadInfo(var aInfo: TBMPInfo; var aMask: TglBitmapColorRec): TglBitmapFormat;
  5159. begin
  5160. result := tfEmpty;
  5161. aStream.Read(aInfo, SizeOf(aInfo));
  5162. FillChar(aMask, SizeOf(aMask), 0);
  5163. //Read Compression
  5164. case aInfo.biCompression of
  5165. BMP_COMP_RLE4,
  5166. BMP_COMP_RLE8: begin
  5167. raise EglBitmapException.Create('RLE compression is not supported');
  5168. end;
  5169. BMP_COMP_BITFIELDS: begin
  5170. if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
  5171. aStream.Read(aMask.r, SizeOf(aMask.r));
  5172. aStream.Read(aMask.g, SizeOf(aMask.g));
  5173. aStream.Read(aMask.b, SizeOf(aMask.b));
  5174. aStream.Read(aMask.a, SizeOf(aMask.a));
  5175. end else
  5176. raise EglBitmapException.Create('Bitfields are only supported for 16bit and 32bit formats');
  5177. end;
  5178. end;
  5179. //get suitable format
  5180. case aInfo.biBitCount of
  5181. 8: result := tfLuminance8;
  5182. 16: result := tfBGR5;
  5183. 24: result := tfBGR8;
  5184. 32: result := tfBGRA8;
  5185. end;
  5186. end;
  5187. function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TColorTableFormat;
  5188. var
  5189. i, c: Integer;
  5190. ColorTable: TColorTable;
  5191. begin
  5192. result := nil;
  5193. if (aInfo.biBitCount >= 16) then
  5194. exit;
  5195. aFormat := tfLuminance8;
  5196. c := aInfo.biClrUsed;
  5197. if (c = 0) then
  5198. c := 1 shl aInfo.biBitCount;
  5199. SetLength(ColorTable, c);
  5200. for i := 0 to c-1 do begin
  5201. aStream.Read(ColorTable[i], SizeOf(TColorTableEnty));
  5202. if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then
  5203. aFormat := tfRGB8;
  5204. end;
  5205. result := TColorTableFormat.Create;
  5206. result.PixelSize := aInfo.biBitCount / 8;
  5207. result.ColorTable := ColorTable;
  5208. result.Range := glBitmapColorRec($FF, $FF, $FF, $00);
  5209. end;
  5210. //////////////////////////////////////////////////////////////////////////////////////////////////
  5211. function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapColorRec;
  5212. const aInfo: TBMPInfo): TBitfieldFormat;
  5213. var
  5214. TmpFormat: TglBitmapFormat;
  5215. FormatDesc: TFormatDescriptor;
  5216. begin
  5217. result := nil;
  5218. if (aMask.r <> 0) or (aMask.g <> 0) or (aMask.b <> 0) or (aMask.a <> 0) then begin
  5219. for TmpFormat := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
  5220. FormatDesc := TFormatDescriptor.Get(TmpFormat);
  5221. if FormatDesc.MaskMatch(aMask.r, aMask.g, aMask.b, aMask.a) then begin
  5222. aFormat := FormatDesc.Format;
  5223. exit;
  5224. end;
  5225. end;
  5226. if (aMask.a = 0) and TFormatDescriptor.Get(aFormat).HasAlpha then
  5227. aFormat := TFormatDescriptor.Get(aFormat).WithoutAlpha;
  5228. if (aMask.a <> 0) and not TFormatDescriptor.Get(aFormat).HasAlpha then
  5229. aFormat := TFormatDescriptor.Get(aFormat).WithAlpha;
  5230. result := TBitfieldFormat.Create;
  5231. result.PixelSize := aInfo.biBitCount / 8;
  5232. result.RedMask := aMask.r;
  5233. result.GreenMask := aMask.g;
  5234. result.BlueMask := aMask.b;
  5235. result.AlphaMask := aMask.a;
  5236. end;
  5237. end;
  5238. var
  5239. //simple types
  5240. StartPos: Int64;
  5241. ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
  5242. PaddingBuff: Cardinal;
  5243. LineBuf, ImageData, TmpData: PByte;
  5244. SourceMD, DestMD: Pointer;
  5245. BmpFormat: TglBitmapFormat;
  5246. ColorTable: TColorTable;
  5247. //records
  5248. Mask: TglBitmapColorRec;
  5249. Header: TBMPHeader;
  5250. Info: TBMPInfo;
  5251. //classes
  5252. SpecialFormat: TFormatDescriptor;
  5253. FormatDesc: TFormatDescriptor;
  5254. //////////////////////////////////////////////////////////////////////////////////////////////////
  5255. procedure SpecialFormatReadLine(aData: PByte; aLineBuf: PByte);
  5256. var
  5257. i, j: Integer;
  5258. Pixel: TglBitmapPixelData;
  5259. begin
  5260. aStream.Read(aLineBuf^, rbLineSize);
  5261. SpecialFormat.PreparePixel(Pixel);
  5262. for i := 0 to Info.biWidth-1 do begin
  5263. SpecialFormat.Unmap(aLineBuf, Pixel, SourceMD);
  5264. with FormatDesc do begin
  5265. //TODO: use convert function
  5266. for j := 0 to 3 do
  5267. if (SpecialFormat.Range.arr[j] <> Range.arr[j]) then begin
  5268. if (SpecialFormat.Range.arr[j] > 0) then
  5269. Pixel.Data.arr[j] := Round(Pixel.Data.arr[j] / SpecialFormat.Range.arr[j] * Range.arr[j])
  5270. else
  5271. Pixel.Data.arr[j] := 0;
  5272. end;
  5273. end;
  5274. FormatDesc.Map(Pixel, aData, DestMD);
  5275. end;
  5276. end;
  5277. begin
  5278. result := false;
  5279. BmpFormat := tfEmpty;
  5280. SpecialFormat := nil;
  5281. LineBuf := nil;
  5282. SourceMD := nil;
  5283. DestMD := nil;
  5284. // Header
  5285. StartPos := aStream.Position;
  5286. aStream.Read(Header, SizeOf(Header));
  5287. if Header.bfType = BMP_MAGIC then begin
  5288. try try
  5289. BmpFormat := ReadInfo(Info, Mask);
  5290. SpecialFormat := ReadColorTable(BmpFormat, Info);
  5291. if not Assigned(SpecialFormat) then
  5292. SpecialFormat := CheckBitfields(BmpFormat, Mask, Info);
  5293. aStream.Position := StartPos + Header.bfOffBits;
  5294. if (BmpFormat <> tfEmpty) then begin
  5295. FormatDesc := TFormatDescriptor.Get(BmpFormat);
  5296. rbLineSize := Round(Info.biWidth * Info.biBitCount / 8); //ReadBuffer LineSize
  5297. wbLineSize := Trunc(Info.biWidth * FormatDesc.PixelSize);
  5298. Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
  5299. //get Memory
  5300. DestMD := FormatDesc.CreateMappingData;
  5301. ImageSize := FormatDesc.GetSize(Info.biWidth, abs(Info.biHeight));
  5302. GetMem(ImageData, ImageSize);
  5303. if Assigned(SpecialFormat) then begin
  5304. GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
  5305. SourceMD := SpecialFormat.CreateMappingData;
  5306. end;
  5307. //read Data
  5308. try try
  5309. FillChar(ImageData^, ImageSize, $FF);
  5310. TmpData := ImageData;
  5311. if (Info.biHeight > 0) then
  5312. Inc(TmpData, wbLineSize * (Info.biHeight-1));
  5313. for i := 0 to Abs(Info.biHeight)-1 do begin
  5314. if Assigned(SpecialFormat) then
  5315. SpecialFormatReadLine(TmpData, LineBuf) //if is special format read and convert data
  5316. else
  5317. aStream.Read(TmpData^, wbLineSize); //else only read data
  5318. if (Info.biHeight > 0) then
  5319. dec(TmpData, wbLineSize)
  5320. else
  5321. inc(TmpData, wbLineSize);
  5322. aStream.Read(PaddingBuff, Padding);
  5323. end;
  5324. SetDataPointer(ImageData, BmpFormat, Info.biWidth, abs(Info.biHeight));
  5325. result := true;
  5326. finally
  5327. if Assigned(LineBuf) then
  5328. FreeMem(LineBuf);
  5329. if Assigned(SourceMD) then
  5330. SpecialFormat.FreeMappingData(SourceMD);
  5331. FormatDesc.FreeMappingData(DestMD);
  5332. end;
  5333. except
  5334. FreeMem(ImageData);
  5335. raise;
  5336. end;
  5337. end else
  5338. raise EglBitmapException.Create('LoadBMP - No suitable format found');
  5339. except
  5340. aStream.Position := StartPos;
  5341. raise;
  5342. end;
  5343. finally
  5344. FreeAndNil(SpecialFormat);
  5345. end;
  5346. end
  5347. else aStream.Position := StartPos;
  5348. end;
  5349. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5350. procedure TglBitmap.SaveBMP(const aStream: TStream);
  5351. var
  5352. Header: TBMPHeader;
  5353. Info: TBMPInfo;
  5354. pData, pTemp: pByte;
  5355. PixelFormat: TglBitmapPixelData;
  5356. FormatDesc: TFormatDescriptor;
  5357. ImageSize, LineSize, Padding, LineIdx, ColorIdx: Integer;
  5358. Temp, RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
  5359. PaddingBuff: Cardinal;
  5360. function GetLineWidth : Integer;
  5361. begin
  5362. result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
  5363. end;
  5364. begin
  5365. if not (ftBMP in FormatGetSupportedFiles(Format)) then
  5366. raise EglBitmapUnsupportedFormatFormat.Create('SaveBMP - ' + UNSUPPORTED_FORMAT);
  5367. ImageSize := TFormatDescriptor.Get(Format).GetSize(Dimension);
  5368. Header.bfType := BMP_MAGIC;
  5369. Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
  5370. Header.bfReserved1 := 0;
  5371. Header.bfReserved2 := 0;
  5372. Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
  5373. FillChar(Info, SizeOf(Info), 0);
  5374. Info.biSize := SizeOf(Info);
  5375. Info.biWidth := Width;
  5376. Info.biHeight := Height;
  5377. Info.biPlanes := 1;
  5378. Info.biCompression := BMP_COMP_RGB;
  5379. Info.biSizeImage := ImageSize;
  5380. case Format of
  5381. tfR3G3B2, tfLuminance8: begin
  5382. Info.biBitCount := 8;
  5383. Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal);
  5384. end;
  5385. tfRGB5, tfRGB5A1, tfR5G6B5, tfRGB4, tfRGBA4,
  5386. tfBGR5, tfBGR5A1, tfB5G6R5, tfBGR4, tfBGRA4: begin
  5387. Info.biBitCount := 16;
  5388. Info.biCompression := BMP_COMP_BITFIELDS;
  5389. end;
  5390. tfBGR8, tfRGB8: begin
  5391. Info.biBitCount := 24;
  5392. end;
  5393. tfRGB10, tfRGB10A2, tfRGBA8,
  5394. tfBGR10, tfBGR10A2, tfBGRA8: begin
  5395. Info.biBitCount := 32;
  5396. Info.biCompression := BMP_COMP_BITFIELDS;
  5397. end;
  5398. else
  5399. raise EglBitmapUnsupportedFormatFormat.Create('SaveBMP - ' + UNSUPPORTED_FORMAT);
  5400. end;
  5401. Info.biXPelsPerMeter := 2835;
  5402. Info.biYPelsPerMeter := 2835;
  5403. // prepare bitmasks
  5404. if Info.biCompression = BMP_COMP_BITFIELDS then begin
  5405. Info.biSize := Info.biSize + 4 * SizeOf(Cardinal);
  5406. Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
  5407. Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
  5408. FormatDesc := TFormatDescriptor.Get(Format);
  5409. RedMask := FormatDesc.RedMask;
  5410. GreenMask := FormatDesc.GreenMask;
  5411. BlueMask := FormatDesc.BlueMask;
  5412. AlphaMask := FormatDesc.AlphaMask;
  5413. end;
  5414. // headers
  5415. aStream.Write(Header, SizeOf(Header));
  5416. aStream.Write(Info, SizeOf(Info));
  5417. // colortable
  5418. if Info.biBitCount = 8 then begin
  5419. Temp := 0;
  5420. for ColorIdx := Low(Byte) to High(Byte) do begin
  5421. aStream.Write(Temp, 4);
  5422. Temp := Temp + $00010101;
  5423. end;
  5424. end;
  5425. // bitmasks
  5426. if Info.biCompression = BMP_COMP_BITFIELDS then begin
  5427. aStream.Write(RedMask, SizeOf(Cardinal));
  5428. aStream.Write(GreenMask, SizeOf(Cardinal));
  5429. aStream.Write(BlueMask, SizeOf(Cardinal));
  5430. aStream.Write(AlphaMask, SizeOf(Cardinal));
  5431. end;
  5432. // image data
  5433. LineSize := Trunc(Width * TFormatDescriptor.Get(Format).PixelSize);
  5434. Padding := GetLineWidth - LineSize;
  5435. PaddingBuff := 0;
  5436. pData := Data;
  5437. Inc(pData, (Height -1) * LineSize);
  5438. // prepare row buffer. But only for RGB because RGBA supports color masks
  5439. // so it's possible to change color within the image.
  5440. if (Format = tfRGB8) then
  5441. GetMem(pTemp, fRowSize)
  5442. else
  5443. pTemp := nil;
  5444. try
  5445. // write image data
  5446. for LineIdx := 0 to Height - 1 do begin
  5447. // preparing row
  5448. if Format = tfRGB8 then begin
  5449. Move(pData^, pTemp^, fRowSize);
  5450. SwapRGB(pTemp, Width, false);
  5451. end else
  5452. pTemp := pData;
  5453. aStream.Write(pTemp^, LineSize);
  5454. Dec(pData, LineSize);
  5455. if Padding > 0 then
  5456. aStream.Write(PaddingBuff, Padding);
  5457. end;
  5458. finally
  5459. // destroy row buffer
  5460. if Format = tfRGB8 then
  5461. FreeMem(pTemp);
  5462. end;
  5463. end;
  5464. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5465. //TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5466. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5467. type
  5468. TTGAHeader = packed record
  5469. ImageID: Byte;
  5470. ColorMapType: Byte;
  5471. ImageType: Byte;
  5472. ColorMapSpec: Array[0..4] of Byte;
  5473. OrigX: Word;
  5474. OrigY: Word;
  5475. Width: Word;
  5476. Height: Word;
  5477. Bpp: Byte;
  5478. ImageDes: Byte;
  5479. end;
  5480. const
  5481. TGA_UNCOMPRESSED_RGB = 2;
  5482. TGA_UNCOMPRESSED_GRAY = 3;
  5483. TGA_COMPRESSED_RGB = 10;
  5484. TGA_COMPRESSED_GRAY = 11;
  5485. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5486. function TglBitmap.LoadTGA(const aStream: TStream): Boolean;
  5487. var
  5488. Header: TTGAHeader;
  5489. NewImage, pData: PByte;
  5490. StreamPos: Int64;
  5491. PixelSize, LineSize, YStart, YEnd, YInc: Integer;
  5492. Format: TglBitmapFormat;
  5493. const
  5494. CACHE_SIZE = $4000;
  5495. ////////////////////////////////////////////////////////////////////////////////////////
  5496. procedure ReadUncompressed;
  5497. var
  5498. RowSize: Integer;
  5499. begin
  5500. RowSize := Header.Width * PixelSize;
  5501. // copy line by line
  5502. while YStart <> YEnd + YInc do begin
  5503. pData := NewImage;
  5504. Inc(pData, YStart * LineSize);
  5505. aStream.Read(pData^, RowSize);
  5506. Inc(YStart, YInc);
  5507. end;
  5508. end;
  5509. ////////////////////////////////////////////////////////////////////////////////////////
  5510. procedure ReadCompressed;
  5511. var
  5512. HeaderWidth, HeaderHeight: Integer;
  5513. LinePixelsRead, ImgPixelsRead, ImgPixelsToRead: Integer;
  5514. Cache: PByte;
  5515. CacheSize, CachePos: Integer;
  5516. Temp: Byte;
  5517. TempBuf: Array [0..15] of Byte;
  5518. PixelRepeat: Boolean;
  5519. PixelToRead, TempPixels: Integer;
  5520. /////////////////////////////////////////////////////////////////
  5521. procedure CheckLine;
  5522. begin
  5523. if LinePixelsRead >= HeaderWidth then begin
  5524. LinePixelsRead := 0;
  5525. pData := NewImage;
  5526. Inc(YStart, YInc);
  5527. Inc(pData, YStart * LineSize);
  5528. end;
  5529. end;
  5530. /////////////////////////////////////////////////////////////////
  5531. procedure CachedRead(out Buffer; Count: Integer);
  5532. var
  5533. BytesRead: Integer;
  5534. begin
  5535. if (CachePos + Count) > CacheSize then begin
  5536. BytesRead := 0;
  5537. // Read Data
  5538. if CacheSize - CachePos > 0 then begin
  5539. BytesRead := CacheSize - CachePos;
  5540. Move(pByteArray(Cache)^[CachePos], Buffer, BytesRead);
  5541. Inc(CachePos, BytesRead);
  5542. end;
  5543. // Reload Data
  5544. CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
  5545. aStream.Read(Cache^, CacheSize);
  5546. CachePos := 0;
  5547. // Read else
  5548. if Count - BytesRead > 0 then begin
  5549. Move(pByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
  5550. Inc(CachePos, Count - BytesRead);
  5551. end;
  5552. end else begin
  5553. Move(pByteArray(Cache)^[CachePos], Buffer, Count);
  5554. Inc(CachePos, Count);
  5555. end;
  5556. end;
  5557. begin
  5558. CacheSize := 0;
  5559. CachePos := 0;
  5560. HeaderWidth := Header.Width;
  5561. HeaderHeight := Header.Height;
  5562. GetMem(Cache, CACHE_SIZE); // 16K Buffer
  5563. try
  5564. ImgPixelsToRead := HeaderWidth * HeaderHeight;
  5565. ImgPixelsRead := 0;
  5566. LinePixelsRead := 0;
  5567. pData := NewImage;
  5568. Inc(pData, YStart * LineSize);
  5569. // Read until all Pixels
  5570. repeat
  5571. CachedRead(Temp, 1);
  5572. PixelRepeat := Temp and $80 > 0;
  5573. PixelToRead := (Temp and $7F) + 1;
  5574. Inc(ImgPixelsRead, PixelToRead);
  5575. if PixelRepeat then begin
  5576. // repeat one pixel x times
  5577. CachedRead(TempBuf[0], PixelSize);
  5578. // repeat Pixel
  5579. while PixelToRead > 0 do begin
  5580. CheckLine;
  5581. TempPixels := HeaderWidth - LinePixelsRead;
  5582. if PixelToRead < TempPixels then
  5583. TempPixels := PixelToRead;
  5584. Inc(LinePixelsRead, TempPixels);
  5585. Dec(PixelToRead, TempPixels);
  5586. while TempPixels > 0 do begin
  5587. case PixelSize of
  5588. 1: begin
  5589. pData^ := TempBuf[0];
  5590. Inc(pData);
  5591. end;
  5592. 2: begin
  5593. pWord(pData)^ := pWord(@TempBuf[0])^;
  5594. Inc(pData, 2);
  5595. end;
  5596. 3: begin
  5597. pWord(pData)^ := pWord(@TempBuf[0])^;
  5598. Inc(pData, 2);
  5599. pData^ := TempBuf[2];
  5600. Inc(pData);
  5601. end;
  5602. 4: begin
  5603. pDWord(pData)^ := pDWord(@TempBuf[0])^;
  5604. Inc(pData, 4);
  5605. end;
  5606. end;
  5607. Dec(TempPixels);
  5608. end;
  5609. end;
  5610. end else begin
  5611. // copy x pixels
  5612. while PixelToRead > 0 do begin
  5613. CheckLine;
  5614. TempPixels := HeaderWidth - LinePixelsRead;
  5615. if PixelToRead < TempPixels then
  5616. TempPixels := PixelToRead;
  5617. CachedRead(pData^, PixelSize * TempPixels);
  5618. Inc(pData, PixelSize * TempPixels);
  5619. Inc(LinePixelsRead, TempPixels);
  5620. Dec(PixelToRead, TempPixels);
  5621. end;
  5622. end;
  5623. until ImgPixelsRead >= ImgPixelsToRead;
  5624. finally
  5625. FreeMem(Cache)
  5626. end;
  5627. end;
  5628. begin
  5629. result := false;
  5630. // reading header to test file and set cursor back to begin
  5631. StreamPos := aStream.Position;
  5632. aStream.Read(Header, SizeOf(Header));
  5633. // no colormapped files
  5634. if (Header.ColorMapType = 0) then begin
  5635. if Header.ImageType in [TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY] then begin
  5636. case Header.Bpp of
  5637. //TODO 8: Format := tfAlpha8;
  5638. 16: Format := tfLuminance8Alpha8;
  5639. 24: Format := tfBGR8;
  5640. 32: Format := tfBGRA8;
  5641. else
  5642. raise EglBitmapException.Create('LoadTga - unsupported BitsPerPixel found.');
  5643. end;
  5644. // skip image ID
  5645. if Header.ImageID <> 0 then
  5646. aStream.Position := aStream.Position + Header.ImageID;
  5647. PixelSize := TFormatDescriptor.Get(Format).GetSize(1, 1);
  5648. LineSize := Trunc(Header.Width * PixelSize);
  5649. GetMem(NewImage, LineSize * Header.Height);
  5650. try
  5651. // Row direction
  5652. if (Header.ImageDes and $20 > 0) then begin
  5653. YStart := 0;
  5654. YEnd := Header.Height -1;
  5655. YInc := 1;
  5656. end else begin
  5657. YStart := Header.Height -1;
  5658. YEnd := 0;
  5659. YInc := -1;
  5660. end;
  5661. // Read Image
  5662. case Header.ImageType of
  5663. TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY:
  5664. ReadUncompressed;
  5665. TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY:
  5666. ReadCompressed;
  5667. end;
  5668. SetDataPointer(NewImage, Format, Header.Width, Header.Height);
  5669. result := true;
  5670. except
  5671. FreeMem(NewImage);
  5672. raise;
  5673. end;
  5674. end
  5675. else aStream.Position := StreamPos;
  5676. end
  5677. else aStream.Position := StreamPos;
  5678. end;
  5679. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5680. procedure TglBitmap.SaveTGA(const aStream: TStream);
  5681. var
  5682. Header: TTGAHeader;
  5683. Size: Integer;
  5684. pTemp: pByte;
  5685. FormatDesc: TFormatDescriptor;
  5686. procedure ConvertData(pTemp: pByte);
  5687. var
  5688. Idx, PixelSize: Integer;
  5689. Temp: byte;
  5690. begin
  5691. PixelSize := fPixelSize;
  5692. for Idx := 1 to Height * Width do begin
  5693. Temp := pByteArray(pTemp)^[2];
  5694. pByteArray(pTemp)^[2] := pByteArray(pTemp)^[0];
  5695. pByteArray(pTemp)^[0] := Temp;
  5696. Inc(pTemp, PixelSize);
  5697. end;
  5698. end;
  5699. begin
  5700. if not (ftTGA in FormatGetSupportedFiles(Format)) then
  5701. raise EglBitmapUnsupportedFormatFormat.Create('SaveTGA - ' + UNSUPPORTED_FORMAT);
  5702. FillChar(Header, SizeOf(Header), 0);
  5703. case Format of
  5704. //TODO ifAlpha8, ifLuminance8, ifDepth8: begin
  5705. tfLuminance8: begin
  5706. Header.ImageType := TGA_UNCOMPRESSED_GRAY;
  5707. Header.Bpp := 8;
  5708. end;
  5709. tfLuminance8Alpha8: begin
  5710. Header.ImageType := TGA_UNCOMPRESSED_GRAY;
  5711. Header.Bpp := 16;
  5712. end;
  5713. tfRGB8, tfBGR8: begin
  5714. Header.ImageType := TGA_UNCOMPRESSED_RGB;
  5715. Header.Bpp := 24;
  5716. end;
  5717. tfRGBA8, tfBGRA8: begin
  5718. Header.ImageType := TGA_UNCOMPRESSED_RGB;
  5719. Header.Bpp := 32;
  5720. end;
  5721. else
  5722. raise EglBitmapUnsupportedFormatFormat.Create('SaveTGA - ' + UNSUPPORTED_FORMAT);
  5723. end;
  5724. Header.Width := Width;
  5725. Header.Height := Height;
  5726. Header.ImageDes := $20;
  5727. FormatDesc := TFormatDescriptor.Get(Format);
  5728. if FormatDesc.HasAlpha then
  5729. Header.ImageDes := Header.ImageDes or $08;
  5730. aStream.Write(Header, SizeOf(Header));
  5731. // convert RGB(A) to BGR(A)
  5732. Size := FormatDesc.GetSize(Dimension);
  5733. if Format in [tfRGB8, tfRGBA8] then begin
  5734. GetMem(pTemp, Size);
  5735. end else
  5736. pTemp := Data;
  5737. try
  5738. // convert data
  5739. if Format in [tfRGB8, tfRGBA8] then begin
  5740. Move(Data^, pTemp^, Size);
  5741. ConvertData(pTemp);
  5742. end;
  5743. // write data
  5744. aStream.Write(pTemp^, Size);
  5745. finally
  5746. // free tempdata
  5747. if Format in [tfRGB8, tfRGBA8] then
  5748. FreeMem(pTemp);
  5749. end;
  5750. end;
  5751. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5752. //DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5753. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5754. const
  5755. DDS_MAGIC = $20534444;
  5756. // DDS_header.dwFlags
  5757. DDSD_CAPS = $00000001;
  5758. DDSD_HEIGHT = $00000002;
  5759. DDSD_WIDTH = $00000004;
  5760. DDSD_PITCH = $00000008;
  5761. DDSD_PIXELFORMAT = $00001000;
  5762. DDSD_MIPMAPCOUNT = $00020000;
  5763. DDSD_LINEARSIZE = $00080000;
  5764. DDSD_DEPTH = $00800000;
  5765. // DDS_header.sPixelFormat.dwFlags
  5766. DDPF_ALPHAPIXELS = $00000001;
  5767. DDPF_FOURCC = $00000004;
  5768. DDPF_INDEXED = $00000020;
  5769. DDPF_RGB = $00000040;
  5770. // DDS_header.sCaps.dwCaps1
  5771. DDSCAPS_COMPLEX = $00000008;
  5772. DDSCAPS_TEXTURE = $00001000;
  5773. DDSCAPS_MIPMAP = $00400000;
  5774. // DDS_header.sCaps.dwCaps2
  5775. DDSCAPS2_CUBEMAP = $00000200;
  5776. DDSCAPS2_CUBEMAP_POSITIVEX = $00000400;
  5777. DDSCAPS2_CUBEMAP_NEGATIVEX = $00000800;
  5778. DDSCAPS2_CUBEMAP_POSITIVEY = $00001000;
  5779. DDSCAPS2_CUBEMAP_NEGATIVEY = $00002000;
  5780. DDSCAPS2_CUBEMAP_POSITIVEZ = $00004000;
  5781. DDSCAPS2_CUBEMAP_NEGATIVEZ = $00008000;
  5782. DDSCAPS2_VOLUME = $00200000;
  5783. D3DFMT_DXT1 = $31545844;
  5784. D3DFMT_DXT3 = $33545844;
  5785. D3DFMT_DXT5 = $35545844;
  5786. type
  5787. TDDSPixelFormat = packed record
  5788. dwSize: Cardinal;
  5789. dwFlags: Cardinal;
  5790. dwFourCC: Cardinal;
  5791. dwRGBBitCount: Cardinal;
  5792. dwRBitMask: Cardinal;
  5793. dwGBitMask: Cardinal;
  5794. dwBBitMask: Cardinal;
  5795. dwABitMask: Cardinal;
  5796. end;
  5797. TDDSCaps = packed record
  5798. dwCaps1: Cardinal;
  5799. dwCaps2: Cardinal;
  5800. dwDDSX: Cardinal;
  5801. dwReserved: Cardinal;
  5802. end;
  5803. TDDSHeader = packed record
  5804. dwMagic: Cardinal;
  5805. dwSize: Cardinal;
  5806. dwFlags: Cardinal;
  5807. dwHeight: Cardinal;
  5808. dwWidth: Cardinal;
  5809. dwPitchOrLinearSize: Cardinal;
  5810. dwDepth: Cardinal;
  5811. dwMipMapCount: Cardinal;
  5812. dwReserved: array[0..10] of Cardinal;
  5813. PixelFormat: TDDSPixelFormat;
  5814. Caps: TDDSCaps;
  5815. dwReserved2: Cardinal;
  5816. end;
  5817. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5818. function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
  5819. var
  5820. Header: TDDSHeader;
  5821. StreamPos: Int64;
  5822. Y, LineSize: Cardinal;
  5823. RowSize: Cardinal;
  5824. NewImage, pData: pByte;
  5825. ddsFormat: TglBitmapFormat;
  5826. function RaiseEx : Exception;
  5827. begin
  5828. result := EglBitmapException.Create('LoadDDS - unsupported Pixelformat found.');
  5829. end;
  5830. function GetDDSFormat: TglBitmapFormat;
  5831. begin
  5832. with Header.PixelFormat do begin
  5833. // Compresses
  5834. if (dwFlags and DDPF_FOURCC) > 0 then begin
  5835. (* TODO
  5836. case Header.PixelFormat.dwFourCC of
  5837. D3DFMT_DXT1: result := ifDXT1;
  5838. D3DFMT_DXT3: result := ifDXT3;
  5839. D3DFMT_DXT5: result := ifDXT5;
  5840. else
  5841. raise RaiseEx;
  5842. end;
  5843. *)
  5844. raise RaiseEx;
  5845. end else
  5846. // RGB
  5847. if (dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS)) > 0 then begin
  5848. case dwRGBBitCount of
  5849. 8: begin
  5850. (* TODO if dwFlags and DDPF_ALPHAPIXELS > 0 then
  5851. result := tfAlpha
  5852. else
  5853. *)
  5854. result := tfLuminance8;
  5855. end;
  5856. 16: begin
  5857. if dwFlags and DDPF_ALPHAPIXELS > 0 then begin
  5858. // Alpha
  5859. case CountSetBits(dwRBitMask) of
  5860. 5: result := tfRGB5A1;
  5861. //TODO 4: result := tfRGBA4;
  5862. else
  5863. result := tfLuminance8Alpha8;
  5864. end;
  5865. end else begin
  5866. // no Alpha
  5867. //TODO result := ifR5G6B5;
  5868. raise RaiseEx;
  5869. end;
  5870. end;
  5871. 24: begin
  5872. if dwRBitMask > dwBBitMask then
  5873. result := tfBGR8
  5874. else
  5875. result := tfRGB8;
  5876. end;
  5877. 32: begin
  5878. if CountSetBits(dwRBitMask) = 10 then
  5879. //TODO result := tfRGB10A2
  5880. raise RaiseEx
  5881. else
  5882. if dwRBitMask > dwBBitMask then
  5883. result := tfBGRA8
  5884. else
  5885. result := tfRGBA8;
  5886. end;
  5887. else
  5888. raise RaiseEx;
  5889. end;
  5890. end else
  5891. raise RaiseEx;
  5892. end;
  5893. end;
  5894. begin
  5895. result := false;
  5896. // Header
  5897. StreamPos := aStream.Position;
  5898. aStream.Read(Header, sizeof(Header));
  5899. if ((Header.dwMagic <> DDS_MAGIC) or (Header.dwSize <> 124) or
  5900. ((Header.dwFlags and DDSD_PIXELFORMAT) = 0) or ((Header.dwFlags and DDSD_CAPS) = 0)) then begin
  5901. aStream.Position := StreamPos;
  5902. exit;
  5903. end;
  5904. ddsFormat := GetDDSFormat;
  5905. LineSize := Trunc(Header.dwWidth * TFormatDescriptor.Get(ddsFormat).PixelSize);
  5906. GetMem(NewImage, Header.dwHeight * LineSize);
  5907. try
  5908. pData := NewImage;
  5909. // Compressed
  5910. if (Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0 then begin
  5911. RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
  5912. for Y := 0 to Header.dwHeight -1 do begin
  5913. aStream.Read(pData^, RowSize);
  5914. Inc(pData, LineSize);
  5915. end;
  5916. end else
  5917. // RGB(A)
  5918. if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS)) > 0 then begin
  5919. RowSize := Header.dwPitchOrLinearSize;
  5920. for Y := 0 to Header.dwHeight -1 do begin
  5921. aStream.Read(pData^, RowSize);
  5922. Inc(pData, LineSize);
  5923. end;
  5924. end else
  5925. raise RaiseEx;
  5926. SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight);
  5927. result := true;
  5928. except
  5929. FreeMem(NewImage);
  5930. raise;
  5931. end;
  5932. end;
  5933. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5934. procedure TglBitmap.SaveDDS(const aStream: TStream);
  5935. var
  5936. Header: TDDSHeader;
  5937. Pix: TglBitmapPixelData;
  5938. FormatDesc: TFormatDescriptor;
  5939. begin
  5940. //if not FormatIsUncompressed(InternalFormat) then
  5941. // raise EglBitmapUnsupportedFormatFormat.Create('SaveDDS - ' + UNSUPPORTED_FORMAT);
  5942. (* TODO if Format = tfAlpha8 then
  5943. FORMAT_DESCRIPTORS[tfLuminance8].PreparePixel(Pix);
  5944. else *)
  5945. TFormatDescriptor.Get(Format).PreparePixel(Pix);
  5946. // Generell
  5947. FillChar(Header, SizeOf(Header), 0);
  5948. Header.dwMagic := DDS_MAGIC;
  5949. Header.dwSize := 124;
  5950. Header.dwFlags := DDSD_PITCH or DDSD_CAPS or DDSD_PIXELFORMAT;
  5951. if Width > 0 then begin
  5952. Header.dwWidth := Width;
  5953. Header.dwFlags := Header.dwFlags or DDSD_WIDTH;
  5954. end;
  5955. if Height > 0 then begin
  5956. Header.dwHeight := Height;
  5957. Header.dwFlags := Header.dwFlags or DDSD_HEIGHT;
  5958. end;
  5959. Header.dwPitchOrLinearSize := fRowSize;
  5960. Header.dwMipMapCount := 1;
  5961. // Caps
  5962. Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
  5963. // Pixelformat
  5964. Header.PixelFormat.dwSize := Sizeof(Header.PixelFormat);
  5965. Header.PixelFormat.dwFlags := DDPF_RGB;
  5966. (* TODO tfAlpha8
  5967. if FORMAT_DESCRIPTORS[Format].HasAlpha and (Format <> tfAlpha8) then
  5968. Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
  5969. *)
  5970. FormatDesc := TFormatDescriptor.Get(Format);
  5971. Header.PixelFormat.dwRGBBitCount := Trunc(FormatDesc.PixelSize * 8);
  5972. Header.PixelFormat.dwRBitMask := FormatDesc.RedMask;
  5973. Header.PixelFormat.dwGBitMask := FormatDesc.GreenMask;
  5974. Header.PixelFormat.dwBBitMask := FormatDesc.BlueMask;
  5975. Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
  5976. aStream.Write(Header, SizeOf(Header));
  5977. aStream.Write(Data^, FormatDesc.GetSize(Dimension));
  5978. end;
  5979. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5980. //TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5981. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5982. function TglBitmap2D.GetScanline(const aIndex: Integer): Pointer;
  5983. begin
  5984. if (aIndex >= Low(fLines)) and (aIndex <= High(fLines)) then
  5985. result := fLines[aIndex]
  5986. else
  5987. result := nil;
  5988. end;
  5989. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5990. procedure TglBitmap2D.SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
  5991. const aWidth: Integer; const aHeight: Integer);
  5992. var
  5993. Idx, LineWidth: Integer;
  5994. begin
  5995. inherited SetDataPointer(aData, aFormat, aWidth, aHeight);
  5996. //TODO compression
  5997. if {FormatIsUncompressed(Format)} true then begin
  5998. (* TODO PixelFuncs
  5999. fGetPixelFunc := GetPixel2DUnmap;
  6000. fSetPixelFunc := SetPixel2DUnmap;
  6001. *)
  6002. // Assigning Data
  6003. if Assigned(Data) then begin
  6004. SetLength(fLines, GetHeight);
  6005. LineWidth := Trunc(GetWidth * TFormatDescriptor.Get(Format).PixelSize);
  6006. for Idx := 0 to GetHeight -1 do begin
  6007. fLines[Idx] := Data;
  6008. Inc(fLines[Idx], Idx * LineWidth);
  6009. end;
  6010. end
  6011. else SetLength(fLines, 0);
  6012. end else begin
  6013. (*
  6014. SetLength(fLines, 0);
  6015. fSetPixelFunc := nil;
  6016. case Format of
  6017. ifDXT1:
  6018. fGetPixelFunc := GetPixel2DDXT1;
  6019. ifDXT3:
  6020. fGetPixelFunc := GetPixel2DDXT3;
  6021. ifDXT5:
  6022. fGetPixelFunc := GetPixel2DDXT5;
  6023. else
  6024. fGetPixelFunc := nil;
  6025. end;
  6026. *)
  6027. end;
  6028. end;
  6029. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6030. procedure TglBitmap2D.UploadData(const aTarget: Cardinal; const aBuildWithGlu: Boolean);
  6031. var
  6032. FormatDesc: TFormatDescriptor;
  6033. begin
  6034. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  6035. (* TODO compression
  6036. if Self.InternalFormat in [ifDXT1, ifDXT3, ifDXT5] then
  6037. glCompressedTexImage2D(Target, 0, InternalFormat, Width, Height, 0, Trunc(Width * Height * FormatGetSize(Self.InternalFormat)), Data)
  6038. else
  6039. *)
  6040. FormatDesc := TFormatDescriptor.Get(Format);
  6041. if aBuildWithGlu then
  6042. gluBuild2DMipmaps(aTarget, FormatDesc.Components, Width, Height,
  6043. FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
  6044. else
  6045. glTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0,
  6046. FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
  6047. // Freigeben
  6048. if (FreeDataAfterGenTexture) then
  6049. FreeData;
  6050. end;
  6051. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6052. procedure TglBitmap2D.AfterConstruction;
  6053. begin
  6054. inherited;
  6055. Target := GL_TEXTURE_2D;
  6056. end;
  6057. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6058. procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
  6059. var
  6060. Temp: pByte;
  6061. Size, w, h: Integer;
  6062. FormatDesc: TFormatDescriptor;
  6063. begin
  6064. (* TODO compression
  6065. if not FormatIsUncompressed(Format) then
  6066. raise EglBitmapUnsupportedFormatFormat.Create('TglBitmap2D.GrabScreen - ' + UNSUPPORTED_FORMAT);
  6067. *)
  6068. w := aRight - aLeft;
  6069. h := aBottom - aTop;
  6070. FormatDesc := TFormatDescriptor.Get(Format);
  6071. Size := FormatDesc.GetSize(w, h);
  6072. GetMem(Temp, Size);
  6073. try
  6074. glPixelStorei(GL_PACK_ALIGNMENT, 1);
  6075. glReadPixels(aLeft, aTop, w, h, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
  6076. SetDataPointer(Temp, Format, w, h);
  6077. FlipVert;
  6078. except
  6079. FreeMem(Temp);
  6080. raise;
  6081. end;
  6082. end;
  6083. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6084. procedure TglBitmap2D.GetDataFromTexture;
  6085. var
  6086. Temp: PByte;
  6087. TempWidth, TempHeight: Integer;
  6088. TempType, TempIntFormat: Cardinal;
  6089. IntFormat, f: TglBitmapFormat;
  6090. FormatDesc: TFormatDescriptor;
  6091. begin
  6092. Bind;
  6093. // Request Data
  6094. glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
  6095. glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
  6096. glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
  6097. IntFormat := tfEmpty;
  6098. for f := Low(TglBitmapFormat) to High(TglBitmapFormat) do
  6099. if (TFormatDescriptor.Get(f).glInternalFormat = TempIntFormat) then begin
  6100. IntFormat := FormatDesc.Format;
  6101. break;
  6102. end;
  6103. // Getting data from OpenGL
  6104. FormatDesc := TFormatDescriptor.Get(IntFormat);
  6105. GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
  6106. try
  6107. (* TODO Compression
  6108. if FormatIsCompressed(IntFormat) and (GL_VERSION_1_3 or GL_ARB_texture_compression) then
  6109. glGetCompressedTexImage(Target, 0, Temp)
  6110. else
  6111. *)
  6112. glGetTexImage(Target, 0, FormatDesc.glInternalFormat, FormatDesc.glDataFormat, Temp);
  6113. SetDataPointer(Temp, IntFormat, TempWidth, TempHeight);
  6114. except
  6115. FreeMem(Temp);
  6116. raise;
  6117. end;
  6118. end;
  6119. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6120. procedure TglBitmap2D.GenTexture(const aTestTextureSize: Boolean);
  6121. var
  6122. BuildWithGlu, PotTex, TexRec: Boolean;
  6123. TexSize: Integer;
  6124. begin
  6125. if Assigned(Data) then begin
  6126. // Check Texture Size
  6127. if (aTestTextureSize) then begin
  6128. glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
  6129. if ((Height > TexSize) or (Width > TexSize)) then
  6130. raise EglBitmapSizeToLargeException.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
  6131. PotTex := IsPowerOfTwo(Height) and IsPowerOfTwo(Width);
  6132. TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE_ARB);
  6133. if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
  6134. raise EglBitmapNonPowerOfTwoException.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
  6135. end;
  6136. CreateId;
  6137. SetupParameters(BuildWithGlu);
  6138. UploadData(Target, BuildWithGlu);
  6139. glAreTexturesResident(1, @fID, @fIsResident);
  6140. end;
  6141. end;
  6142. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6143. function TglBitmap2D.FlipHorz: Boolean;
  6144. var
  6145. Col, Row: Integer;
  6146. TempDestData, DestData, SourceData: PByte;
  6147. ImgSize: Integer;
  6148. begin
  6149. result := inherited FlipHorz;
  6150. if Assigned(Data) then begin
  6151. SourceData := Data;
  6152. ImgSize := Height * fRowSize;
  6153. GetMem(DestData, ImgSize);
  6154. try
  6155. TempDestData := DestData;
  6156. Dec(TempDestData, fRowSize + fPixelSize);
  6157. for Row := 0 to Height -1 do begin
  6158. Inc(TempDestData, fRowSize * 2);
  6159. for Col := 0 to Width -1 do begin
  6160. Move(SourceData^, TempDestData^, fPixelSize);
  6161. Inc(SourceData, fPixelSize);
  6162. Dec(TempDestData, fPixelSize);
  6163. end;
  6164. end;
  6165. SetDataPointer(DestData, Format);
  6166. result := true;
  6167. except
  6168. FreeMem(DestData);
  6169. raise;
  6170. end;
  6171. end;
  6172. end;
  6173. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6174. function TglBitmap2D.FlipVert: Boolean;
  6175. var
  6176. Row: Integer;
  6177. TempDestData, DestData, SourceData: PByte;
  6178. begin
  6179. result := inherited FlipVert;
  6180. if Assigned(Data) then begin
  6181. SourceData := Data;
  6182. GetMem(DestData, Height * fRowSize);
  6183. try
  6184. TempDestData := DestData;
  6185. Inc(TempDestData, Width * (Height -1) * fPixelSize);
  6186. for Row := 0 to Height -1 do begin
  6187. Move(SourceData^, TempDestData^, fRowSize);
  6188. Dec(TempDestData, fRowSize);
  6189. Inc(SourceData, fRowSize);
  6190. end;
  6191. SetDataPointer(DestData, Format);
  6192. result := true;
  6193. except
  6194. FreeMem(DestData);
  6195. raise;
  6196. end;
  6197. end;
  6198. end;
  6199. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6200. //TglBitmap2D - ToNormalMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6201. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6202. type
  6203. TMatrixItem = record
  6204. X, Y: Integer;
  6205. W: Single;
  6206. end;
  6207. PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
  6208. TglBitmapToNormalMapRec = Record
  6209. Scale: Single;
  6210. Heights: array of Single;
  6211. MatrixU : array of TMatrixItem;
  6212. MatrixV : array of TMatrixItem;
  6213. end;
  6214. const
  6215. ONE_OVER_255 = 1 / 255;
  6216. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6217. procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
  6218. var
  6219. Val: Single;
  6220. begin
  6221. with FuncRec do begin
  6222. Val :=
  6223. Source.Data.r * LUMINANCE_WEIGHT_R +
  6224. Source.Data.g * LUMINANCE_WEIGHT_G +
  6225. Source.Data.b * LUMINANCE_WEIGHT_B;
  6226. PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255;
  6227. end;
  6228. end;
  6229. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6230. procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
  6231. begin
  6232. with FuncRec do
  6233. PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
  6234. end;
  6235. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6236. procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
  6237. type
  6238. TVec = Array[0..2] of Single;
  6239. var
  6240. Idx: Integer;
  6241. du, dv: Double;
  6242. Len: Single;
  6243. Vec: TVec;
  6244. function GetHeight(X, Y: Integer): Single;
  6245. begin
  6246. with FuncRec do begin
  6247. X := Max(0, Min(Size.X -1, X));
  6248. Y := Max(0, Min(Size.Y -1, Y));
  6249. result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
  6250. end;
  6251. end;
  6252. begin
  6253. with FuncRec do begin
  6254. with PglBitmapToNormalMapRec(Args)^ do begin
  6255. du := 0;
  6256. for Idx := Low(MatrixU) to High(MatrixU) do
  6257. du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
  6258. dv := 0;
  6259. for Idx := Low(MatrixU) to High(MatrixU) do
  6260. dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
  6261. Vec[0] := -du * Scale;
  6262. Vec[1] := -dv * Scale;
  6263. Vec[2] := 1;
  6264. end;
  6265. // Normalize
  6266. Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
  6267. if Len <> 0 then begin
  6268. Vec[0] := Vec[0] * Len;
  6269. Vec[1] := Vec[1] * Len;
  6270. Vec[2] := Vec[2] * Len;
  6271. end;
  6272. // Farbe zuweisem
  6273. Dest.Data.r := Trunc((Vec[0] + 1) * 127.5);
  6274. Dest.Data.g := Trunc((Vec[1] + 1) * 127.5);
  6275. Dest.Data.b := Trunc((Vec[2] + 1) * 127.5);
  6276. end;
  6277. end;
  6278. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6279. procedure TglBitmap2D.ToNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
  6280. var
  6281. Rec: TglBitmapToNormalMapRec;
  6282. procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
  6283. begin
  6284. if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
  6285. Matrix[Index].X := X;
  6286. Matrix[Index].Y := Y;
  6287. Matrix[Index].W := W;
  6288. end;
  6289. end;
  6290. begin
  6291. (* TODO Compression
  6292. if not FormatIsUncompressed(InternalFormat) then
  6293. raise EglBitmapUnsupportedFormatFormat.Create('TglBitmap2D.ToNormalMap - ' + UNSUPPORTED_FORMAT);
  6294. *)
  6295. if aScale > 100 then
  6296. Rec.Scale := 100
  6297. else if aScale < -100 then
  6298. Rec.Scale := -100
  6299. else
  6300. Rec.Scale := aScale;
  6301. SetLength(Rec.Heights, Width * Height);
  6302. try
  6303. case aFunc of
  6304. nm4Samples: begin
  6305. SetLength(Rec.MatrixU, 2);
  6306. SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
  6307. SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
  6308. SetLength(Rec.MatrixV, 2);
  6309. SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
  6310. SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
  6311. end;
  6312. nmSobel: begin
  6313. SetLength(Rec.MatrixU, 6);
  6314. SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
  6315. SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
  6316. SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
  6317. SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
  6318. SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
  6319. SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
  6320. SetLength(Rec.MatrixV, 6);
  6321. SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
  6322. SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
  6323. SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
  6324. SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
  6325. SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
  6326. SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
  6327. end;
  6328. nm3x3: begin
  6329. SetLength(Rec.MatrixU, 6);
  6330. SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
  6331. SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
  6332. SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
  6333. SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
  6334. SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
  6335. SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
  6336. SetLength(Rec.MatrixV, 6);
  6337. SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
  6338. SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
  6339. SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
  6340. SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
  6341. SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
  6342. SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
  6343. end;
  6344. nm5x5: begin
  6345. SetLength(Rec.MatrixU, 20);
  6346. SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
  6347. SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
  6348. SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
  6349. SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
  6350. SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
  6351. SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
  6352. SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
  6353. SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
  6354. SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
  6355. SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
  6356. SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
  6357. SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
  6358. SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
  6359. SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
  6360. SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
  6361. SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
  6362. SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
  6363. SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
  6364. SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
  6365. SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
  6366. SetLength(Rec.MatrixV, 20);
  6367. SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
  6368. SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
  6369. SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
  6370. SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
  6371. SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
  6372. SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
  6373. SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
  6374. SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
  6375. SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
  6376. SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
  6377. SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
  6378. SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
  6379. SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
  6380. SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
  6381. SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
  6382. SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
  6383. SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
  6384. SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
  6385. SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
  6386. SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
  6387. end;
  6388. end;
  6389. // Daten Sammeln
  6390. if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
  6391. AddFunc(glBitmapToNormalMapPrepareAlphaFunc, false, PtrInt(@Rec))
  6392. else
  6393. AddFunc(glBitmapToNormalMapPrepareFunc, false, PtrInt(@Rec));
  6394. AddFunc(glBitmapToNormalMapFunc, false, PtrInt(@Rec));
  6395. finally
  6396. SetLength(Rec.Heights, 0);
  6397. end;
  6398. end;
  6399. (*
  6400. procedure TglBitmap1D.SetDataPointer(Data: pByte; Format: TglBitmapInternalFormat; Width, Height: Integer);
  6401. var
  6402. pTemp: pByte;
  6403. Size: Integer;
  6404. begin
  6405. if Height > 1 then begin
  6406. // extract first line of the data
  6407. Size := FormatGetImageSize(glBitmapPosition(Width), Format);
  6408. GetMem(pTemp, Size);
  6409. Move(Data^, pTemp^, Size);
  6410. FreeMem(Data);
  6411. end else
  6412. pTemp := Data;
  6413. // set data pointer
  6414. inherited SetDataPointer(pTemp, Format, Width);
  6415. if FormatIsUncompressed(Format) then begin
  6416. fUnmapFunc := FormatGetUnMapFunc(Format);
  6417. fGetPixelFunc := GetPixel1DUnmap;
  6418. end;
  6419. end;
  6420. procedure TglBitmap1D.GetPixel1DUnmap(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
  6421. var
  6422. pTemp: pByte;
  6423. begin
  6424. pTemp := Data;
  6425. Inc(pTemp, Pos.X * fPixelSize);
  6426. fUnmapFunc(pTemp, Pixel);
  6427. end;
  6428. function TglBitmap1D.FlipHorz: Boolean;
  6429. var
  6430. Col: Integer;
  6431. pTempDest, pDest, pSource: pByte;
  6432. begin
  6433. result := inherited FlipHorz;
  6434. if Assigned(Data) and FormatIsUncompressed(InternalFormat) then begin
  6435. pSource := Data;
  6436. GetMem(pDest, fRowSize);
  6437. try
  6438. pTempDest := pDest;
  6439. Inc(pTempDest, fRowSize);
  6440. for Col := 0 to Width -1 do begin
  6441. Move(pSource^, pTempDest^, fPixelSize);
  6442. Inc(pSource, fPixelSize);
  6443. Dec(pTempDest, fPixelSize);
  6444. end;
  6445. SetDataPointer(pDest, InternalFormat);
  6446. result := true;
  6447. finally
  6448. FreeMem(pDest);
  6449. end;
  6450. end;
  6451. end;
  6452. procedure TglBitmap1D.UploadData (Target, Format, InternalFormat, Typ: Cardinal; BuildWithGlu: Boolean);
  6453. begin
  6454. // Upload data
  6455. if Self.InternalFormat in [ifDXT1, ifDXT3, ifDXT5] then
  6456. glCompressedTexImage1D(Target, 0, InternalFormat, Width, 0, Trunc(Width * FormatGetSize(Self.InternalFormat)), Data)
  6457. else
  6458. // Upload data
  6459. if BuildWithGlu then
  6460. gluBuild1DMipmaps(Target, InternalFormat, Width, Format, Typ, Data)
  6461. else
  6462. glTexImage1D(Target, 0, InternalFormat, Width, 0, Format, Typ, Data);
  6463. // Freigeben
  6464. if (FreeDataAfterGenTexture) then
  6465. FreeData;
  6466. end;
  6467. procedure TglBitmap1D.GenTexture(TestTextureSize: Boolean);
  6468. var
  6469. BuildWithGlu, TexRec: Boolean;
  6470. glFormat, glInternalFormat, glType: Cardinal;
  6471. TexSize: Integer;
  6472. begin
  6473. if Assigned(Data) then begin
  6474. // Check Texture Size
  6475. if (TestTextureSize) then begin
  6476. glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
  6477. if (Width > TexSize) then
  6478. raise EglBitmapSizeToLargeException.Create('TglBitmap1D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
  6479. TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
  6480. (Target = GL_TEXTURE_RECTANGLE_ARB);
  6481. if not (IsPowerOfTwo (Width) or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
  6482. raise EglBitmapNonPowerOfTwoException.Create('TglBitmap1D.GenTexture - Rendercontex dosn''t support non power of two texture.');
  6483. end;
  6484. CreateId;
  6485. SetupParameters(BuildWithGlu);
  6486. SelectFormat(InternalFormat, glFormat, glInternalFormat, glType);
  6487. UploadData(Target, glFormat, glInternalFormat, glType, BuildWithGlu);
  6488. // Infos sammeln
  6489. glAreTexturesResident(1, @fID, @fIsResident);
  6490. end;
  6491. end;
  6492. procedure TglBitmap1D.AfterConstruction;
  6493. begin
  6494. inherited;
  6495. Target := GL_TEXTURE_1D;
  6496. end;
  6497. { TglBitmapCubeMap }
  6498. procedure TglBitmapCubeMap.AfterConstruction;
  6499. begin
  6500. inherited;
  6501. if not (GL_VERSION_1_3 or GL_ARB_texture_cube_map or GL_EXT_texture_cube_map) then
  6502. raise EglBitmapException.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
  6503. SetWrap; // set all to GL_CLAMP_TO_EDGE
  6504. Target := GL_TEXTURE_CUBE_MAP;
  6505. fGenMode := GL_REFLECTION_MAP;
  6506. end;
  6507. procedure TglBitmapCubeMap.Bind(EnableTexCoordsGen, EnableTextureUnit: Boolean);
  6508. begin
  6509. inherited Bind (EnableTextureUnit);
  6510. if EnableTexCoordsGen then begin
  6511. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, fGenMode);
  6512. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, fGenMode);
  6513. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, fGenMode);
  6514. glEnable(GL_TEXTURE_GEN_S);
  6515. glEnable(GL_TEXTURE_GEN_T);
  6516. glEnable(GL_TEXTURE_GEN_R);
  6517. end;
  6518. end;
  6519. procedure TglBitmapCubeMap.GenerateCubeMap(CubeTarget: Cardinal; TestTextureSize: Boolean);
  6520. var
  6521. glFormat, glInternalFormat, glType: Cardinal;
  6522. BuildWithGlu: Boolean;
  6523. TexSize: Integer;
  6524. begin
  6525. // Check Texture Size
  6526. if (TestTextureSize) then begin
  6527. glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @TexSize);
  6528. if ((Height > TexSize) or (Width > TexSize)) then
  6529. raise EglBitmapSizeToLargeException.Create('TglBitmapCubeMap.GenTexture - The size for the Cubemap is to large. It''s may be not conform with the Hardware.');
  6530. if not ((IsPowerOfTwo (Height) and IsPowerOfTwo (Width)) or GL_VERSION_2_0 or GL_ARB_texture_non_power_of_two) then
  6531. raise EglBitmapNonPowerOfTwoException.Create('TglBitmapCubeMap.GenTexture - Cubemaps dosn''t support non power of two texture.');
  6532. end;
  6533. // create Texture
  6534. if ID = 0 then begin
  6535. CreateID;
  6536. SetupParameters(BuildWithGlu);
  6537. end;
  6538. SelectFormat(InternalFormat, glFormat, glInternalFormat, glType);
  6539. UploadData (CubeTarget, glFormat, glInternalFormat, glType, BuildWithGlu);
  6540. end;
  6541. procedure TglBitmapCubeMap.GenTexture(TestTextureSize: Boolean);
  6542. begin
  6543. Assert(false, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
  6544. end;
  6545. procedure TglBitmapCubeMap.Unbind(DisableTexCoordsGen,
  6546. DisableTextureUnit: Boolean);
  6547. begin
  6548. inherited Unbind (DisableTextureUnit);
  6549. if DisableTexCoordsGen then begin
  6550. glDisable(GL_TEXTURE_GEN_S);
  6551. glDisable(GL_TEXTURE_GEN_T);
  6552. glDisable(GL_TEXTURE_GEN_R);
  6553. end;
  6554. end;
  6555. { TglBitmapNormalMap }
  6556. type
  6557. TVec = Array[0..2] of Single;
  6558. TglBitmapNormalMapGetVectorFunc = procedure (var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
  6559. PglBitmapNormalMapRec = ^TglBitmapNormalMapRec;
  6560. TglBitmapNormalMapRec = record
  6561. HalfSize : Integer;
  6562. Func: TglBitmapNormalMapGetVectorFunc;
  6563. end;
  6564. procedure glBitmapNormalMapPosX(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
  6565. begin
  6566. Vec[0] := HalfSize;
  6567. Vec[1] := - (Position.Y + 0.5 - HalfSize);
  6568. Vec[2] := - (Position.X + 0.5 - HalfSize);
  6569. end;
  6570. procedure glBitmapNormalMapNegX(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
  6571. begin
  6572. Vec[0] := - HalfSize;
  6573. Vec[1] := - (Position.Y + 0.5 - HalfSize);
  6574. Vec[2] := Position.X + 0.5 - HalfSize;
  6575. end;
  6576. procedure glBitmapNormalMapPosY(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
  6577. begin
  6578. Vec[0] := Position.X + 0.5 - HalfSize;
  6579. Vec[1] := HalfSize;
  6580. Vec[2] := Position.Y + 0.5 - HalfSize;
  6581. end;
  6582. procedure glBitmapNormalMapNegY(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
  6583. begin
  6584. Vec[0] := Position.X + 0.5 - HalfSize;
  6585. Vec[1] := - HalfSize;
  6586. Vec[2] := - (Position.Y + 0.5 - HalfSize);
  6587. end;
  6588. procedure glBitmapNormalMapPosZ(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
  6589. begin
  6590. Vec[0] := Position.X + 0.5 - HalfSize;
  6591. Vec[1] := - (Position.Y + 0.5 - HalfSize);
  6592. Vec[2] := HalfSize;
  6593. end;
  6594. procedure glBitmapNormalMapNegZ(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
  6595. begin
  6596. Vec[0] := - (Position.X + 0.5 - HalfSize);
  6597. Vec[1] := - (Position.Y + 0.5 - HalfSize);
  6598. Vec[2] := - HalfSize;
  6599. end;
  6600. procedure glBitmapNormalMapFunc(var FuncRec: TglBitmapFunctionRec);
  6601. var
  6602. Vec : TVec;
  6603. Len: Single;
  6604. begin
  6605. with FuncRec do begin
  6606. with PglBitmapNormalMapRec (CustomData)^ do begin
  6607. Func(Vec, Position, HalfSize);
  6608. // Normalize
  6609. Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
  6610. if Len <> 0 then begin
  6611. Vec[0] := Vec[0] * Len;
  6612. Vec[1] := Vec[1] * Len;
  6613. Vec[2] := Vec[2] * Len;
  6614. end;
  6615. // Scale Vector and AddVectro
  6616. Vec[0] := Vec[0] * 0.5 + 0.5;
  6617. Vec[1] := Vec[1] * 0.5 + 0.5;
  6618. Vec[2] := Vec[2] * 0.5 + 0.5;
  6619. end;
  6620. // Set Color
  6621. Dest.Red := Round(Vec[0] * 255);
  6622. Dest.Green := Round(Vec[1] * 255);
  6623. Dest.Blue := Round(Vec[2] * 255);
  6624. end;
  6625. end;
  6626. procedure TglBitmapNormalMap.AfterConstruction;
  6627. begin
  6628. inherited;
  6629. fGenMode := GL_NORMAL_MAP;
  6630. end;
  6631. procedure TglBitmapNormalMap.GenerateNormalMap(Size: Integer;
  6632. TestTextureSize: Boolean);
  6633. var
  6634. Rec: TglBitmapNormalMapRec;
  6635. SizeRec: TglBitmapPixelPosition;
  6636. begin
  6637. Rec.HalfSize := Size div 2;
  6638. FreeDataAfterGenTexture := false;
  6639. SizeRec.Fields := [ffX, ffY];
  6640. SizeRec.X := Size;
  6641. SizeRec.Y := Size;
  6642. // Positive X
  6643. Rec.Func := glBitmapNormalMapPosX;
  6644. LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
  6645. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X, TestTextureSize);
  6646. // Negative X
  6647. Rec.Func := glBitmapNormalMapNegX;
  6648. LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
  6649. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, TestTextureSize);
  6650. // Positive Y
  6651. Rec.Func := glBitmapNormalMapPosY;
  6652. LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
  6653. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, TestTextureSize);
  6654. // Negative Y
  6655. Rec.Func := glBitmapNormalMapNegY;
  6656. LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
  6657. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, TestTextureSize);
  6658. // Positive Z
  6659. Rec.Func := glBitmapNormalMapPosZ;
  6660. LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
  6661. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, TestTextureSize);
  6662. // Negative Z
  6663. Rec.Func := glBitmapNormalMapNegZ;
  6664. LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
  6665. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, TestTextureSize);
  6666. end;
  6667. *)
  6668. initialization
  6669. glBitmapSetDefaultFormat(tfEmpty);
  6670. glBitmapSetDefaultMipmap(mmMipmap);
  6671. glBitmapSetDefaultFilter(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
  6672. glBitmapSetDefaultWrap (GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
  6673. glBitmapSetDefaultFreeDataAfterGenTexture(true);
  6674. glBitmapSetDefaultDeleteTextureOnFree (true);
  6675. TFormatDescriptor.Init;
  6676. finalization
  6677. TFormatDescriptor.Finalize;
  6678. end.