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

7856 lines
256 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. TbmpBitfieldFormat = 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. TbmpColorTableEnty = packed record
  1202. b, g, r, a: Byte;
  1203. end;
  1204. TbmpColorTable = array of TbmpColorTableEnty;
  1205. TbmpColorTableFormat = class(TFormatDescriptor)
  1206. private
  1207. fColorTable: TbmpColorTable;
  1208. public
  1209. property PixelSize: Single read fPixelSize write fPixelSize;
  1210. property ColorTable: TbmpColorTable read fColorTable write fColorTable;
  1211. property Range: TglBitmapColorRec read fRange write fRange;
  1212. property Shift: TShiftRec read fShift write fShift;
  1213. property Format: TglBitmapFormat read fFormat write fFormat;
  1214. procedure CreateColorTable;
  1215. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1216. procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1217. destructor Destroy; override;
  1218. end;
  1219. const
  1220. LUMINANCE_WEIGHT_R = 0.30;
  1221. LUMINANCE_WEIGHT_G = 0.59;
  1222. LUMINANCE_WEIGHT_B = 0.11;
  1223. ALPHA_WEIGHT_R = 0.30;
  1224. ALPHA_WEIGHT_G = 0.59;
  1225. ALPHA_WEIGHT_B = 0.11;
  1226. DEPTH_WEIGHT_R = 0.333333333;
  1227. DEPTH_WEIGHT_G = 0.333333333;
  1228. DEPTH_WEIGHT_B = 0.333333333;
  1229. UNSUPPORTED_FORMAT = 'the given format isn''t supported by this function.';
  1230. FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
  1231. TfdEmpty,
  1232. TfdAlpha4,
  1233. TfdAlpha8,
  1234. TfdAlpha12,
  1235. TfdAlpha16,
  1236. TfdLuminance4,
  1237. TfdLuminance8,
  1238. TfdLuminance12,
  1239. TfdLuminance16,
  1240. TfdLuminance4Alpha4,
  1241. TfdLuminance6Alpha2,
  1242. TfdLuminance8Alpha8,
  1243. TfdLuminance12Alpha4,
  1244. TfdLuminance12Alpha12,
  1245. TfdLuminance16Alpha16,
  1246. TfdR3G3B2,
  1247. TfdRGB4,
  1248. TfdR5G6B5,
  1249. TfdRGB5,
  1250. TfdRGB8,
  1251. TfdRGB10,
  1252. TfdRGB12,
  1253. TfdRGB16,
  1254. TfdRGBA2,
  1255. TfdRGBA4,
  1256. TfdRGB5A1,
  1257. TfdRGBA8,
  1258. TfdRGB10A2,
  1259. TfdRGBA12,
  1260. TfdRGBA16,
  1261. TfdBGR4,
  1262. TfdB5G6R5,
  1263. TfdBGR5,
  1264. TfdBGR8,
  1265. TfdBGR10,
  1266. TfdBGR12,
  1267. TfdBGR16,
  1268. TfdBGRA2,
  1269. TfdBGRA4,
  1270. TfdBGR5A1,
  1271. TfdBGRA8,
  1272. TfdBGR10A2,
  1273. TfdBGRA12,
  1274. TfdBGRA16,
  1275. TfdDepth16,
  1276. TfdDepth24,
  1277. TfdDepth32
  1278. );
  1279. var
  1280. FormatDescriptorCS: TCriticalSection;
  1281. FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
  1282. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1283. function glBitmapPosition(X, Y: Integer): TglBitmapPixelPosition;
  1284. begin
  1285. result.Fields := [];
  1286. if X >= 0 then
  1287. result.Fields := result.Fields + [ffX];
  1288. if Y >= 0 then
  1289. result.Fields := result.Fields + [ffY];
  1290. result.X := Max(0, X);
  1291. result.Y := Max(0, Y);
  1292. end;
  1293. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1294. function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
  1295. begin
  1296. result.r := r;
  1297. result.g := g;
  1298. result.b := b;
  1299. result.a := a;
  1300. end;
  1301. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1302. function glBitmapShiftRec(const r, g, b, a: Byte): TShiftRec;
  1303. begin
  1304. result.r := r;
  1305. result.g := g;
  1306. result.b := b;
  1307. result.a := a;
  1308. end;
  1309. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1310. function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
  1311. begin
  1312. result := [ftDDS, ftTGA];
  1313. if (aFormat in [
  1314. //4 bbp
  1315. tfLuminance4,
  1316. //8bpp
  1317. tfR3G3B2, tfLuminance8,
  1318. //16bpp
  1319. tfRGB4, tfRGB5, tfR5G6B5, tfRGB5A1, tfRGBA4,
  1320. tfBGR4, tfBGR5, tfB5G6R5, tfBGR5A1, tfBGRA4,
  1321. //24bpp
  1322. tfBGR8, tfRGB8,
  1323. //32bpp
  1324. tfRGB10, tfRGB10A2, tfRGBA8,
  1325. tfBGR10, tfBGR10A2, tfBGRA8]) then
  1326. result := result + [ftBMP];
  1327. //TODO Supported File Formats!
  1328. (*
  1329. {$IFDEF GLB_SUPPORT_PNG_WRITE}
  1330. if aFormat in [
  1331. tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16,
  1332. tfLuminance4, tfLuminance8, tfLuminance12, tfLuminance16,
  1333. tfuminance4Alpha4, tfLuminance6Alpha2, tfLuminance8Alpha8, tfLuminance12Alpha4, tfLuminance12Alpha12, tfLuminance16Alpha16,
  1334. tfR3G3B2, tfRGB4, tfRGB5, tfRGB8, tfRGB10, tfRGB12, tfRGB16,
  1335. tfRGBA2, tfRGBA4, tfRGB5A1, tfRGBA8, tfRGB10A2, tfRGBA12, tfRGBA16,
  1336. tfDepth16, tfDepth24, tfDepth32]
  1337. then
  1338. result := result + [ftPNG];
  1339. {$ENDIF}
  1340. {$IFDEF GLB_SUPPORT_JPEG_WRITE}
  1341. if Format in [
  1342. tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16,
  1343. tfLuminance4, tfLuminance8, tfLuminance12, tfLuminance16,
  1344. tfR3G3B2, tfRGB4, tfRGB5, tfRGB8, tfRGB10, tfRGB12, tfRGB16,
  1345. tfDepth16, tfDepth24, tfDepth32]
  1346. then
  1347. result := result + [ftJPEG];
  1348. {$ENDIF}
  1349. if aFormat in [
  1350. tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16,
  1351. tfLuminance4, tfLuminance8, tfLuminance12, tfLuminance16,
  1352. tfuminance4Alpha4, tfLuminance6Alpha2, tfLuminance8Alpha8, tfLuminance12Alpha4, tfLuminance12Alpha12, tfLuminance16Alpha16,
  1353. tfR3G3B2, tfRGB4, tfRGB5, tfRGB8, tfRGB10, tfRGB12, tfRGB16,
  1354. tfRGBA2, tfRGBA4, tfRGB5A1, tfRGBA8, tfRGB10A2, tfRGBA12, tfRGBA16,
  1355. tfDepth16, tfDepth24, tfDepth32]
  1356. then
  1357. result := result + [ftDDS, ftTGA, ftBMP];
  1358. *)
  1359. end;
  1360. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1361. function IsPowerOfTwo(aNumber: Integer): Boolean;
  1362. begin
  1363. while (aNumber and 1) = 0 do
  1364. aNumber := aNumber shr 1;
  1365. result := aNumber = 1;
  1366. end;
  1367. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1368. function GetTopMostBit(aBitSet: UInt64): Integer;
  1369. begin
  1370. result := 0;
  1371. while aBitSet > 0 do begin
  1372. inc(result);
  1373. aBitSet := aBitSet shr 1;
  1374. end;
  1375. end;
  1376. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1377. function CountSetBits(aBitSet: UInt64): Integer;
  1378. begin
  1379. result := 0;
  1380. while aBitSet > 0 do begin
  1381. if (aBitSet and 1) = 1 then
  1382. inc(result);
  1383. aBitSet := aBitSet shr 1;
  1384. end;
  1385. end;
  1386. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1387. function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
  1388. begin
  1389. result := Trunc(
  1390. LUMINANCE_WEIGHT_R * aPixel.Data.r +
  1391. LUMINANCE_WEIGHT_G * aPixel.Data.g +
  1392. LUMINANCE_WEIGHT_B * aPixel.Data.b);
  1393. end;
  1394. function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
  1395. begin
  1396. result := Trunc(
  1397. DEPTH_WEIGHT_R * aPixel.Data.r +
  1398. DEPTH_WEIGHT_G * aPixel.Data.g +
  1399. DEPTH_WEIGHT_B * aPixel.Data.b);
  1400. end;
  1401. //TODO check _ARB functions and constants
  1402. (* GLB_NO_NATIVE_GL
  1403. {$IFNDEF GLB_NO_NATIVE_GL}
  1404. procedure ReadOpenGLExtensions;
  1405. var
  1406. {$IFDEF GLB_DELPHI}
  1407. Context: HGLRC;
  1408. {$ENDIF}
  1409. Buffer: AnsiString;
  1410. MajorVersion, MinorVersion: Integer;
  1411. procedure TrimVersionString(Buffer: AnsiString; var Major, Minor: Integer);
  1412. var
  1413. Separator: Integer;
  1414. begin
  1415. Minor := 0;
  1416. Major := 0;
  1417. Separator := Pos(AnsiString('.'), Buffer);
  1418. if (Separator > 1) and (Separator < Length(Buffer)) and
  1419. (Buffer[Separator - 1] in ['0'..'9']) and
  1420. (Buffer[Separator + 1] in ['0'..'9']) then begin
  1421. Dec(Separator);
  1422. while (Separator > 0) and (Buffer[Separator] in ['0'..'9']) do
  1423. Dec(Separator);
  1424. Delete(Buffer, 1, Separator);
  1425. Separator := Pos(AnsiString('.'), Buffer) + 1;
  1426. while (Separator <= Length(Buffer)) and (AnsiChar(Buffer[Separator]) in ['0'..'9']) do
  1427. Inc(Separator);
  1428. Delete(Buffer, Separator, 255);
  1429. Separator := Pos(AnsiString('.'), Buffer);
  1430. Major := StrToInt(Copy(String(Buffer), 1, Separator - 1));
  1431. Minor := StrToInt(Copy(String(Buffer), Separator + 1, 1));
  1432. end;
  1433. end;
  1434. function CheckExtension(const Extension: AnsiString): Boolean;
  1435. var
  1436. ExtPos: Integer;
  1437. begin
  1438. ExtPos := Pos(Extension, Buffer);
  1439. result := ExtPos > 0;
  1440. if result then
  1441. result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
  1442. end;
  1443. function glLoad (aFunc: pAnsiChar): pointer;
  1444. begin
  1445. {$IFDEF LINUX}
  1446. result := glXGetProcAddress(aFunc);
  1447. {$else}
  1448. result := wglGetProcAddress(aFunc);
  1449. {$ENDIF}
  1450. end;
  1451. begin
  1452. {$IFDEF GLB_DELPHI}
  1453. Context := wglGetCurrentContext;
  1454. if Context <> gLastContext then begin
  1455. gLastContext := Context;
  1456. {$ENDIF}
  1457. // Version
  1458. Buffer := glGetString(GL_VERSION);
  1459. TrimVersionString(Buffer, MajorVersion, MinorVersion);
  1460. GL_VERSION_1_2 := false;
  1461. GL_VERSION_1_3 := false;
  1462. GL_VERSION_1_4 := false;
  1463. GL_VERSION_2_0 := false;
  1464. if MajorVersion = 1 then begin
  1465. if MinorVersion >= 1 then begin
  1466. if MinorVersion >= 2 then
  1467. GL_VERSION_1_2 := true;
  1468. if MinorVersion >= 3 then
  1469. GL_VERSION_1_3 := true;
  1470. if MinorVersion >= 4 then
  1471. GL_VERSION_1_4 := true;
  1472. end;
  1473. end;
  1474. if MajorVersion >= 2 then begin
  1475. GL_VERSION_1_2 := true;
  1476. GL_VERSION_1_3 := true;
  1477. GL_VERSION_1_4 := true;
  1478. GL_VERSION_2_0 := true;
  1479. end;
  1480. // Extensions
  1481. Buffer := glGetString(GL_EXTENSIONS);
  1482. GL_ARB_texture_border_clamp := CheckExtension('GL_ARB_texture_border_clamp');
  1483. GL_ARB_texture_cube_map := CheckExtension('GL_ARB_texture_cube_map');
  1484. GL_ARB_texture_compression := CheckExtension('GL_ARB_texture_compression');
  1485. GL_ARB_texture_non_power_of_two := CheckExtension('GL_ARB_texture_non_power_of_two');
  1486. GL_ARB_texture_rectangle := CheckExtension('GL_ARB_texture_rectangle');
  1487. GL_ARB_texture_mirrored_repeat := CheckExtension('GL_ARB_texture_mirrored_repeat');
  1488. GL_EXT_bgra := CheckExtension('GL_EXT_bgra');
  1489. GL_EXT_texture_edge_clamp := CheckExtension('GL_EXT_texture_edge_clamp');
  1490. GL_EXT_texture_cube_map := CheckExtension('GL_EXT_texture_cube_map');
  1491. GL_EXT_texture_compression_s3tc := CheckExtension('GL_EXT_texture_compression_s3tc');
  1492. GL_EXT_texture_filter_anisotropic := CheckExtension('GL_EXT_texture_filter_anisotropic');
  1493. GL_EXT_texture_rectangle := CheckExtension('GL_EXT_texture_rectangle');
  1494. GL_NV_texture_rectangle := CheckExtension('GL_NV_texture_rectangle');
  1495. GL_IBM_texture_mirrored_repeat := CheckExtension('GL_IBM_texture_mirrored_repeat');
  1496. GL_SGIS_generate_mipmap := CheckExtension('GL_SGIS_generate_mipmap');
  1497. // Funtions
  1498. if GL_VERSION_1_3 then begin
  1499. // Loading Core
  1500. glCompressedTexImage1D := glLoad('glCompressedTexImage1D');
  1501. glCompressedTexImage2D := glLoad('glCompressedTexImage2D');
  1502. glGetCompressedTexImage := glLoad('glGetCompressedTexImage');
  1503. end else
  1504. begin
  1505. // Try loading Extension
  1506. glCompressedTexImage1D := glLoad('glCompressedTexImage1DARB');
  1507. glCompressedTexImage2D := glLoad('glCompressedTexImage2DARB');
  1508. glGetCompressedTexImage := glLoad('glGetCompressedTexImageARB');
  1509. end;
  1510. {$IFDEF GLB_DELPHI}
  1511. end;
  1512. {$ENDIF}
  1513. end;
  1514. {$ENDIF}
  1515. *)
  1516. (* TODO GLB_DELPHI
  1517. {$IFDEF GLB_DELPHI}
  1518. function CreateGrayPalette: HPALETTE;
  1519. var
  1520. Idx: Integer;
  1521. Pal: PLogPalette;
  1522. begin
  1523. GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
  1524. Pal.palVersion := $300;
  1525. Pal.palNumEntries := 256;
  1526. {$IFOPT R+}
  1527. {$DEFINE GLB_TEMPRANGECHECK}
  1528. {$R-}
  1529. {$ENDIF}
  1530. for Idx := 0 to 256 - 1 do begin
  1531. Pal.palPalEntry[Idx].peRed := Idx;
  1532. Pal.palPalEntry[Idx].peGreen := Idx;
  1533. Pal.palPalEntry[Idx].peBlue := Idx;
  1534. Pal.palPalEntry[Idx].peFlags := 0;
  1535. end;
  1536. {$IFDEF GLB_TEMPRANGECHECK}
  1537. {$UNDEF GLB_TEMPRANGECHECK}
  1538. {$R+}
  1539. {$ENDIF}
  1540. result := CreatePalette(Pal^);
  1541. FreeMem(Pal);
  1542. end;
  1543. {$ENDIF}
  1544. *)
  1545. (* TODO GLB_SDL_IMAGE
  1546. {$IFDEF GLB_SDL_IMAGE}
  1547. function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
  1548. begin
  1549. result := TStream(context^.unknown.data1).Seek(offset, whence);
  1550. end;
  1551. function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
  1552. begin
  1553. result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
  1554. end;
  1555. function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
  1556. begin
  1557. result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
  1558. end;
  1559. function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
  1560. begin
  1561. result := 0;
  1562. end;
  1563. function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
  1564. begin
  1565. result := SDL_AllocRW;
  1566. if result = nil then
  1567. raise EglBitmapException.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
  1568. result^.seek := glBitmapRWseek;
  1569. result^.read := glBitmapRWread;
  1570. result^.write := glBitmapRWwrite;
  1571. result^.close := glBitmapRWclose;
  1572. result^.unknown.data1 := Stream;
  1573. end;
  1574. {$ENDIF}
  1575. *)
  1576. (* TODO LoadFuncs
  1577. function LoadTexture(Filename: String; var Texture: Cardinal{$IFDEF GLB_DELPHI}; LoadFromRes : Boolean; Instance: Cardinal{$ENDIF}): Boolean;
  1578. var
  1579. glBitmap: TglBitmap2D;
  1580. begin
  1581. result := false;
  1582. Texture := 0;
  1583. {$IFDEF GLB_DELPHI}
  1584. if Instance = 0 then
  1585. Instance := HInstance;
  1586. if (LoadFromRes) then
  1587. glBitmap := TglBitmap2D.CreateFromResourceName(Instance, FileName)
  1588. else
  1589. {$ENDIF}
  1590. glBitmap := TglBitmap2D.Create(FileName);
  1591. try
  1592. glBitmap.DeleteTextureOnFree := false;
  1593. glBitmap.FreeDataAfterGenTexture := false;
  1594. glBitmap.GenTexture(true);
  1595. if (glBitmap.ID > 0) then begin
  1596. Texture := glBitmap.ID;
  1597. result := true;
  1598. end;
  1599. finally
  1600. glBitmap.Free;
  1601. end;
  1602. end;
  1603. function LoadCubeMap(PositiveX, NegativeX, PositiveY, NegativeY, PositiveZ, NegativeZ: String; var Texture: Cardinal{$IFDEF GLB_DELPHI}; LoadFromRes : Boolean; Instance: Cardinal{$ENDIF}): Boolean;
  1604. var
  1605. CM: TglBitmapCubeMap;
  1606. begin
  1607. Texture := 0;
  1608. {$IFDEF GLB_DELPHI}
  1609. if Instance = 0 then
  1610. Instance := HInstance;
  1611. {$ENDIF}
  1612. CM := TglBitmapCubeMap.Create;
  1613. try
  1614. CM.DeleteTextureOnFree := false;
  1615. // Maps
  1616. {$IFDEF GLB_DELPHI}
  1617. if (LoadFromRes) then
  1618. CM.LoadFromResource(Instance, PositiveX)
  1619. else
  1620. {$ENDIF}
  1621. CM.LoadFromFile(PositiveX);
  1622. CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X);
  1623. {$IFDEF GLB_DELPHI}
  1624. if (LoadFromRes) then
  1625. CM.LoadFromResource(Instance, NegativeX)
  1626. else
  1627. {$ENDIF}
  1628. CM.LoadFromFile(NegativeX);
  1629. CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X);
  1630. {$IFDEF GLB_DELPHI}
  1631. if (LoadFromRes) then
  1632. CM.LoadFromResource(Instance, PositiveY)
  1633. else
  1634. {$ENDIF}
  1635. CM.LoadFromFile(PositiveY);
  1636. CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y);
  1637. {$IFDEF GLB_DELPHI}
  1638. if (LoadFromRes) then
  1639. CM.LoadFromResource(Instance, NegativeY)
  1640. else
  1641. {$ENDIF}
  1642. CM.LoadFromFile(NegativeY);
  1643. CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
  1644. {$IFDEF GLB_DELPHI}
  1645. if (LoadFromRes) then
  1646. CM.LoadFromResource(Instance, PositiveZ)
  1647. else
  1648. {$ENDIF}
  1649. CM.LoadFromFile(PositiveZ);
  1650. CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
  1651. {$IFDEF GLB_DELPHI}
  1652. if (LoadFromRes) then
  1653. CM.LoadFromResource(Instance, NegativeZ)
  1654. else
  1655. {$ENDIF}
  1656. CM.LoadFromFile(NegativeZ);
  1657. CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
  1658. Texture := CM.ID;
  1659. result := true;
  1660. finally
  1661. CM.Free;
  1662. end;
  1663. end;
  1664. function LoadNormalMap(Size: Integer; var Texture: Cardinal): Boolean;
  1665. var
  1666. NM: TglBitmapNormalMap;
  1667. begin
  1668. Texture := 0;
  1669. NM := TglBitmapNormalMap.Create;
  1670. try
  1671. NM.DeleteTextureOnFree := false;
  1672. NM.GenerateNormalMap(Size);
  1673. Texture := NM.ID;
  1674. result := true;
  1675. finally
  1676. NM.Free;
  1677. end;
  1678. end;
  1679. *)
  1680. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1681. procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
  1682. begin
  1683. glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
  1684. end;
  1685. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1686. procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
  1687. begin
  1688. glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
  1689. end;
  1690. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1691. procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
  1692. begin
  1693. glBitmapDefaultMipmap := aValue;
  1694. end;
  1695. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1696. procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
  1697. begin
  1698. glBitmapDefaultFormat := aFormat;
  1699. end;
  1700. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1701. procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
  1702. begin
  1703. glBitmapDefaultFilterMin := aMin;
  1704. glBitmapDefaultFilterMag := aMag;
  1705. end;
  1706. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1707. procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
  1708. begin
  1709. glBitmapDefaultWrapS := S;
  1710. glBitmapDefaultWrapT := T;
  1711. glBitmapDefaultWrapR := R;
  1712. end;
  1713. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1714. function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
  1715. begin
  1716. result := glBitmapDefaultDeleteTextureOnFree;
  1717. end;
  1718. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1719. function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
  1720. begin
  1721. result := glBitmapDefaultFreeDataAfterGenTextures;
  1722. end;
  1723. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1724. function glBitmapGetDefaultMipmap: TglBitmapMipMap;
  1725. begin
  1726. result := glBitmapDefaultMipmap;
  1727. end;
  1728. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1729. function glBitmapGetDefaultFormat: TglBitmapFormat;
  1730. begin
  1731. result := glBitmapDefaultFormat;
  1732. end;
  1733. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1734. procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
  1735. begin
  1736. aMin := glBitmapDefaultFilterMin;
  1737. aMag := glBitmapDefaultFilterMag;
  1738. end;
  1739. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1740. procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
  1741. begin
  1742. S := glBitmapDefaultWrapS;
  1743. T := glBitmapDefaultWrapT;
  1744. R := glBitmapDefaultWrapR;
  1745. end;
  1746. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1747. //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1748. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1749. function TFormatDescriptor.GetRedMask: UInt64;
  1750. begin
  1751. result := fRange.r shl fShift.r;
  1752. end;
  1753. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1754. function TFormatDescriptor.GetGreenMask: UInt64;
  1755. begin
  1756. result := fRange.g shl fShift.g;
  1757. end;
  1758. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1759. function TFormatDescriptor.GetBlueMask: UInt64;
  1760. begin
  1761. result := fRange.b shl fShift.b;
  1762. end;
  1763. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1764. function TFormatDescriptor.GetAlphaMask: UInt64;
  1765. begin
  1766. result := fRange.a shl fShift.a;
  1767. end;
  1768. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1769. function TFormatDescriptor.GetComponents: Integer;
  1770. var
  1771. i: Integer;
  1772. begin
  1773. result := 0;
  1774. for i := 0 to 3 do
  1775. if (fRange.arr[i] > 0) then
  1776. inc(result);
  1777. end;
  1778. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1779. function TFormatDescriptor.GetSize(const aSize: TglBitmapPixelPosition): Integer;
  1780. var
  1781. w, h: Integer;
  1782. begin
  1783. if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
  1784. w := Max(1, aSize.X);
  1785. h := Max(1, aSize.Y);
  1786. result := GetSize(w, h);
  1787. end else
  1788. result := 0;
  1789. end;
  1790. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1791. function TFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer;
  1792. begin
  1793. result := 0;
  1794. if (aWidth <= 0) or (aHeight <= 0) then
  1795. exit;
  1796. result := Ceil(aWidth * aHeight * fPixelSize);
  1797. end;
  1798. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1799. function TFormatDescriptor.CreateMappingData: Pointer;
  1800. begin
  1801. result := nil;
  1802. end;
  1803. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1804. procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
  1805. begin
  1806. //DUMMY
  1807. end;
  1808. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1809. function TFormatDescriptor.IsEmpty: Boolean;
  1810. begin
  1811. result := (fFormat = tfEmpty);
  1812. end;
  1813. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1814. function TFormatDescriptor.HasAlpha: Boolean;
  1815. begin
  1816. result := (fRange.a > 0);
  1817. end;
  1818. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1819. function TFormatDescriptor.MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: UInt64): Boolean;
  1820. begin
  1821. result := false;
  1822. if (aRedMask = 0) and (aGreenMask = 0) and (aBlueMask = 0) and (aAlphaMask = 0) then
  1823. raise EglBitmapException.Create('FormatCheckFormat - All Masks are 0');
  1824. if (aRedMask <> RedMask) then
  1825. exit;
  1826. if (aGreenMask <> GreenMask) then
  1827. exit;
  1828. if (aBlueMask <> BlueMask) then
  1829. exit;
  1830. if (aAlphaMask <> AlphaMask) then
  1831. exit;
  1832. result := true;
  1833. end;
  1834. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1835. procedure TFormatDescriptor.PreparePixel(var aPixel: TglBitmapPixelData);
  1836. begin
  1837. FillChar(aPixel, SizeOf(aPixel), 0);
  1838. aPixel.Data := fRange;
  1839. aPixel.Range := fRange;
  1840. aPixel.Format := fFormat;
  1841. end;
  1842. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1843. constructor TFormatDescriptor.Create;
  1844. begin
  1845. inherited Create;
  1846. fFormat := tfEmpty;
  1847. fWithAlpha := tfEmpty;
  1848. fWithoutAlpha := tfEmpty;
  1849. fPixelSize := 0.0;
  1850. fglFormat := 0;
  1851. fglInternalFormat := 0;
  1852. fglDataFormat := 0;
  1853. FillChar(fRange, 0, SizeOf(fRange));
  1854. FillChar(fShift, 0, SizeOf(fShift));
  1855. end;
  1856. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1857. //TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1858. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1859. procedure TfdAlpha_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  1860. begin
  1861. aData^ := aPixel.Data.a;
  1862. inc(aData);
  1863. end;
  1864. procedure TfdAlpha_UB1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  1865. begin
  1866. aPixel.Data.r := 0;
  1867. aPixel.Data.g := 0;
  1868. aPixel.Data.b := 0;
  1869. aPixel.Data.a := aData^;
  1870. inc(aData^);
  1871. end;
  1872. constructor TfdAlpha_UB1.Create;
  1873. begin
  1874. inherited Create;
  1875. fPixelSize := 1.0;
  1876. fRange.a := $FF;
  1877. fglFormat := GL_ALPHA;
  1878. fglDataFormat := GL_UNSIGNED_BYTE;
  1879. end;
  1880. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1881. //TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1882. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1883. procedure TfdLuminance_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  1884. begin
  1885. aData^ := LuminanceWeight(aPixel);
  1886. inc(aData);
  1887. end;
  1888. procedure TfdLuminance_UB1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  1889. begin
  1890. aPixel.Data.r := aData^;
  1891. aPixel.Data.g := aData^;
  1892. aPixel.Data.b := aData^;
  1893. aPixel.Data.a := 0;
  1894. inc(aData);
  1895. end;
  1896. constructor TfdLuminance_UB1.Create;
  1897. begin
  1898. inherited Create;
  1899. fPixelSize := 1.0;
  1900. fRange.r := $FF;
  1901. fRange.g := $FF;
  1902. fRange.b := $FF;
  1903. fglFormat := GL_LUMINANCE;
  1904. fglDataFormat := GL_UNSIGNED_BYTE;
  1905. end;
  1906. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1907. //TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1908. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1909. procedure TfdUniversal_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  1910. var
  1911. i: Integer;
  1912. begin
  1913. aData^ := 0;
  1914. for i := 0 to 3 do
  1915. if (fRange.arr[i] > 0) then
  1916. aData^ := aData^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
  1917. inc(aData);
  1918. end;
  1919. procedure TfdUniversal_UB1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  1920. var
  1921. i: Integer;
  1922. begin
  1923. for i := 0 to 3 do
  1924. aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and fRange.arr[i];
  1925. inc(aData);
  1926. end;
  1927. constructor TfdUniversal_UB1.Create;
  1928. begin
  1929. inherited Create;
  1930. fPixelSize := 1.0;
  1931. end;
  1932. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1933. //TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1934. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1935. procedure TfdLuminanceAlpha_UB2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  1936. begin
  1937. inherited Map(aPixel, aData, aMapData);
  1938. aData^ := aPixel.Data.a;
  1939. inc(aData);
  1940. end;
  1941. procedure TfdLuminanceAlpha_UB2.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  1942. begin
  1943. inherited Unmap(aData, aPixel, aMapData);
  1944. aPixel.Data.a := aData^;
  1945. inc(aData);
  1946. end;
  1947. constructor TfdLuminanceAlpha_UB2.Create;
  1948. begin
  1949. inherited Create;
  1950. fPixelSize := 2.0;
  1951. fRange.a := $FF;
  1952. fShift.a := 8;
  1953. fglFormat := GL_LUMINANCE_ALPHA;
  1954. fglDataFormat := GL_UNSIGNED_BYTE;
  1955. end;
  1956. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1957. //TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1958. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1959. procedure TfdRGB_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  1960. begin
  1961. aData^ := aPixel.Data.r;
  1962. inc(aData);
  1963. aData^ := aPixel.Data.g;
  1964. inc(aData);
  1965. aData^ := aPixel.Data.b;
  1966. inc(aData);
  1967. end;
  1968. procedure TfdRGB_UB3.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  1969. begin
  1970. aPixel.Data.r := aData^;
  1971. inc(aData);
  1972. aPixel.Data.g := aData^;
  1973. inc(aData);
  1974. aPixel.Data.b := aData^;
  1975. inc(aData);
  1976. aPixel.Data.a := 0;
  1977. end;
  1978. constructor TfdRGB_UB3.Create;
  1979. begin
  1980. inherited Create;
  1981. fPixelSize := 3.0;
  1982. fRange.r := $FF;
  1983. fRange.g := $FF;
  1984. fRange.b := $FF;
  1985. fShift.r := 0;
  1986. fShift.g := 8;
  1987. fShift.b := 16;
  1988. fglFormat := GL_RGB;
  1989. fglDataFormat := GL_UNSIGNED_BYTE;
  1990. end;
  1991. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1992. //TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1993. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1994. procedure TfdBGR_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  1995. begin
  1996. aData^ := aPixel.Data.b;
  1997. inc(aData);
  1998. aData^ := aPixel.Data.g;
  1999. inc(aData);
  2000. aData^ := aPixel.Data.r;
  2001. inc(aData);
  2002. end;
  2003. procedure TfdBGR_UB3.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2004. begin
  2005. aPixel.Data.b := aData^;
  2006. inc(aData);
  2007. aPixel.Data.g := aData^;
  2008. inc(aData);
  2009. aPixel.Data.r := aData^;
  2010. inc(aData);
  2011. aPixel.Data.a := 0;
  2012. end;
  2013. constructor TfdBGR_UB3.Create;
  2014. begin
  2015. fPixelSize := 3.0;
  2016. fRange.r := $FF;
  2017. fRange.g := $FF;
  2018. fRange.b := $FF;
  2019. fShift.r := 16;
  2020. fShift.g := 8;
  2021. fShift.b := 0;
  2022. fglFormat := GL_BGR;
  2023. fglDataFormat := GL_UNSIGNED_BYTE;
  2024. end;
  2025. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2026. //TdfRGBA_UB4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2027. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2028. procedure TfdRGBA_UB4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2029. begin
  2030. inherited Map(aPixel, aData, aMapData);
  2031. aData^ := aPixel.Data.a;
  2032. inc(aData);
  2033. end;
  2034. procedure TfdRGBA_UB4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2035. begin
  2036. inherited Unmap(aData, aPixel, aMapData);
  2037. aPixel.Data.a := aData^;
  2038. inc(aData);
  2039. end;
  2040. constructor TfdRGBA_UB4.Create;
  2041. begin
  2042. inherited Create;
  2043. fPixelSize := 4.0;
  2044. fRange.a := $FF;
  2045. fShift.a := 24;
  2046. fglFormat := GL_RGBA;
  2047. fglDataFormat := GL_UNSIGNED_BYTE;
  2048. end;
  2049. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2050. //TfdBGRA_UB4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2051. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2052. procedure TfdBGRA_UB4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2053. begin
  2054. inherited Map(aPixel, aData, aMapData);
  2055. aData^ := aPixel.Data.a;
  2056. inc(aData);
  2057. end;
  2058. procedure TfdBGRA_UB4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2059. begin
  2060. inherited Unmap(aData, aPixel, aMapData);
  2061. aPixel.Data.a := aData^;
  2062. inc(aData);
  2063. end;
  2064. constructor TfdBGRA_UB4.Create;
  2065. begin
  2066. inherited Create;
  2067. fPixelSize := 4.0;
  2068. fRange.a := $FF;
  2069. fShift.a := 24;
  2070. fglFormat := GL_BGRA;
  2071. fglDataFormat := GL_UNSIGNED_BYTE;
  2072. end;
  2073. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2074. //TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2075. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2076. procedure TfdAlpha_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2077. begin
  2078. PWord(aData)^ := aPixel.Data.a;
  2079. inc(aData, 2);
  2080. end;
  2081. procedure TfdAlpha_US1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2082. begin
  2083. aPixel.Data.r := 0;
  2084. aPixel.Data.g := 0;
  2085. aPixel.Data.b := 0;
  2086. aPixel.Data.a := PWord(aData)^;
  2087. inc(aData, 2);
  2088. end;
  2089. constructor TfdAlpha_US1.Create;
  2090. begin
  2091. inherited Create;
  2092. fPixelSize := 2.0;
  2093. fRange.a := $FFFF;
  2094. fglFormat := GL_ALPHA;
  2095. fglDataFormat := GL_UNSIGNED_SHORT;
  2096. end;
  2097. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2098. //TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2099. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2100. procedure TfdLuminance_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2101. begin
  2102. PWord(aData)^ := LuminanceWeight(aPixel);
  2103. inc(aData, 2);
  2104. end;
  2105. procedure TfdLuminance_US1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2106. begin
  2107. aPixel.Data.r := PWord(aData)^;
  2108. aPixel.Data.g := PWord(aData)^;
  2109. aPixel.Data.b := PWord(aData)^;
  2110. aPixel.Data.a := 0;
  2111. inc(aData, 2);
  2112. end;
  2113. constructor TfdLuminance_US1.Create;
  2114. begin
  2115. inherited Create;
  2116. fPixelSize := 2.0;
  2117. fRange.r := $FFFF;
  2118. fRange.g := $FFFF;
  2119. fRange.b := $FFFF;
  2120. fglFormat := GL_LUMINANCE;
  2121. fglDataFormat := GL_UNSIGNED_SHORT;
  2122. end;
  2123. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2124. //TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2125. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2126. procedure TfdUniversal_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2127. var
  2128. i: Integer;
  2129. begin
  2130. PWord(aData)^ := 0;
  2131. for i := 0 to 3 do
  2132. if (fRange.arr[i] > 0) then
  2133. PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
  2134. inc(aData, 2);
  2135. end;
  2136. procedure TfdUniversal_US1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2137. var
  2138. i: Integer;
  2139. begin
  2140. for i := 0 to 3 do
  2141. aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and fRange.arr[i];
  2142. inc(aData, 2);
  2143. end;
  2144. constructor TfdUniversal_US1.Create;
  2145. begin
  2146. inherited Create;
  2147. fPixelSize := 2.0;
  2148. end;
  2149. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2150. //TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2151. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2152. procedure TfdDepth_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2153. begin
  2154. PWord(aData)^ := DepthWeight(aPixel);
  2155. inc(aData, 2);
  2156. end;
  2157. procedure TfdDepth_US1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2158. begin
  2159. aPixel.Data.r := PWord(aData)^;
  2160. aPixel.Data.g := PWord(aData)^;
  2161. aPixel.Data.b := PWord(aData)^;
  2162. aPixel.Data.a := 0;
  2163. inc(aData, 2);
  2164. end;
  2165. constructor TfdDepth_US1.Create;
  2166. begin
  2167. inherited Create;
  2168. fPixelSize := 2.0;
  2169. fRange.r := $FFFF;
  2170. fRange.g := $FFFF;
  2171. fRange.b := $FFFF;
  2172. fglFormat := GL_DEPTH_COMPONENT;
  2173. fglDataFormat := GL_UNSIGNED_SHORT;
  2174. end;
  2175. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2176. //TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2177. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2178. procedure TfdLuminanceAlpha_US2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2179. begin
  2180. inherited Map(aPixel, aData, aMapData);
  2181. PWord(aData)^ := aPixel.Data.a;
  2182. inc(aData, 2);
  2183. end;
  2184. procedure TfdLuminanceAlpha_US2.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2185. begin
  2186. inherited Unmap(aData, aPixel, aMapData);
  2187. aPixel.Data.a := PWord(aData)^;
  2188. inc(aData, 2);
  2189. end;
  2190. constructor TfdLuminanceAlpha_US2.Create;
  2191. begin
  2192. inherited Create;
  2193. fPixelSize := 4.0;
  2194. fRange.a := $FFFF;
  2195. fShift.a := 16;
  2196. fglFormat := GL_LUMINANCE_ALPHA;
  2197. fglDataFormat := GL_UNSIGNED_SHORT;
  2198. end;
  2199. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2200. //TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2201. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2202. procedure TfdRGB_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2203. begin
  2204. PWord(aData)^ := aPixel.Data.r;
  2205. inc(aData, 2);
  2206. PWord(aData)^ := aPixel.Data.g;
  2207. inc(aData, 2);
  2208. PWord(aData)^ := aPixel.Data.b;
  2209. inc(aData, 2);
  2210. end;
  2211. procedure TfdRGB_US3.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2212. begin
  2213. aPixel.Data.r := PWord(aData)^;
  2214. inc(aData, 2);
  2215. aPixel.Data.g := PWord(aData)^;
  2216. inc(aData, 2);
  2217. aPixel.Data.b := PWord(aData)^;
  2218. inc(aData, 2);
  2219. aPixel.Data.a := 0;
  2220. end;
  2221. constructor TfdRGB_US3.Create;
  2222. begin
  2223. inherited Create;
  2224. fPixelSize := 6.0;
  2225. fRange.r := $FFFF;
  2226. fRange.g := $FFFF;
  2227. fRange.b := $FFFF;
  2228. fShift.r := 0;
  2229. fShift.g := 16;
  2230. fShift.b := 32;
  2231. fglFormat := GL_RGB;
  2232. fglDataFormat := GL_UNSIGNED_SHORT;
  2233. end;
  2234. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2235. //TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2236. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2237. procedure TfdBGR_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2238. begin
  2239. PWord(aData)^ := aPixel.Data.b;
  2240. inc(aData, 2);
  2241. PWord(aData)^ := aPixel.Data.g;
  2242. inc(aData, 2);
  2243. PWord(aData)^ := aPixel.Data.r;
  2244. inc(aData, 2);
  2245. end;
  2246. procedure TfdBGR_US3.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2247. begin
  2248. aPixel.Data.b := PWord(aData)^;
  2249. inc(aData, 2);
  2250. aPixel.Data.g := PWord(aData)^;
  2251. inc(aData, 2);
  2252. aPixel.Data.r := PWord(aData)^;
  2253. inc(aData, 2);
  2254. aPixel.Data.a := 0;
  2255. end;
  2256. constructor TfdBGR_US3.Create;
  2257. begin
  2258. inherited Create;
  2259. fPixelSize := 6.0;
  2260. fRange.r := $FFFF;
  2261. fRange.g := $FFFF;
  2262. fRange.b := $FFFF;
  2263. fShift.r := 32;
  2264. fShift.g := 16;
  2265. fShift.b := 0;
  2266. fglFormat := GL_BGR;
  2267. fglDataFormat := GL_UNSIGNED_SHORT;
  2268. end;
  2269. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2270. //TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2271. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2272. procedure TfdRGBA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2273. begin
  2274. inherited Map(aPixel, aData, aMapData);
  2275. PWord(aData)^ := aPixel.Data.a;
  2276. inc(aData, 2);
  2277. end;
  2278. procedure TfdRGBA_US4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2279. begin
  2280. inherited Unmap(aData, aPixel, aMapData);
  2281. aPixel.Data.a := PWord(aData)^;
  2282. inc(aData, 2);
  2283. end;
  2284. constructor TfdRGBA_US4.Create;
  2285. begin
  2286. inherited Create;
  2287. fPixelSize := 8.0;
  2288. fRange.a := $FFFF;
  2289. fShift.a := 48;
  2290. fglFormat := GL_RGBA;
  2291. fglDataFormat := GL_UNSIGNED_SHORT;
  2292. end;
  2293. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2294. //TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2295. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2296. procedure TfdBGRA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2297. begin
  2298. inherited Map(aPixel, aData, aMapData);
  2299. PWord(aData)^ := aPixel.Data.a;
  2300. inc(aData, 2);
  2301. end;
  2302. procedure TfdBGRA_US4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2303. begin
  2304. inherited Unmap(aData, aPixel, aMapData);
  2305. aPixel.Data.a := PWord(aData)^;
  2306. inc(aData, 2);
  2307. end;
  2308. constructor TfdBGRA_US4.Create;
  2309. begin
  2310. inherited Create;
  2311. fPixelSize := 8.0;
  2312. fRange.a := $FFFF;
  2313. fShift.a := 48;
  2314. fglFormat := GL_BGRA;
  2315. fglDataFormat := GL_UNSIGNED_SHORT;
  2316. end;
  2317. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2318. //TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2319. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2320. procedure TfdUniversal_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2321. var
  2322. i: Integer;
  2323. begin
  2324. PCardinal(aData)^ := 0;
  2325. for i := 0 to 3 do
  2326. if (fRange.arr[i] > 0) then
  2327. PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
  2328. inc(aData, 4);
  2329. end;
  2330. procedure TfdUniversal_UI1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2331. var
  2332. i: Integer;
  2333. begin
  2334. for i := 0 to 3 do
  2335. aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and fRange.arr[i];
  2336. inc(aData, 2);
  2337. end;
  2338. constructor TfdUniversal_UI1.Create;
  2339. begin
  2340. inherited Create;
  2341. fPixelSize := 4.0;
  2342. end;
  2343. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2344. //TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2345. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2346. procedure TfdDepth_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2347. begin
  2348. PCardinal(aData)^ := DepthWeight(aPixel);
  2349. inc(aData, 4);
  2350. end;
  2351. procedure TfdDepth_UI1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2352. begin
  2353. aPixel.Data.r := PCardinal(aData)^;
  2354. aPixel.Data.g := PCardinal(aData)^;
  2355. aPixel.Data.b := PCardinal(aData)^;
  2356. aPixel.Data.a := 0;
  2357. inc(aData, 4);
  2358. end;
  2359. constructor TfdDepth_UI1.Create;
  2360. begin
  2361. inherited Create;
  2362. fPixelSize := 4.0;
  2363. fRange.r := $FFFFFFFF;
  2364. fRange.g := $FFFFFFFF;
  2365. fRange.b := $FFFFFFFF;
  2366. fglFormat := GL_DEPTH_COMPONENT;
  2367. fglDataFormat := GL_UNSIGNED_INT;
  2368. end;
  2369. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2370. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2371. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2372. constructor TfdAlpha4.Create;
  2373. begin
  2374. inherited Create;
  2375. fFormat := tfAlpha4;
  2376. fWithAlpha := tfAlpha4;
  2377. fglInternalFormat := GL_ALPHA4;
  2378. end;
  2379. constructor TfdAlpha8.Create;
  2380. begin
  2381. inherited Create;
  2382. fFormat := tfAlpha8;
  2383. fWithAlpha := tfAlpha8;
  2384. fglInternalFormat := GL_ALPHA8;
  2385. end;
  2386. constructor TfdAlpha12.Create;
  2387. begin
  2388. inherited Create;
  2389. fFormat := tfAlpha12;
  2390. fWithAlpha := tfAlpha12;
  2391. fglInternalFormat := GL_ALPHA12;
  2392. end;
  2393. constructor TfdAlpha16.Create;
  2394. begin
  2395. inherited Create;
  2396. fFormat := tfAlpha16;
  2397. fWithAlpha := tfAlpha16;
  2398. fglInternalFormat := GL_ALPHA16;
  2399. end;
  2400. constructor TfdLuminance4.Create;
  2401. begin
  2402. inherited Create;
  2403. fFormat := tfLuminance4;
  2404. fWithAlpha := tfLuminance4Alpha4;
  2405. fWithoutAlpha := tfLuminance4;
  2406. fglInternalFormat := GL_LUMINANCE4;
  2407. end;
  2408. constructor TfdLuminance8.Create;
  2409. begin
  2410. inherited Create;
  2411. fFormat := tfLuminance8;
  2412. fWithAlpha := tfLuminance8Alpha8;
  2413. fWithoutAlpha := tfLuminance8;
  2414. fglInternalFormat := GL_LUMINANCE8;
  2415. end;
  2416. constructor TfdLuminance12.Create;
  2417. begin
  2418. inherited Create;
  2419. fFormat := tfLuminance12;
  2420. fWithAlpha := tfLuminance12Alpha12;
  2421. fWithoutAlpha := tfLuminance12;
  2422. fglInternalFormat := GL_LUMINANCE12;
  2423. end;
  2424. constructor TfdLuminance16.Create;
  2425. begin
  2426. inherited Create;
  2427. fFormat := tfLuminance16;
  2428. fWithAlpha := tfLuminance16Alpha16;
  2429. fWithoutAlpha := tfLuminance16;
  2430. fglInternalFormat := GL_LUMINANCE16;
  2431. end;
  2432. constructor TfdLuminance4Alpha4.Create;
  2433. begin
  2434. inherited Create;
  2435. fFormat := tfLuminance4Alpha4;
  2436. fWithAlpha := tfLuminance4Alpha4;
  2437. fWithoutAlpha := tfLuminance4;
  2438. fglInternalFormat := GL_LUMINANCE4_ALPHA4;
  2439. end;
  2440. constructor TfdLuminance6Alpha2.Create;
  2441. begin
  2442. inherited Create;
  2443. fFormat := tfLuminance6Alpha2;
  2444. fWithAlpha := tfLuminance6Alpha2;
  2445. fWithoutAlpha := tfLuminance8;
  2446. fglInternalFormat := GL_LUMINANCE6_ALPHA2;
  2447. end;
  2448. constructor TfdLuminance8Alpha8.Create;
  2449. begin
  2450. inherited Create;
  2451. fFormat := tfLuminance8Alpha8;
  2452. fWithAlpha := tfLuminance8Alpha8;
  2453. fWithoutAlpha := tfLuminance8;
  2454. fglInternalFormat := GL_LUMINANCE8_ALPHA8;
  2455. end;
  2456. constructor TfdLuminance12Alpha4.Create;
  2457. begin
  2458. inherited Create;
  2459. fFormat := tfLuminance12Alpha4;
  2460. fWithAlpha := tfLuminance12Alpha4;
  2461. fWithoutAlpha := tfLuminance12;
  2462. fglInternalFormat := GL_LUMINANCE12_ALPHA4;
  2463. end;
  2464. constructor TfdLuminance12Alpha12.Create;
  2465. begin
  2466. inherited Create;
  2467. fFormat := tfLuminance12Alpha12;
  2468. fWithAlpha := tfLuminance12Alpha12;
  2469. fWithoutAlpha := tfLuminance12;
  2470. fglInternalFormat := GL_LUMINANCE12_ALPHA12;
  2471. end;
  2472. constructor TfdLuminance16Alpha16.Create;
  2473. begin
  2474. inherited Create;
  2475. fFormat := tfLuminance16Alpha16;
  2476. fWithAlpha := tfLuminance16Alpha16;
  2477. fWithoutAlpha := tfLuminance16;
  2478. fglInternalFormat := GL_LUMINANCE16_ALPHA16;
  2479. end;
  2480. constructor TfdR3G3B2.Create;
  2481. begin
  2482. inherited Create;
  2483. fFormat := tfR3G3B2;
  2484. fWithAlpha := tfRGBA2;
  2485. fWithoutAlpha := tfR3G3B2;
  2486. fRange.r := $7;
  2487. fRange.g := $7;
  2488. fRange.b := $3;
  2489. fShift.r := 0;
  2490. fShift.g := 3;
  2491. fShift.b := 6;
  2492. fglFormat := GL_RGB;
  2493. fglInternalFormat := GL_R3_G3_B2;
  2494. fglDataFormat := GL_UNSIGNED_BYTE_2_3_3_REV;
  2495. end;
  2496. constructor TfdRGB4.Create;
  2497. begin
  2498. inherited Create;
  2499. fFormat := tfRGB4;
  2500. fWithAlpha := tfRGBA4;
  2501. fWithoutAlpha := tfRGB4;
  2502. fRange.r := $F;
  2503. fRange.g := $F;
  2504. fRange.b := $F;
  2505. fShift.r := 0;
  2506. fShift.g := 4;
  2507. fShift.b := 8;
  2508. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2509. fglInternalFormat := GL_RGB4;
  2510. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
  2511. end;
  2512. constructor TfdR5G6B5.Create;
  2513. begin
  2514. inherited Create;
  2515. fFormat := tfR5G6B5;
  2516. fWithAlpha := tfRGBA4;
  2517. fWithoutAlpha := tfR5G6B5;
  2518. fRange.r := $1F;
  2519. fRange.g := $3F;
  2520. fRange.b := $1F;
  2521. fShift.r := 0;
  2522. fShift.g := 5;
  2523. fShift.b := 11;
  2524. fglFormat := GL_RGB;
  2525. fglInternalFormat := GL_RGB565;
  2526. fglDataFormat := GL_UNSIGNED_SHORT_5_6_5_REV;
  2527. end;
  2528. constructor TfdRGB5.Create;
  2529. begin
  2530. inherited Create;
  2531. fFormat := tfRGB5;
  2532. fWithAlpha := tfRGB5A1;
  2533. fWithoutAlpha := tfRGB5;
  2534. fRange.r := $1F;
  2535. fRange.g := $1F;
  2536. fRange.b := $1F;
  2537. fShift.r := 0;
  2538. fShift.g := 5;
  2539. fShift.b := 10;
  2540. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2541. fglInternalFormat := GL_RGB5;
  2542. fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
  2543. end;
  2544. constructor TfdRGB8.Create;
  2545. begin
  2546. inherited Create;
  2547. fFormat := tfRGB8;
  2548. fWithAlpha := tfRGBA8;
  2549. fWithoutAlpha := tfRGB8;
  2550. fglInternalFormat := GL_RGB8;
  2551. end;
  2552. constructor TfdRGB10.Create;
  2553. begin
  2554. inherited Create;
  2555. fFormat := tfRGB10;
  2556. fWithAlpha := tfRGB10A2;
  2557. fWithoutAlpha := tfRGB10;
  2558. fRange.r := $3FF;
  2559. fRange.g := $3FF;
  2560. fRange.b := $3FF;
  2561. fShift.r := 0;
  2562. fShift.g := 10;
  2563. fShift.b := 20;
  2564. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2565. fglInternalFormat := GL_RGB10;
  2566. fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
  2567. end;
  2568. constructor TfdRGB12.Create;
  2569. begin
  2570. inherited Create;
  2571. fFormat := tfRGB12;
  2572. fWithAlpha := tfRGBA12;
  2573. fWithoutAlpha := tfRGB12;
  2574. fglInternalFormat := GL_RGB12;
  2575. end;
  2576. constructor TfdRGB16.Create;
  2577. begin
  2578. inherited Create;
  2579. fFormat := tfRGB16;
  2580. fWithAlpha := tfRGBA16;
  2581. fWithoutAlpha := tfRGB16;
  2582. fglInternalFormat := GL_RGB16;
  2583. end;
  2584. constructor TfdRGBA2.Create;
  2585. begin
  2586. inherited Create;
  2587. fFormat := tfRGBA2;
  2588. fWithAlpha := tfRGBA2;
  2589. fWithoutAlpha := tfR3G3B2;
  2590. fglInternalFormat := GL_RGBA2;
  2591. end;
  2592. constructor TfdRGBA4.Create;
  2593. begin
  2594. inherited Create;
  2595. fFormat := tfRGBA4;
  2596. fWithAlpha := tfRGBA4;
  2597. fWithoutAlpha := tfRGB4;
  2598. fRange.r := $F;
  2599. fRange.g := $F;
  2600. fRange.b := $F;
  2601. fRange.a := $F;
  2602. fShift.r := 0;
  2603. fShift.g := 4;
  2604. fShift.b := 8;
  2605. fShift.a := 12;
  2606. fglFormat := GL_RGBA;
  2607. fglInternalFormat := GL_RGBA4;
  2608. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
  2609. end;
  2610. constructor TfdRGB5A1.Create;
  2611. begin
  2612. inherited Create;
  2613. fFormat := tfRGB5A1;
  2614. fWithAlpha := tfRGB5A1;
  2615. fWithoutAlpha := tfRGB5;
  2616. fRange.r := $1F;
  2617. fRange.g := $1F;
  2618. fRange.b := $1F;
  2619. fRange.a := $01;
  2620. fShift.r := 0;
  2621. fShift.g := 5;
  2622. fShift.b := 10;
  2623. fShift.a := 15;
  2624. fglFormat := GL_RGBA;
  2625. fglInternalFormat := GL_RGB5_A1;
  2626. fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
  2627. end;
  2628. constructor TfdRGBA8.Create;
  2629. begin
  2630. inherited Create;
  2631. fFormat := tfRGBA8;
  2632. fWithAlpha := tfRGBA8;
  2633. fWithoutAlpha := tfRGB8;
  2634. fglInternalFormat := GL_RGBA8;
  2635. end;
  2636. constructor TfdRGB10A2.Create;
  2637. begin
  2638. inherited Create;
  2639. fFormat := tfRGB10A2;
  2640. fWithAlpha := tfRGB10A2;
  2641. fWithoutAlpha := tfRGB10;
  2642. fRange.r := $3FF;
  2643. fRange.g := $3FF;
  2644. fRange.b := $3FF;
  2645. fRange.a := $003;
  2646. fShift.r := 0;
  2647. fShift.g := 10;
  2648. fShift.b := 20;
  2649. fShift.a := 30;
  2650. fglFormat := GL_RGBA;
  2651. fglInternalFormat := GL_RGB10_A2;
  2652. fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
  2653. end;
  2654. constructor TfdRGBA12.Create;
  2655. begin
  2656. inherited Create;
  2657. fFormat := tfRGBA12;
  2658. fWithAlpha := tfRGBA12;
  2659. fWithoutAlpha := tfRGB12;
  2660. fglInternalFormat := GL_RGBA12;
  2661. end;
  2662. constructor TfdRGBA16.Create;
  2663. begin
  2664. inherited Create;
  2665. fFormat := tfRGBA16;
  2666. fWithAlpha := tfRGBA16;
  2667. fWithoutAlpha := tfRGB16;
  2668. fglInternalFormat := GL_RGBA16;
  2669. end;
  2670. constructor TfdBGR4.Create;
  2671. begin
  2672. inherited Create;
  2673. fPixelSize := 2.0;
  2674. fFormat := tfBGR4;
  2675. fWithAlpha := tfBGRA4;
  2676. fWithoutAlpha := tfBGR4;
  2677. fRange.r := $F;
  2678. fRange.g := $F;
  2679. fRange.b := $F;
  2680. fRange.a := $0;
  2681. fShift.r := 8;
  2682. fShift.g := 4;
  2683. fShift.b := 0;
  2684. fShift.a := 0;
  2685. fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2686. fglInternalFormat := GL_RGB4;
  2687. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
  2688. end;
  2689. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2690. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2691. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2692. constructor TfdB5G6R5.Create;
  2693. begin
  2694. inherited Create;
  2695. fFormat := tfB5G6R5;
  2696. fWithAlpha := tfBGRA4;
  2697. fWithoutAlpha := tfB5G6R5;
  2698. fRange.r := $1F;
  2699. fRange.g := $3F;
  2700. fRange.b := $1F;
  2701. fShift.r := 11;
  2702. fShift.g := 5;
  2703. fShift.b := 0;
  2704. fglFormat := GL_RGB; //B5G6R5 is only possible as R5G6B5 -> use reverted dataformat
  2705. fglInternalFormat := GL_RGB8;
  2706. fglDataFormat := GL_UNSIGNED_SHORT_5_6_5;
  2707. end;
  2708. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2709. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2710. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2711. constructor TfdBGR5.Create;
  2712. begin
  2713. inherited Create;
  2714. fPixelSize := 2.0;
  2715. fFormat := tfBGR5;
  2716. fWithAlpha := tfBGR5A1;
  2717. fWithoutAlpha := tfBGR5;
  2718. fRange.r := $1F;
  2719. fRange.g := $1F;
  2720. fRange.b := $1F;
  2721. fRange.a := $00;
  2722. fShift.r := 10;
  2723. fShift.g := 5;
  2724. fShift.b := 0;
  2725. fShift.a := 0;
  2726. fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2727. fglInternalFormat := GL_RGB5;
  2728. fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
  2729. end;
  2730. constructor TfdBGR8.Create;
  2731. begin
  2732. inherited Create;
  2733. fFormat := tfBGR8;
  2734. fWithAlpha := tfBGRA8;
  2735. fWithoutAlpha := tfBGR8;
  2736. fglInternalFormat := GL_RGB8;
  2737. end;
  2738. constructor TfdBGR10.Create;
  2739. begin
  2740. inherited Create;
  2741. fFormat := tfBGR10;
  2742. fWithAlpha := tfBGR10A2;
  2743. fWithoutAlpha := tfBGR10;
  2744. fRange.r := $3FF;
  2745. fRange.g := $3FF;
  2746. fRange.b := $3FF;
  2747. fRange.a := $000;
  2748. fShift.r := 20;
  2749. fShift.g := 10;
  2750. fShift.b := 0;
  2751. fShift.a := 0;
  2752. fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2753. fglInternalFormat := GL_RGB10;
  2754. fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
  2755. end;
  2756. constructor TfdBGR12.Create;
  2757. begin
  2758. inherited Create;
  2759. fFormat := tfBGR12;
  2760. fWithAlpha := tfBGRA12;
  2761. fWithoutAlpha := tfBGR12;
  2762. fglInternalFormat := GL_RGB12;
  2763. end;
  2764. constructor TfdBGR16.Create;
  2765. begin
  2766. inherited Create;
  2767. fFormat := tfBGR16;
  2768. fWithAlpha := tfBGRA16;
  2769. fWithoutAlpha := tfBGR16;
  2770. fglInternalFormat := GL_RGB16;
  2771. end;
  2772. constructor TfdBGRA2.Create;
  2773. begin
  2774. inherited Create;
  2775. fFormat := tfBGRA2;
  2776. fWithAlpha := tfBGRA4;
  2777. fWithoutAlpha := tfBGR4;
  2778. fglInternalFormat := GL_RGBA2;
  2779. end;
  2780. constructor TfdBGRA4.Create;
  2781. begin
  2782. inherited Create;
  2783. fFormat := tfBGRA4;
  2784. fWithAlpha := tfBGRA4;
  2785. fWithoutAlpha := tfBGR4;
  2786. fRange.r := $F;
  2787. fRange.g := $F;
  2788. fRange.b := $F;
  2789. fRange.a := $F;
  2790. fShift.r := 8;
  2791. fShift.g := 4;
  2792. fShift.b := 0;
  2793. fShift.a := 12;
  2794. fglFormat := GL_BGRA;
  2795. fglInternalFormat := GL_RGBA4;
  2796. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
  2797. end;
  2798. constructor TfdBGR5A1.Create;
  2799. begin
  2800. inherited Create;
  2801. fFormat := tfBGR5A1;
  2802. fWithAlpha := tfBGR5A1;
  2803. fWithoutAlpha := tfBGR5;
  2804. fRange.r := $1F;
  2805. fRange.g := $1F;
  2806. fRange.b := $1F;
  2807. fRange.a := $01;
  2808. fShift.r := 10;
  2809. fShift.g := 5;
  2810. fShift.b := 0;
  2811. fShift.a := 15;
  2812. fglFormat := GL_BGRA;
  2813. fglInternalFormat := GL_RGB5_A1;
  2814. fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
  2815. end;
  2816. constructor TfdBGRA8.Create;
  2817. begin
  2818. inherited Create;
  2819. fFormat := tfBGRA8;
  2820. fWithAlpha := tfBGRA8;
  2821. fWithoutAlpha := tfBGR8;
  2822. fglInternalFormat := GL_RGBA8;
  2823. end;
  2824. constructor TfdBGR10A2.Create;
  2825. begin
  2826. inherited Create;
  2827. fFormat := tfBGR10A2;
  2828. fWithAlpha := tfBGR10A2;
  2829. fWithoutAlpha := tfBGR10;
  2830. fRange.r := $3FF;
  2831. fRange.g := $3FF;
  2832. fRange.b := $3FF;
  2833. fRange.a := $003;
  2834. fShift.r := 20;
  2835. fShift.g := 10;
  2836. fShift.b := 0;
  2837. fShift.a := 30;
  2838. fglFormat := GL_BGRA;
  2839. fglInternalFormat := GL_RGB10_A2;
  2840. fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
  2841. end;
  2842. constructor TfdBGRA12.Create;
  2843. begin
  2844. inherited Create;
  2845. fFormat := tfBGRA12;
  2846. fWithAlpha := tfBGRA12;
  2847. fWithoutAlpha := tfBGR12;
  2848. fglInternalFormat := GL_RGBA12;
  2849. end;
  2850. constructor TfdBGRA16.Create;
  2851. begin
  2852. inherited Create;
  2853. fFormat := tfBGRA16;
  2854. fWithAlpha := tfBGRA16;
  2855. fWithoutAlpha := tfBGR16;
  2856. fglInternalFormat := GL_RGBA16;
  2857. end;
  2858. constructor TfdDepth16.Create;
  2859. begin
  2860. inherited Create;
  2861. fFormat := tfDepth16;
  2862. fWithAlpha := tfEmpty;
  2863. fWithoutAlpha := tfDepth16;
  2864. fglInternalFormat := GL_DEPTH_COMPONENT16;
  2865. end;
  2866. constructor TfdDepth24.Create;
  2867. begin
  2868. inherited Create;
  2869. fFormat := tfDepth24;
  2870. fWithAlpha := tfEmpty;
  2871. fWithoutAlpha := tfDepth24;
  2872. fglInternalFormat := GL_DEPTH_COMPONENT24;
  2873. end;
  2874. constructor TfdDepth32.Create;
  2875. begin
  2876. inherited Create;
  2877. fFormat := tfDepth32;
  2878. fWithAlpha := tfEmpty;
  2879. fWithoutAlpha := tfDepth32;
  2880. fglInternalFormat := GL_DEPTH_COMPONENT32;
  2881. end;
  2882. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2883. //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2884. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2885. class procedure TFormatDescriptor.Init;
  2886. begin
  2887. if not Assigned(FormatDescriptorCS) then
  2888. FormatDescriptorCS := TCriticalSection.Create;
  2889. end;
  2890. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2891. class function TFormatDescriptor.Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
  2892. begin
  2893. FormatDescriptorCS.Enter;
  2894. try
  2895. result := FormatDescriptors[aFormat];
  2896. if not Assigned(result) then begin
  2897. result := FORMAT_DESCRIPTOR_CLASSES[aFormat].Create;
  2898. FormatDescriptors[aFormat] := result;
  2899. end;
  2900. finally
  2901. FormatDescriptorCS.Leave;
  2902. end;
  2903. end;
  2904. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2905. class function TFormatDescriptor.GetWithAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
  2906. begin
  2907. result := Get(Get(aFormat).WithAlpha);
  2908. end;
  2909. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2910. class procedure TFormatDescriptor.Clear;
  2911. var
  2912. f: TglBitmapFormat;
  2913. begin
  2914. FormatDescriptorCS.Enter;
  2915. try
  2916. for f := low(FormatDescriptors) to high(FormatDescriptors) do
  2917. FreeAndNil(FormatDescriptors[f]);
  2918. finally
  2919. FormatDescriptorCS.Leave;
  2920. end;
  2921. end;
  2922. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2923. class procedure TFormatDescriptor.Finalize;
  2924. begin
  2925. Clear;
  2926. FreeAndNil(FormatDescriptorCS);
  2927. end;
  2928. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2929. //TBitfieldFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2930. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2931. procedure TbmpBitfieldFormat.SetRedMask(const aValue: UInt64);
  2932. begin
  2933. Update(aValue, fRange.r, fShift.r);
  2934. end;
  2935. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2936. procedure TbmpBitfieldFormat.SetGreenMask(const aValue: UInt64);
  2937. begin
  2938. Update(aValue, fRange.g, fShift.g);
  2939. end;
  2940. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2941. procedure TbmpBitfieldFormat.SetBlueMask(const aValue: UInt64);
  2942. begin
  2943. Update(aValue, fRange.b, fShift.b);
  2944. end;
  2945. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2946. procedure TbmpBitfieldFormat.SetAlphaMask(const aValue: UInt64);
  2947. begin
  2948. Update(aValue, fRange.a, fShift.a);
  2949. end;
  2950. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2951. procedure TbmpBitfieldFormat.Update(aMask: UInt64; out aRange: Cardinal; out
  2952. aShift: Byte);
  2953. begin
  2954. aShift := 0;
  2955. aRange := 0;
  2956. if (aMask = 0) then
  2957. exit;
  2958. while (aMask > 0) and ((aMask and 1) = 0) do begin
  2959. inc(aShift);
  2960. aMask := aMask shr 1;
  2961. end;
  2962. aRange := 1;
  2963. while (aMask > 0) do begin
  2964. aRange := aRange shl 1;
  2965. aMask := aMask shr 1;
  2966. end;
  2967. dec(aRange);
  2968. fPixelSize := Round(GetTopMostBit(RedMask or GreenMask or BlueMask or AlphaMask) / 8);
  2969. end;
  2970. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2971. procedure TbmpBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2972. var
  2973. data: UInt64;
  2974. s: Integer;
  2975. type
  2976. PUInt64 = ^UInt64;
  2977. begin
  2978. data :=
  2979. ((aPixel.Data.r and fRange.r) shl fShift.r) or
  2980. ((aPixel.Data.g and fRange.g) shl fShift.g) or
  2981. ((aPixel.Data.b and fRange.b) shl fShift.b) or
  2982. ((aPixel.Data.a and fRange.a) shl fShift.a);
  2983. s := Round(fPixelSize);
  2984. case s of
  2985. 1: aData^ := data;
  2986. 2: PWord(aData)^ := data;
  2987. 4: PCardinal(aData)^ := data;
  2988. 8: PUInt64(aData)^ := data;
  2989. else
  2990. raise EglBitmapException.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
  2991. end;
  2992. inc(aData, s);
  2993. end;
  2994. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2995. procedure TbmpBitfieldFormat.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2996. var
  2997. data: UInt64;
  2998. s, i: Integer;
  2999. type
  3000. PUInt64 = ^UInt64;
  3001. begin
  3002. s := Round(fPixelSize);
  3003. case s of
  3004. 1: data := aData^;
  3005. 2: data := PWord(aData)^;
  3006. 4: data := PCardinal(aData)^;
  3007. 8: data := PUInt64(aData)^;
  3008. else
  3009. raise EglBitmapException.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
  3010. end;
  3011. for i := 0 to 3 do
  3012. aPixel.Data.arr[i] := (data shr fShift.arr[i]) and fRange.arr[i];
  3013. inc(aData, s);
  3014. end;
  3015. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3016. //TColorTableFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3017. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3018. procedure TbmpColorTableFormat.CreateColorTable;
  3019. var
  3020. bits: Byte;
  3021. len: Integer;
  3022. i: Integer;
  3023. begin
  3024. if not (Format in [tfLuminance4, tfLuminance8, tfR3G3B2]) then
  3025. raise EglBitmapException.Create(UNSUPPORTED_FORMAT);
  3026. if (Format = tfLuminance4) then
  3027. SetLength(fColorTable, 16)
  3028. else
  3029. SetLength(fColorTable, 256);
  3030. case Format of
  3031. tfLuminance4: begin
  3032. for i := 0 to High(fColorTable) do begin
  3033. fColorTable[i].r := 16 * i;
  3034. fColorTable[i].g := 16 * i;
  3035. fColorTable[i].b := 16 * i;
  3036. fColorTable[i].a := 0;
  3037. end;
  3038. end;
  3039. tfLuminance8: begin
  3040. for i := 0 to High(fColorTable) do begin
  3041. fColorTable[i].r := i;
  3042. fColorTable[i].g := i;
  3043. fColorTable[i].b := i;
  3044. fColorTable[i].a := 0;
  3045. end;
  3046. end;
  3047. tfR3G3B2: begin
  3048. for i := 0 to High(fColorTable) do begin
  3049. fColorTable[i].r := Round(((i shr Shift.r) and Range.r) / Range.r * 255);
  3050. fColorTable[i].g := Round(((i shr Shift.g) and Range.g) / Range.g * 255);
  3051. fColorTable[i].b := Round(((i shr Shift.b) and Range.b) / Range.b * 255);
  3052. fColorTable[i].a := 0;
  3053. s := SysUtils.Format('%.2X%.2X%.2X' + sLineBreak, [fColorTable[i].r, fColorTable[i].g, fColorTable[i].b]);
  3054. fs.Write(s[1], Length(s));
  3055. end;
  3056. end;
  3057. end;
  3058. end;
  3059. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3060. procedure TbmpColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  3061. var
  3062. d: Byte;
  3063. begin
  3064. if not (Format in [tfLuminance4, tfLuminance8, tfR3G3B2]) then
  3065. raise EglBitmapException.Create(UNSUPPORTED_FORMAT);
  3066. case Format of
  3067. tfLuminance4: begin
  3068. if (aMapData = nil) then
  3069. aData^ := 0;
  3070. d := LuminanceWeight(aPixel) and Range.r;
  3071. aData^ := aData^ or (d shl (4 - PtrInt(aMapData)));
  3072. inc(aMapData, 4);
  3073. if (PtrInt(aMapData) >= 8) then begin
  3074. inc(aData);
  3075. aMapData := nil;
  3076. end;
  3077. end;
  3078. tfLuminance8: begin
  3079. aData^ := LuminanceWeight(aPixel) and Range.r;
  3080. inc(aData);
  3081. end;
  3082. tfR3G3B2: begin
  3083. aData^ := Round(
  3084. ((aPixel.Data.r and Range.r) shl Shift.r) or
  3085. ((aPixel.Data.g and Range.g) shl Shift.g) or
  3086. ((aPixel.Data.b and Range.b) shl Shift.b));
  3087. inc(aData);
  3088. end;
  3089. end;
  3090. end;
  3091. procedure TbmpColorTableFormat.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
  3092. type
  3093. PUInt64 = ^UInt64;
  3094. var
  3095. idx: UInt64;
  3096. s: Integer;
  3097. bits: Byte;
  3098. f: Single;
  3099. begin
  3100. s := Trunc(fPixelSize);
  3101. f := fPixelSize - s;
  3102. bits := Round(8 * f);
  3103. case s of
  3104. 0: idx := (aData^ shr (8 - bits - PtrInt(aMapData))) and ((1 shl bits) - 1);
  3105. 1: idx := aData^;
  3106. 2: idx := PWord(aData)^;
  3107. 4: idx := PCardinal(aData)^;
  3108. 8: idx := PUInt64(aData)^;
  3109. else
  3110. raise EglBitmapException.CreateFmt('invalid pixel size: %.3f', [fPixelSize]);
  3111. end;
  3112. if (idx >= Length(fColorTable)) then
  3113. raise EglBitmapException.CreateFmt('invalid color index: %d', [idx]);
  3114. with fColorTable[idx] do begin
  3115. aPixel.Data.r := r;
  3116. aPixel.Data.g := g;
  3117. aPixel.Data.b := b;
  3118. aPixel.Data.a := a;
  3119. end;
  3120. inc(aMapData, bits);
  3121. if (PtrInt(aMapData) >= 8) then begin
  3122. inc(aData, 1);
  3123. dec(aMapData, 8);
  3124. end;
  3125. inc(aData, s);
  3126. end;
  3127. destructor TbmpColorTableFormat.Destroy;
  3128. begin
  3129. SetLength(fColorTable, 0);
  3130. inherited Destroy;
  3131. end;
  3132. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3133. //TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3134. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3135. procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
  3136. begin
  3137. with aFuncRec do begin
  3138. if (Source.Range.r > 0) then
  3139. Dest.Data.r := Source.Data.r;
  3140. if (Source.Range.g > 0) then
  3141. Dest.Data.g := Source.Data.g;
  3142. if (Source.Range.b > 0) then
  3143. Dest.Data.b := Source.Data.b;
  3144. if (Source.Range.a > 0) then
  3145. Dest.Data.a := Source.Data.a;
  3146. end;
  3147. end;
  3148. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3149. procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
  3150. var
  3151. i: Integer;
  3152. begin
  3153. with aFuncRec do begin
  3154. for i := 0 to 3 do
  3155. if (Source.Range.arr[i] > 0) then
  3156. Dest.Data.arr[i] := Round(Dest.Range.arr[i] * Source.Data.arr[i] / Source.Range.arr[i]);
  3157. end;
  3158. end;
  3159. type
  3160. TShiftData = packed record
  3161. case Integer of
  3162. 0: (r, g, b, a: SmallInt);
  3163. 1: (arr: array[0..3] of SmallInt);
  3164. end;
  3165. PShiftData = ^TShiftData;
  3166. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3167. procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
  3168. var
  3169. i: Integer;
  3170. begin
  3171. with aFuncRec do
  3172. for i := 0 to 3 do
  3173. if (Source.Range.arr[i] > 0) then
  3174. Dest.Data.arr[i] := Source.Data.arr[i] shr PShiftData(Args)^.arr[i];
  3175. end;
  3176. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3177. procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
  3178. begin
  3179. with aFuncRec do begin
  3180. Dest.Data.r := Source.Data.r;
  3181. Dest.Data.g := Source.Data.g;
  3182. Dest.Data.b := Source.Data.b;
  3183. Dest.Data.a := Source.Data.a;
  3184. if (Args and $1 > 0) then begin
  3185. Dest.Data.r := Dest.Data.r xor Dest.Range.r;
  3186. Dest.Data.g := Dest.Data.g xor Dest.Range.g;
  3187. Dest.Data.b := Dest.Data.b xor Dest.Range.b;
  3188. end;
  3189. if (Args and $2 > 0) then begin
  3190. Dest.Data.a := Dest.Data.a xor Dest.Range.a;
  3191. end;
  3192. end;
  3193. end;
  3194. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3195. procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
  3196. var
  3197. i: Integer;
  3198. begin
  3199. with aFuncRec do begin
  3200. for i := 0 to 3 do
  3201. Dest.Data.arr[i] := PglBitmapPixelData(Args)^.Data.arr[i];
  3202. end;
  3203. end;
  3204. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3205. procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
  3206. var
  3207. Temp: Single;
  3208. begin
  3209. with FuncRec do begin
  3210. if (FuncRec.Args = 0) then begin //source has no alpha
  3211. Temp :=
  3212. Source.Data.r / Source.Range.r * ALPHA_WEIGHT_R +
  3213. Source.Data.g / Source.Range.g * ALPHA_WEIGHT_G +
  3214. Source.Data.b / Source.Range.b * ALPHA_WEIGHT_B;
  3215. Dest.Data.a := Round(Dest.Range.a * Temp);
  3216. end else
  3217. Dest.Data.a := Round(Source.Data.a / Source.Range.a * Dest.Range.a);
  3218. end;
  3219. end;
  3220. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3221. procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
  3222. type
  3223. PglBitmapPixelData = ^TglBitmapPixelData;
  3224. begin
  3225. with FuncRec do begin
  3226. Dest.Data.r := Source.Data.r;
  3227. Dest.Data.g := Source.Data.g;
  3228. Dest.Data.b := Source.Data.b;
  3229. with PglBitmapPixelData(Args)^ do
  3230. if ((Dest.Data.r <= Data.r) and (Dest.Data.r >= Range.r) and
  3231. (Dest.Data.g <= Data.g) and (Dest.Data.g >= Range.g) and
  3232. (Dest.Data.b <= Data.b) and (Dest.Data.b >= Range.b)) then
  3233. Dest.Data.a := 0
  3234. else
  3235. Dest.Data.a := Dest.Range.a;
  3236. end;
  3237. end;
  3238. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3239. procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
  3240. type
  3241. PglBitmapPixelData = ^TglBitmapPixelData;
  3242. begin
  3243. with FuncRec do begin
  3244. Dest.Data.r := Source.Data.r;
  3245. Dest.Data.g := Source.Data.g;
  3246. Dest.Data.b := Source.Data.b;
  3247. Dest.Data.a := PCardinal(Args)^;
  3248. end;
  3249. end;
  3250. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3251. procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
  3252. type
  3253. PRGBPix = ^TRGBPix;
  3254. TRGBPix = array [0..2] of byte;
  3255. var
  3256. Temp: Byte;
  3257. begin
  3258. while aWidth > 0 do begin
  3259. Temp := PRGBPix(aData)^[0];
  3260. PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
  3261. PRGBPix(aData)^[2] := Temp;
  3262. if aHasAlpha then
  3263. Inc(aData, 4)
  3264. else
  3265. Inc(aData, 3);
  3266. dec(aWidth);
  3267. end;
  3268. end;
  3269. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3270. //TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3271. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3272. function TglBitmap.GetWidth: Integer;
  3273. begin
  3274. if (ffX in fDimension.Fields) then
  3275. result := fDimension.X
  3276. else
  3277. result := -1;
  3278. end;
  3279. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3280. function TglBitmap.GetHeight: Integer;
  3281. begin
  3282. if (ffY in fDimension.Fields) then
  3283. result := fDimension.Y
  3284. else
  3285. result := -1;
  3286. end;
  3287. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3288. function TglBitmap.GetFileWidth: Integer;
  3289. begin
  3290. result := Max(1, Width);
  3291. end;
  3292. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3293. function TglBitmap.GetFileHeight: Integer;
  3294. begin
  3295. result := Max(1, Height);
  3296. end;
  3297. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3298. procedure TglBitmap.SetCustomData(const aValue: Pointer);
  3299. begin
  3300. if fCustomData = aValue then
  3301. exit;
  3302. fCustomData := aValue;
  3303. end;
  3304. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3305. procedure TglBitmap.SetCustomName(const aValue: String);
  3306. begin
  3307. if fCustomName = aValue then
  3308. exit;
  3309. fCustomName := aValue;
  3310. end;
  3311. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3312. procedure TglBitmap.SetCustomNameW(const aValue: WideString);
  3313. begin
  3314. if fCustomNameW = aValue then
  3315. exit;
  3316. fCustomNameW := aValue;
  3317. end;
  3318. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3319. procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
  3320. begin
  3321. if fDeleteTextureOnFree = aValue then
  3322. exit;
  3323. fDeleteTextureOnFree := aValue;
  3324. end;
  3325. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3326. procedure TglBitmap.SetFormat(const aValue: TglBitmapFormat);
  3327. begin
  3328. if fFormat = aValue then
  3329. exit;
  3330. if TFormatDescriptor.Get(Format).PixelSize <> TFormatDescriptor.Get(aValue).PixelSize then
  3331. raise EglBitmapUnsupportedFormatFormat.Create('SetInternalFormat - ' + UNSUPPORTED_FORMAT);
  3332. SetDataPointer(Data, aValue, Width, Height);
  3333. end;
  3334. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3335. procedure TglBitmap.SetFreeDataAfterGenTexture(const aValue: Boolean);
  3336. begin
  3337. if fFreeDataAfterGenTexture = aValue then
  3338. exit;
  3339. fFreeDataAfterGenTexture := aValue;
  3340. end;
  3341. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3342. procedure TglBitmap.SetID(const aValue: Cardinal);
  3343. begin
  3344. if fID = aValue then
  3345. exit;
  3346. fID := aValue;
  3347. end;
  3348. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3349. procedure TglBitmap.SetMipMap(const aValue: TglBitmapMipMap);
  3350. begin
  3351. if fMipMap = aValue then
  3352. exit;
  3353. fMipMap := aValue;
  3354. end;
  3355. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3356. procedure TglBitmap.SetTarget(const aValue: Cardinal);
  3357. begin
  3358. if fTarget = aValue then
  3359. exit;
  3360. fTarget := aValue;
  3361. end;
  3362. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3363. procedure TglBitmap.SetAnisotropic(const aValue: Integer);
  3364. var
  3365. MaxAnisotropic: Integer;
  3366. begin
  3367. fAnisotropic := aValue;
  3368. if (ID > 0) then begin
  3369. if GL_EXT_texture_filter_anisotropic then begin
  3370. if fAnisotropic > 0 then begin
  3371. Bind(false);
  3372. glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
  3373. if aValue > MaxAnisotropic then
  3374. fAnisotropic := MaxAnisotropic;
  3375. glTexParameteri(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, fAnisotropic);
  3376. end;
  3377. end else begin
  3378. fAnisotropic := 0;
  3379. end;
  3380. end;
  3381. end;
  3382. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3383. procedure TglBitmap.CreateID;
  3384. begin
  3385. if (ID <> 0) then
  3386. glDeleteTextures(1, @fID);
  3387. glGenTextures(1, @fID);
  3388. Bind(false);
  3389. end;
  3390. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3391. procedure TglBitmap.SetupParameters(var aBuildWithGlu: Boolean);
  3392. begin
  3393. // Set Up Parameters
  3394. SetWrap(fWrapS, fWrapT, fWrapR);
  3395. SetFilter(fFilterMin, fFilterMag);
  3396. SetAnisotropic(fAnisotropic);
  3397. SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
  3398. // Mip Maps Generation Mode
  3399. aBuildWithGlu := false;
  3400. if (MipMap = mmMipmap) then begin
  3401. if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
  3402. glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
  3403. else
  3404. aBuildWithGlu := true;
  3405. end else if (MipMap = mmMipmapGlu) then
  3406. aBuildWithGlu := true;
  3407. end;
  3408. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3409. procedure TglBitmap.SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
  3410. const aWidth: Integer; const aHeight: Integer);
  3411. var
  3412. s: Single;
  3413. begin
  3414. if (Data <> aData) then begin
  3415. if (Assigned(Data)) then
  3416. FreeMem(Data);
  3417. fData := aData;
  3418. end;
  3419. FillChar(fDimension, SizeOf(fDimension), 0);
  3420. if not Assigned(fData) then begin
  3421. fFormat := tfEmpty;
  3422. fPixelSize := 0;
  3423. fRowSize := 0;
  3424. end else begin
  3425. if aWidth <> -1 then begin
  3426. fDimension.Fields := fDimension.Fields + [ffX];
  3427. fDimension.X := aWidth;
  3428. end;
  3429. if aHeight <> -1 then begin
  3430. fDimension.Fields := fDimension.Fields + [ffY];
  3431. fDimension.Y := aHeight;
  3432. end;
  3433. s := TFormatDescriptor.Get(aFormat).PixelSize;
  3434. fFormat := aFormat;
  3435. fPixelSize := Ceil(s);
  3436. fRowSize := Ceil(s * aWidth);
  3437. end;
  3438. end;
  3439. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3440. function TglBitmap.FlipHorz: Boolean;
  3441. begin
  3442. result := false;
  3443. end;
  3444. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3445. function TglBitmap.FlipVert: Boolean;
  3446. begin
  3447. result := false;
  3448. end;
  3449. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3450. //TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3451. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3452. procedure TglBitmap.AfterConstruction;
  3453. begin
  3454. inherited AfterConstruction;
  3455. fID := 0;
  3456. fTarget := 0;
  3457. fIsResident := false;
  3458. fFormat := glBitmapGetDefaultFormat;
  3459. fMipMap := glBitmapDefaultMipmap;
  3460. fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
  3461. fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
  3462. glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
  3463. glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
  3464. end;
  3465. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3466. procedure TglBitmap.BeforeDestruction;
  3467. begin
  3468. SetDataPointer(nil, tfEmpty);
  3469. if (fID > 0) and fDeleteTextureOnFree then
  3470. glDeleteTextures(1, @fID);
  3471. inherited BeforeDestruction;
  3472. end;
  3473. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3474. procedure TglBitmap.LoadFromFile(const aFilename: String);
  3475. var
  3476. fs: TFileStream;
  3477. begin
  3478. fFilename := aFilename;
  3479. fs := TFileStream.Create(fFilename, fmOpenRead);
  3480. try
  3481. fs.Position := 0;
  3482. LoadFromStream(fs);
  3483. finally
  3484. fs.Free;
  3485. end;
  3486. end;
  3487. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3488. procedure TglBitmap.LoadFromStream(const aStream: TStream);
  3489. begin
  3490. {$IFDEF GLB_SUPPORT_PNG_READ}
  3491. if not LoadPNG(aStream) then
  3492. {$ENDIF}
  3493. {$IFDEF GLB_SUPPORT_JPEG_READ}
  3494. if not LoadJPEG(aStream) then
  3495. {$ENDIF}
  3496. if not LoadDDS(aStream) then
  3497. if not LoadTGA(aStream) then
  3498. if not LoadBMP(aStream) then
  3499. raise EglBitmapException.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
  3500. end;
  3501. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3502. procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
  3503. const aFormat: TglBitmapFormat; const aArgs: PtrInt);
  3504. var
  3505. tmpData: PByte;
  3506. size: Integer;
  3507. begin
  3508. size := TFormatDescriptor.Get(aFormat).GetSize(aSize);
  3509. GetMem(tmpData, size);
  3510. try
  3511. FillChar(tmpData^, size, #$FF);
  3512. SetDataPointer(tmpData, aFormat, aSize.X, aSize.Y);
  3513. except
  3514. FreeMem(tmpData);
  3515. raise;
  3516. end;
  3517. AddFunc(Self, aFunc, false, Format, aArgs);
  3518. end;
  3519. {$IFDEF GLB_DELPHI}
  3520. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3521. procedure TglBitmap.LoadFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil);
  3522. var
  3523. rs: TResourceStream;
  3524. TempPos: Integer;
  3525. ResTypeStr: String;
  3526. TempResType: PChar;
  3527. begin
  3528. if not Assigned(ResType) then begin
  3529. TempPos := Pos('.', Resource);
  3530. ResTypeStr := UpperCase(Copy(Resource, TempPos + 1, Length(Resource) - TempPos));
  3531. Resource := UpperCase(Copy(Resource, 0, TempPos -1));
  3532. TempResType := PChar(ResTypeStr);
  3533. end else
  3534. TempResType := ResType
  3535. rs := TResourceStream.Create(Instance, Resource, TempResType);
  3536. try
  3537. LoadFromStream(rs);
  3538. finally
  3539. rs.Free;
  3540. end;
  3541. end;
  3542. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3543. procedure TglBitmap.LoadFromResourceID(const sInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
  3544. var
  3545. rs: TResourceStream;
  3546. begin
  3547. rs := TResourceStream.CreateFromID(Instance, ResourceID, ResType);
  3548. try
  3549. LoadFromStream(rs);
  3550. finally
  3551. rs.Free;
  3552. end;
  3553. end;
  3554. {$ENDIF}
  3555. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3556. procedure TglBitmap.SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
  3557. var
  3558. fs: TFileStream;
  3559. begin
  3560. fs := TFileStream.Create(aFileName, fmCreate);
  3561. try
  3562. fs.Position := 0;
  3563. SaveToStream(fs, aFileType);
  3564. finally
  3565. fs.Free;
  3566. end;
  3567. end;
  3568. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3569. procedure TglBitmap.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
  3570. begin
  3571. case aFileType of
  3572. {$IFDEF GLB_SUPPORT_PNG_WRITE}
  3573. ftPNG: SavePng(aStream);
  3574. {$ENDIF}
  3575. {$IFDEF GLB_SUPPORT_JPEG_WRITE}
  3576. ftJPEG: SaveJPEG(aStream);
  3577. {$ENDIF}
  3578. ftDDS: SaveDDS(aStream);
  3579. ftTGA: SaveTGA(aStream);
  3580. ftBMP: SaveBMP(aStream);
  3581. end;
  3582. end;
  3583. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3584. function TglBitmap.AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: PtrInt): Boolean;
  3585. begin
  3586. result := AddFunc(Self, aFunc, aCreateTemp, Format, aArgs);
  3587. end;
  3588. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3589. function TglBitmap.AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
  3590. const aFormat: TglBitmapFormat; const aArgs: PtrInt): Boolean;
  3591. var
  3592. DestData, TmpData, SourceData: pByte;
  3593. TempHeight, TempWidth: Integer;
  3594. SourceFD, DestFD: TFormatDescriptor;
  3595. SourceMD, DestMD: Pointer;
  3596. FuncRec: TglBitmapFunctionRec;
  3597. begin
  3598. Assert(Assigned(Data));
  3599. Assert(Assigned(aSource));
  3600. Assert(Assigned(aSource.Data));
  3601. result := false;
  3602. if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
  3603. SourceFD := TFormatDescriptor.Get(aSource.Format);
  3604. DestFD := TFormatDescriptor.Get(aFormat);
  3605. // inkompatible Formats so CreateTemp
  3606. if (SourceFD.PixelSize <> DestFD.PixelSize) then
  3607. aCreateTemp := true;
  3608. // Values
  3609. TempHeight := Max(1, aSource.Height);
  3610. TempWidth := Max(1, aSource.Width);
  3611. FuncRec.Sender := Self;
  3612. FuncRec.Args := aArgs;
  3613. TmpData := nil;
  3614. if aCreateTemp then begin
  3615. GetMem(TmpData, TFormatDescriptor.Get(aFormat).GetSize(TempWidth, TempHeight));
  3616. DestData := TmpData;
  3617. end else
  3618. DestData := Data;
  3619. try
  3620. SourceFD.PreparePixel(FuncRec.Source);
  3621. DestFD.PreparePixel (FuncRec.Dest);
  3622. SourceMD := SourceFD.CreateMappingData;
  3623. DestMD := DestFD.CreateMappingData;
  3624. FuncRec.Size := aSource.Dimension;
  3625. FuncRec.Position.Fields := FuncRec.Size.Fields;
  3626. try
  3627. SourceData := aSource.Data;
  3628. FuncRec.Position.Y := 0;
  3629. while FuncRec.Position.Y < TempHeight do begin
  3630. FuncRec.Position.X := 0;
  3631. while FuncRec.Position.X < TempWidth do begin
  3632. SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
  3633. aFunc(FuncRec);
  3634. DestFD.Map(FuncRec.Dest, DestData, DestMD);
  3635. inc(FuncRec.Position.X);
  3636. end;
  3637. inc(FuncRec.Position.Y);
  3638. end;
  3639. // Updating Image or InternalFormat
  3640. if aCreateTemp then
  3641. SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height)
  3642. else if (aFormat <> fFormat) then
  3643. Format := aFormat;
  3644. result := true;
  3645. finally
  3646. SourceFD.FreeMappingData(SourceMD);
  3647. DestFD.FreeMappingData(DestMD);
  3648. end;
  3649. except
  3650. if aCreateTemp then
  3651. FreeMem(TmpData);
  3652. raise;
  3653. end;
  3654. end;
  3655. end;
  3656. {$IFDEF GLB_SDL}
  3657. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3658. function TglBitmap.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
  3659. var
  3660. Row, RowSize: Integer;
  3661. SourceData, TmpData: PByte;
  3662. TempDepth: Integer;
  3663. Pix: TglBitmapPixelData;
  3664. FormatDesc: TglBitmapFormatDescriptor;
  3665. function GetRowPointer(Row: Integer): pByte;
  3666. begin
  3667. result := Surface.pixels;
  3668. Inc(result, Row * RowSize);
  3669. end;
  3670. begin
  3671. result := false;
  3672. (* TODO
  3673. if not FormatIsUncompressed(InternalFormat) then
  3674. raise EglBitmapUnsupportedInternalFormat.Create('AssignToSurface - ' + UNSUPPORTED_INTERNAL_FORMAT);
  3675. *)
  3676. FormatDesc := FORMAT_DESCRIPTORS[Format];
  3677. if Assigned(Data) then begin
  3678. case Trunc(FormatDesc.GetSize) of
  3679. 1: TempDepth := 8;
  3680. 2: TempDepth := 16;
  3681. 3: TempDepth := 24;
  3682. 4: TempDepth := 32;
  3683. else
  3684. raise EglBitmapException.Create('AssignToSurface - ' + UNSUPPORTED_INTERNAL_FORMAT);
  3685. end;
  3686. FormatDesc.PreparePixel(Pix);
  3687. with Pix.PixelDesc do
  3688. Surface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
  3689. RedRange shl RedShift, GreenRange shl GreenShift, BlueRange shl BlueShift, AlphaRange shl AlphaShift);
  3690. SourceData := Data;
  3691. RowSize := Ceil(FileWidth * FormatDesc.GetSize);
  3692. for Row := 0 to FileHeight -1 do begin
  3693. TmpData := GetRowPointer(Row);
  3694. if Assigned(TmpData) then begin
  3695. Move(SourceData^, TmpData^, RowSize);
  3696. inc(SourceData, RowSize);
  3697. end;
  3698. end;
  3699. result := true;
  3700. end;
  3701. end;
  3702. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3703. function TglBitmap.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
  3704. var
  3705. pSource, pData, pTempData: PByte;
  3706. Row, RowSize, TempWidth, TempHeight: Integer;
  3707. IntFormat, f: TglBitmapInternalFormat;
  3708. FormatDesc: TglBitmapFormatDescriptor;
  3709. function GetRowPointer(Row: Integer): pByte;
  3710. begin
  3711. result := Surface^.pixels;
  3712. Inc(result, Row * RowSize);
  3713. end;
  3714. begin
  3715. result := false;
  3716. if (Assigned(Surface)) then begin
  3717. with Surface^.format^ do begin
  3718. IntFormat := tfEmpty;
  3719. for f := Low(f) to High(f) do begin
  3720. if FORMAT_DESCRIPTORS[f].MaskMatch(RMask, GMask, BMask, AMask) then begin
  3721. IntFormat := f;
  3722. break;
  3723. end;
  3724. end;
  3725. if (IntFormat = tfEmpty) then
  3726. raise EglBitmapException.Create('AssignFromSurface - Invalid Pixelformat.');
  3727. end;
  3728. FormatDesc := FORMAT_DESCRIPTORS[IntFormat];
  3729. TempWidth := Surface^.w;
  3730. TempHeight := Surface^.h;
  3731. RowSize := Trunc(TempWidth * FormatDesc.GetSize);
  3732. GetMem(pData, TempHeight * RowSize);
  3733. try
  3734. pTempData := pData;
  3735. for Row := 0 to TempHeight -1 do begin
  3736. pSource := GetRowPointer(Row);
  3737. if (Assigned(pSource)) then begin
  3738. Move(pSource^, pTempData^, RowSize);
  3739. Inc(pTempData, RowSize);
  3740. end;
  3741. end;
  3742. SetDataPointer(pData, IntFormat, TempWidth, TempHeight);
  3743. result := true;
  3744. except
  3745. FreeMem(pData);
  3746. raise;
  3747. end;
  3748. end;
  3749. end;
  3750. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3751. function TglBitmap.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
  3752. var
  3753. Row, Col, AlphaInterleave: Integer;
  3754. pSource, pDest: PByte;
  3755. function GetRowPointer(Row: Integer): pByte;
  3756. begin
  3757. result := aSurface.pixels;
  3758. Inc(result, Row * Width);
  3759. end;
  3760. begin
  3761. result := false;
  3762. if Assigned(Data) then begin
  3763. if Format in [tfAlpha8, tfLuminance8Alpha8, tfBGRA8, tfRGBA8] then begin
  3764. aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
  3765. AlphaInterleave := 0;
  3766. case Format of
  3767. ifLuminance8Alpha8:
  3768. AlphaInterleave := 1;
  3769. ifBGRA8, ifRGBA8:
  3770. AlphaInterleave := 3;
  3771. end;
  3772. pSource := Data;
  3773. for Row := 0 to Height -1 do begin
  3774. pDest := GetRowPointer(Row);
  3775. if Assigned(pDest) then begin
  3776. for Col := 0 to Width -1 do begin
  3777. Inc(pSource, AlphaInterleave);
  3778. pDest^ := pSource^;
  3779. Inc(pDest);
  3780. Inc(pSource);
  3781. end;
  3782. end;
  3783. end;
  3784. result := true;
  3785. end;
  3786. end;
  3787. end;
  3788. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3789. function TglBitmap.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
  3790. var
  3791. bmp: TglBitmap2D;
  3792. begin
  3793. bmp := TglBitmap2D.Create;
  3794. try
  3795. bmp.AssignFromSurface(Surface);
  3796. result := AddAlphaFromGlBitmap(bmp, Func, CustomData);
  3797. finally
  3798. bmp.Free;
  3799. end;
  3800. end;
  3801. {$ENDIF}
  3802. {$IFDEF GLB_DELPHI}
  3803. //TODO rework & test
  3804. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3805. function TglBitmap.AssignToBitmap(const aBitmap: TBitmap): Boolean;
  3806. var
  3807. Row: Integer;
  3808. pSource, pData: PByte;
  3809. begin
  3810. result := false;
  3811. if Assigned(Data) then begin
  3812. if Assigned(aBitmap) then begin
  3813. aBitmap.Width := Width;
  3814. aBitmap.Height := Height;
  3815. case Format of
  3816. tfAlpha8, ifLuminance, ifDepth8:
  3817. begin
  3818. Bitmap.PixelFormat := pf8bit;
  3819. Bitmap.Palette := CreateGrayPalette;
  3820. end;
  3821. ifRGB5A1:
  3822. Bitmap.PixelFormat := pf15bit;
  3823. ifR5G6B5:
  3824. Bitmap.PixelFormat := pf16bit;
  3825. ifRGB8, ifBGR8:
  3826. Bitmap.PixelFormat := pf24bit;
  3827. ifRGBA8, ifBGRA8:
  3828. Bitmap.PixelFormat := pf32bit;
  3829. else
  3830. raise EglBitmapException.Create('AssignToBitmap - Invalid Pixelformat.');
  3831. end;
  3832. pSource := Data;
  3833. for Row := 0 to FileHeight -1 do begin
  3834. pData := Bitmap.Scanline[Row];
  3835. Move(pSource^, pData^, fRowSize);
  3836. Inc(pSource, fRowSize);
  3837. // swap RGB(A) to BGR(A)
  3838. if InternalFormat in [ifRGB8, ifRGBA8] then
  3839. SwapRGB(pData, FileWidth, InternalFormat = ifRGBA8);
  3840. end;
  3841. result := true;
  3842. end;
  3843. end;
  3844. end;
  3845. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3846. function TglBitmap.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
  3847. var
  3848. pSource, pData, pTempData: PByte;
  3849. Row, RowSize, TempWidth, TempHeight: Integer;
  3850. IntFormat: TglBitmapInternalFormat;
  3851. begin
  3852. result := false;
  3853. if (Assigned(Bitmap)) then begin
  3854. case Bitmap.PixelFormat of
  3855. pf8bit:
  3856. IntFormat := ifLuminance;
  3857. pf15bit:
  3858. IntFormat := ifRGB5A1;
  3859. pf16bit:
  3860. IntFormat := ifR5G6B5;
  3861. pf24bit:
  3862. IntFormat := ifBGR8;
  3863. pf32bit:
  3864. IntFormat := ifBGRA8;
  3865. else
  3866. raise EglBitmapException.Create('AssignFromBitmap - Invalid Pixelformat.');
  3867. end;
  3868. TempWidth := Bitmap.Width;
  3869. TempHeight := Bitmap.Height;
  3870. RowSize := Trunc(TempWidth * FormatGetSize(IntFormat));
  3871. GetMem(pData, TempHeight * RowSize);
  3872. try
  3873. pTempData := pData;
  3874. for Row := 0 to TempHeight -1 do begin
  3875. pSource := Bitmap.Scanline[Row];
  3876. if (Assigned(pSource)) then begin
  3877. Move(pSource^, pTempData^, RowSize);
  3878. Inc(pTempData, RowSize);
  3879. end;
  3880. end;
  3881. SetDataPointer(pData, IntFormat, TempWidth, TempHeight);
  3882. result := true;
  3883. except
  3884. FreeMem(pData);
  3885. raise;
  3886. end;
  3887. end;
  3888. end;
  3889. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3890. function TglBitmap.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
  3891. var
  3892. Row, Col, AlphaInterleave: Integer;
  3893. pSource, pDest: PByte;
  3894. begin
  3895. result := false;
  3896. if Assigned(Data) then begin
  3897. if InternalFormat in [ifAlpha, ifLuminanceAlpha, ifRGBA8, ifBGRA8] then begin
  3898. if Assigned(Bitmap) then begin
  3899. Bitmap.PixelFormat := pf8bit;
  3900. Bitmap.Palette := CreateGrayPalette;
  3901. Bitmap.Width := Width;
  3902. Bitmap.Height := Height;
  3903. case InternalFormat of
  3904. ifLuminanceAlpha:
  3905. AlphaInterleave := 1;
  3906. ifRGBA8, ifBGRA8:
  3907. AlphaInterleave := 3;
  3908. else
  3909. AlphaInterleave := 0;
  3910. end;
  3911. // Copy Data
  3912. pSource := Data;
  3913. for Row := 0 to Height -1 do begin
  3914. pDest := Bitmap.Scanline[Row];
  3915. if Assigned(pDest) then begin
  3916. for Col := 0 to Width -1 do begin
  3917. Inc(pSource, AlphaInterleave);
  3918. pDest^ := pSource^;
  3919. Inc(pDest);
  3920. Inc(pSource);
  3921. end;
  3922. end;
  3923. end;
  3924. result := true;
  3925. end;
  3926. end;
  3927. end;
  3928. end;
  3929. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3930. function TglBitmap.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
  3931. var
  3932. tex: TglBitmap2D;
  3933. begin
  3934. tex := TglBitmap2D.Create;
  3935. try
  3936. tex.AssignFromBitmap(Bitmap);
  3937. result := AddAlphaFromglBitmap(tex, Func, CustomData);
  3938. finally
  3939. tex.Free;
  3940. end;
  3941. end;
  3942. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3943. function TglBitmap.AddAlphaFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar;
  3944. const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
  3945. var
  3946. RS: TResourceStream;
  3947. TempPos: Integer;
  3948. ResTypeStr: String;
  3949. TempResType: PChar;
  3950. begin
  3951. if Assigned(ResType) then
  3952. TempResType := ResType
  3953. else
  3954. begin
  3955. TempPos := Pos('.', Resource);
  3956. ResTypeStr := UpperCase(Copy(Resource, TempPos + 1, Length(Resource) - TempPos));
  3957. Resource := UpperCase(Copy(Resource, 0, TempPos -1));
  3958. TempResType := PChar(ResTypeStr);
  3959. end;
  3960. RS := TResourceStream.Create(Instance, Resource, TempResType);
  3961. try
  3962. result := AddAlphaFromStream(RS, Func, CustomData);
  3963. finally
  3964. RS.Free;
  3965. end;
  3966. end;
  3967. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3968. function TglBitmap.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
  3969. const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
  3970. var
  3971. RS: TResourceStream;
  3972. begin
  3973. RS := TResourceStream.CreateFromID(Instance, ResourceID, ResType);
  3974. try
  3975. result := AddAlphaFromStream(RS, Func, CustomData);
  3976. finally
  3977. RS.Free;
  3978. end;
  3979. end;
  3980. {$ENDIF}
  3981. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3982. function TglBitmap.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
  3983. begin
  3984. (* TODO
  3985. if not FormatIsUncompressed(InternalFormat) then
  3986. raise EglBitmapUnsupportedFormatFormat.Create('AddAlphaFromFunc - ' + UNSUPPORTED_FORMAT);
  3987. *)
  3988. result := AddFunc(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs);
  3989. end;
  3990. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3991. function TglBitmap.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
  3992. var
  3993. FS: TFileStream;
  3994. begin
  3995. FS := TFileStream.Create(FileName, fmOpenRead);
  3996. try
  3997. result := AddAlphaFromStream(FS, aFunc, aArgs);
  3998. finally
  3999. FS.Free;
  4000. end;
  4001. end;
  4002. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4003. function TglBitmap.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
  4004. var
  4005. tex: TglBitmap2D;
  4006. begin
  4007. tex := TglBitmap2D.Create(aStream);
  4008. try
  4009. result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
  4010. finally
  4011. tex.Free;
  4012. end;
  4013. end;
  4014. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4015. function TglBitmap.AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
  4016. var
  4017. DestData, DestData2, SourceData: pByte;
  4018. TempHeight, TempWidth: Integer;
  4019. SourceFD, DestFD: TFormatDescriptor;
  4020. SourceMD, DestMD, DestMD2: Pointer;
  4021. FuncRec: TglBitmapFunctionRec;
  4022. begin
  4023. result := false;
  4024. Assert(Assigned(Data));
  4025. Assert(Assigned(aBitmap));
  4026. Assert(Assigned(aBitmap.Data));
  4027. if ((aBitmap.Width = Width) and (aBitmap.Height = Height)) then begin
  4028. result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
  4029. if not Assigned(aFunc) then
  4030. aFunc := glBitmapAlphaFunc;
  4031. SourceFD := TFormatDescriptor.Get(aBitmap.Format);
  4032. DestFD := TFormatDescriptor.Get(Format);
  4033. // Values
  4034. TempHeight := aBitmap.FileHeight;
  4035. TempWidth := aBitmap.FileWidth;
  4036. FuncRec.Sender := Self;
  4037. FuncRec.Args := aArgs;
  4038. FuncRec.Size := Dimension;
  4039. FuncRec.Position.Fields := FuncRec.Size.Fields;
  4040. FuncRec.Args := PtrInt(SourceFD.HasAlpha) and 1;
  4041. DestData := Data;
  4042. DestData2 := Data;
  4043. SourceData := aBitmap.Data;
  4044. // Mapping
  4045. SourceFD.PreparePixel(FuncRec.Source);
  4046. DestFD.PreparePixel (FuncRec.Dest);
  4047. SourceMD := SourceFD.CreateMappingData;
  4048. DestMD := DestFD.CreateMappingData;
  4049. DestMD2 := DestFD.CreateMappingData;
  4050. try
  4051. FuncRec.Position.Y := 0;
  4052. while FuncRec.Position.Y < TempHeight do begin
  4053. FuncRec.Position.X := 0;
  4054. while FuncRec.Position.X < TempWidth do begin
  4055. SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
  4056. DestFD.Unmap (DestData, FuncRec.Dest, DestMD);
  4057. aFunc(FuncRec);
  4058. DestFD.Map(FuncRec.Dest, DestData2, DestMD2);
  4059. inc(FuncRec.Position.X);
  4060. end;
  4061. inc(FuncRec.Position.Y);
  4062. end;
  4063. finally
  4064. SourceFD.FreeMappingData(SourceMD);
  4065. DestFD.FreeMappingData(DestMD);
  4066. DestFD.FreeMappingData(DestMD2);
  4067. end;
  4068. end;
  4069. end;
  4070. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4071. function TglBitmap.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
  4072. begin
  4073. result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
  4074. end;
  4075. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4076. function TglBitmap.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
  4077. var
  4078. PixelData: TglBitmapPixelData;
  4079. begin
  4080. TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
  4081. result := AddAlphaFromColorKeyFloat(
  4082. aRed / PixelData.Range.r,
  4083. aGreen / PixelData.Range.g,
  4084. aBlue / PixelData.Range.b,
  4085. aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b)));
  4086. end;
  4087. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4088. function TglBitmap.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
  4089. var
  4090. values: array[0..2] of Single;
  4091. tmp: Cardinal;
  4092. i: Integer;
  4093. PixelData: TglBitmapPixelData;
  4094. begin
  4095. TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
  4096. with PixelData do begin
  4097. values[0] := aRed;
  4098. values[1] := aGreen;
  4099. values[2] := aBlue;
  4100. for i := 0 to 2 do begin
  4101. tmp := Trunc(Range.arr[i] * aDeviation);
  4102. Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp));
  4103. Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp));
  4104. end;
  4105. Data.a := 0;
  4106. Range.a := 0;
  4107. end;
  4108. result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, PtrInt(@PixelData));
  4109. end;
  4110. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4111. function TglBitmap.AddAlphaFromValue(const aAlpha: Byte): Boolean;
  4112. begin
  4113. result := AddAlphaFromValueFloat(aAlpha / $FF);
  4114. end;
  4115. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4116. function TglBitmap.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
  4117. var
  4118. PixelData: TglBitmapPixelData;
  4119. begin
  4120. TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
  4121. result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
  4122. end;
  4123. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4124. function TglBitmap.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
  4125. var
  4126. PixelData: TglBitmapPixelData;
  4127. begin
  4128. TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
  4129. with PixelData do
  4130. Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
  4131. result := AddAlphaFromFunc(glBitmapValueAlphaFunc, PtrInt(@PixelData.Data.a));
  4132. end;
  4133. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4134. function TglBitmap.RemoveAlpha: Boolean;
  4135. var
  4136. FormatDesc: TFormatDescriptor;
  4137. begin
  4138. result := false;
  4139. FormatDesc := TFormatDescriptor.Get(Format);
  4140. if Assigned(Data) then begin
  4141. if not ({FormatDesc.IsUncompressed or }FormatDesc.HasAlpha) then
  4142. raise EglBitmapUnsupportedFormatFormat.Create('RemoveAlpha - ' + UNSUPPORTED_FORMAT);
  4143. result := ConvertTo(FormatDesc.WithoutAlpha);
  4144. end;
  4145. end;
  4146. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4147. function TglBitmap.Clone: TglBitmap;
  4148. var
  4149. Temp: TglBitmap;
  4150. TempPtr: PByte;
  4151. Size: Integer;
  4152. begin
  4153. result := nil;
  4154. Temp := (ClassType.Create as TglBitmap);
  4155. try
  4156. // copy texture data if assigned
  4157. if Assigned(Data) then begin
  4158. Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
  4159. GetMem(TempPtr, Size);
  4160. try
  4161. Move(Data^, TempPtr^, Size);
  4162. Temp.SetDataPointer(TempPtr, Format, Width, Height);
  4163. except
  4164. FreeMem(TempPtr);
  4165. raise;
  4166. end;
  4167. end else
  4168. Temp.SetDataPointer(nil, Format, Width, Height);
  4169. // copy properties
  4170. Temp.fID := ID;
  4171. Temp.fTarget := Target;
  4172. Temp.fFormat := Format;
  4173. Temp.fMipMap := MipMap;
  4174. Temp.fAnisotropic := Anisotropic;
  4175. Temp.fBorderColor := fBorderColor;
  4176. Temp.fDeleteTextureOnFree := DeleteTextureOnFree;
  4177. Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
  4178. Temp.fFilterMin := fFilterMin;
  4179. Temp.fFilterMag := fFilterMag;
  4180. Temp.fWrapS := fWrapS;
  4181. Temp.fWrapT := fWrapT;
  4182. Temp.fWrapR := fWrapR;
  4183. Temp.fFilename := fFilename;
  4184. Temp.fCustomName := fCustomName;
  4185. Temp.fCustomNameW := fCustomNameW;
  4186. Temp.fCustomData := fCustomData;
  4187. result := Temp;
  4188. except
  4189. FreeAndNil(Temp);
  4190. raise;
  4191. end;
  4192. end;
  4193. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4194. function TglBitmap.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
  4195. var
  4196. SourceFD, DestFD: TFormatDescriptor;
  4197. SourcePD, DestPD: TglBitmapPixelData;
  4198. ShiftData: TShiftData;
  4199. function CanCopyDirect: Boolean;
  4200. begin
  4201. result :=
  4202. ((SourcePD.Range.r = DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
  4203. ((SourcePD.Range.g = DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
  4204. ((SourcePD.Range.b = DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
  4205. ((SourcePD.Range.a = DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
  4206. end;
  4207. function CanShift: Boolean;
  4208. begin
  4209. result :=
  4210. ((SourcePD.Range.r >= DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
  4211. ((SourcePD.Range.g >= DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
  4212. ((SourcePD.Range.b >= DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
  4213. ((SourcePD.Range.a >= DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
  4214. end;
  4215. function GetShift(aSource, aDest: Cardinal) : ShortInt;
  4216. begin
  4217. result := 0;
  4218. while (aSource > aDest) and (aSource > 0) do begin
  4219. inc(result);
  4220. aSource := aSource shr 1;
  4221. end;
  4222. end;
  4223. begin
  4224. if (aFormat <> fFormat) and (aFormat <> tfEmpty) then begin
  4225. SourceFD := TFormatDescriptor.Get(Format);
  4226. DestFD := TFormatDescriptor.Get(aFormat);
  4227. SourceFD.PreparePixel(SourcePD);
  4228. DestFD.PreparePixel (DestPD);
  4229. if CanCopyDirect then
  4230. result := AddFunc(Self, glBitmapConvertCopyFunc, false, aFormat)
  4231. else if CanShift then begin
  4232. ShiftData.r := GetShift(SourcePD.Range.r, DestPD.Range.r);
  4233. ShiftData.g := GetShift(SourcePD.Range.g, DestPD.Range.g);
  4234. ShiftData.b := GetShift(SourcePD.Range.b, DestPD.Range.b);
  4235. ShiftData.a := GetShift(SourcePD.Range.a, DestPD.Range.a);
  4236. result := AddFunc(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, PtrInt(@ShiftData));
  4237. end else
  4238. result := AddFunc(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
  4239. end else
  4240. result := true;
  4241. end;
  4242. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4243. procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
  4244. begin
  4245. if aUseRGB or aUseAlpha then
  4246. AddFunc(glBitmapInvertFunc, false, ((PtrInt(aUseAlpha) and 1) shl 1) or (PtrInt(aUseRGB) and 1));
  4247. end;
  4248. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4249. procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
  4250. begin
  4251. fBorderColor[0] := aRed;
  4252. fBorderColor[1] := aGreen;
  4253. fBorderColor[2] := aBlue;
  4254. fBorderColor[3] := aAlpha;
  4255. if (ID > 0) then begin
  4256. Bind(false);
  4257. glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
  4258. end;
  4259. end;
  4260. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4261. procedure TglBitmap.FreeData;
  4262. begin
  4263. SetDataPointer(nil, tfEmpty);
  4264. end;
  4265. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4266. procedure TglBitmap.FillWithColor(const aRed, aGreen, aBlue: Byte;
  4267. const aAlpha: Byte);
  4268. begin
  4269. FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
  4270. end;
  4271. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4272. procedure TglBitmap.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
  4273. var
  4274. PixelData: TglBitmapPixelData;
  4275. begin
  4276. TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
  4277. FillWithColorFloat(
  4278. aRed / PixelData.Range.r,
  4279. aGreen / PixelData.Range.g,
  4280. aBlue / PixelData.Range.b,
  4281. aAlpha / PixelData.Range.a);
  4282. end;
  4283. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4284. procedure TglBitmap.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
  4285. var
  4286. PixelData: TglBitmapPixelData;
  4287. begin
  4288. TFormatDescriptor.Get(Format).PreparePixel(PixelData);
  4289. with PixelData do begin
  4290. Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed)));
  4291. Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen)));
  4292. Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue)));
  4293. Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha)));
  4294. end;
  4295. AddFunc(glBitmapFillWithColorFunc, false, PtrInt(@PixelData));
  4296. end;
  4297. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4298. procedure TglBitmap.SetFilter(const aMin, aMag: Cardinal);
  4299. begin
  4300. //check MIN filter
  4301. case aMin of
  4302. GL_NEAREST:
  4303. fFilterMin := GL_NEAREST;
  4304. GL_LINEAR:
  4305. fFilterMin := GL_LINEAR;
  4306. GL_NEAREST_MIPMAP_NEAREST:
  4307. fFilterMin := GL_NEAREST_MIPMAP_NEAREST;
  4308. GL_LINEAR_MIPMAP_NEAREST:
  4309. fFilterMin := GL_LINEAR_MIPMAP_NEAREST;
  4310. GL_NEAREST_MIPMAP_LINEAR:
  4311. fFilterMin := GL_NEAREST_MIPMAP_LINEAR;
  4312. GL_LINEAR_MIPMAP_LINEAR:
  4313. fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
  4314. else
  4315. raise EglBitmapException.Create('SetFilter - Unknow MIN filter.');
  4316. end;
  4317. //check MAG filter
  4318. case aMag of
  4319. GL_NEAREST:
  4320. fFilterMag := GL_NEAREST;
  4321. GL_LINEAR:
  4322. fFilterMag := GL_LINEAR;
  4323. else
  4324. raise EglBitmapException.Create('SetFilter - Unknow MAG filter.');
  4325. end;
  4326. //apply filter
  4327. if (ID > 0) then begin
  4328. Bind(false);
  4329. glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
  4330. if (MipMap = mmNone) or (Target = GL_TEXTURE_RECTANGLE) then begin
  4331. case fFilterMin of
  4332. GL_NEAREST, GL_LINEAR:
  4333. glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
  4334. GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR:
  4335. glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  4336. GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR:
  4337. glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  4338. end;
  4339. end else
  4340. glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
  4341. end;
  4342. end;
  4343. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4344. procedure TglBitmap.SetWrap(const S: Cardinal; const T: Cardinal; const R: Cardinal);
  4345. procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
  4346. begin
  4347. case aValue of
  4348. GL_CLAMP:
  4349. aTarget := GL_CLAMP;
  4350. GL_REPEAT:
  4351. aTarget := GL_REPEAT;
  4352. GL_CLAMP_TO_EDGE: begin
  4353. if GL_VERSION_1_2 or GL_EXT_texture_edge_clamp then
  4354. aTarget := GL_CLAMP_TO_EDGE
  4355. else
  4356. aTarget := GL_CLAMP;
  4357. end;
  4358. GL_CLAMP_TO_BORDER: begin
  4359. if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
  4360. aTarget := GL_CLAMP_TO_BORDER
  4361. else
  4362. aTarget := GL_CLAMP;
  4363. end;
  4364. GL_MIRRORED_REPEAT: begin
  4365. if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
  4366. aTarget := GL_MIRRORED_REPEAT
  4367. else
  4368. raise EglBitmapException.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
  4369. end;
  4370. else
  4371. raise EglBitmapException.Create('SetWrap - Unknow Texturewrap (S).');
  4372. end;
  4373. end;
  4374. begin
  4375. CheckAndSetWrap(S, fWrapS);
  4376. CheckAndSetWrap(T, fWrapT);
  4377. CheckAndSetWrap(R, fWrapR);
  4378. if (ID > 0) then begin
  4379. Bind(false);
  4380. glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
  4381. glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
  4382. glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
  4383. end;
  4384. end;
  4385. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4386. procedure TglBitmap.GetPixel(const aPos: TglBitmapPixelPosition; var aPixel: TglBitmapPixelData);
  4387. begin
  4388. { TODO delete?
  4389. if Assigned (fGetPixelFunc) then
  4390. fGetPixelFunc(aPos, aPixel);
  4391. }
  4392. end;
  4393. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4394. procedure TglBitmap.SetPixel(const aPos: TglBitmapPixelPosition; const aPixel: TglBitmapPixelData);
  4395. begin
  4396. {TODO delete?
  4397. if Assigned (fSetPixelFunc) then
  4398. fSetPixelFuc(aPos, aPixel);
  4399. }
  4400. end;
  4401. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4402. procedure TglBitmap.Bind(const aEnableTextureUnit: Boolean);
  4403. begin
  4404. if aEnableTextureUnit then
  4405. glEnable(Target);
  4406. if (ID > 0) then
  4407. glBindTexture(Target, ID);
  4408. end;
  4409. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4410. procedure TglBitmap.Unbind(const aDisableTextureUnit: Boolean);
  4411. begin
  4412. if aDisableTextureUnit then
  4413. glDisable(Target);
  4414. glBindTexture(Target, 0);
  4415. end;
  4416. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4417. constructor TglBitmap.Create;
  4418. begin
  4419. {$IFNDEF GLB_NO_NATIVE_GL}
  4420. ReadOpenGLExtensions;
  4421. {$ENDIF}
  4422. if (ClassType = TglBitmap) then
  4423. raise EglBitmapException.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
  4424. inherited Create;
  4425. end;
  4426. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4427. constructor TglBitmap.Create(const aFileName: String);
  4428. begin
  4429. Create;
  4430. LoadFromFile(FileName);
  4431. end;
  4432. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4433. constructor TglBitmap.Create(const aStream: TStream);
  4434. begin
  4435. Create;
  4436. LoadFromStream(aStream);
  4437. end;
  4438. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4439. constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat);
  4440. var
  4441. Image: PByte;
  4442. ImageSize: Integer;
  4443. begin
  4444. Create;
  4445. TFormatDescriptor.Get(aFormat).GetSize(aSize);
  4446. GetMem(Image, ImageSize);
  4447. try
  4448. FillChar(Image^, ImageSize, #$FF);
  4449. SetDataPointer(Image, aFormat, aSize.X, aSize.Y);
  4450. except
  4451. FreeMem(Image);
  4452. raise;
  4453. end;
  4454. end;
  4455. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4456. constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat;
  4457. const aFunc: TglBitmapFunction; const aArgs: PtrInt);
  4458. begin
  4459. Create;
  4460. LoadFromFunc(aSize, aFunc, aFormat, aArgs);
  4461. end;
  4462. {$IFDEF GLB_DELPHI}
  4463. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4464. constructor TglBitmap.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
  4465. begin
  4466. Create;
  4467. LoadFromResource(aInstance, aResource, aResType);
  4468. end;
  4469. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4470. constructor TglBitmap.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
  4471. begin
  4472. Create;
  4473. LoadFromResourceID(aInstance, aResourceID, aResType);
  4474. end;
  4475. {$ENDIF}
  4476. {$IFDEF GLB_SUPPORT_PNG_READ}
  4477. {$IF DEFINED(GLB_SDL_IMAGE)}
  4478. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4479. //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4480. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4481. function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
  4482. var
  4483. Surface: PSDL_Surface;
  4484. RWops: PSDL_RWops;
  4485. begin
  4486. result := false;
  4487. RWops := glBitmapCreateRWops(aStream);
  4488. try
  4489. if IMG_isPNG(RWops) > 0 then begin
  4490. Surface := IMG_LoadPNG_RW(RWops);
  4491. try
  4492. AssignFromSurface(Surface);
  4493. Rresult := true;
  4494. finally
  4495. SDL_FreeSurface(Surface);
  4496. end;
  4497. end;
  4498. finally
  4499. SDL_FreeRW(RWops);
  4500. end;
  4501. end;
  4502. {$ELSEIF DEFINED(GLB_LIB_PNG)}
  4503. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4504. procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
  4505. begin
  4506. TStream(png_get_io_ptr(png)).Read(buffer^, size);
  4507. end;
  4508. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4509. function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
  4510. var
  4511. StreamPos: Int64;
  4512. signature: array [0..7] of byte;
  4513. png: png_structp;
  4514. png_info: png_infop;
  4515. TempHeight, TempWidth: Integer;
  4516. Format: TglBitmapInternalFormat;
  4517. png_data: pByte;
  4518. png_rows: array of pByte;
  4519. Row, LineSize: Integer;
  4520. begin
  4521. result := false;
  4522. if not init_libPNG then
  4523. raise Exception.Create('LoadPNG - unable to initialize libPNG.');
  4524. try
  4525. // signature
  4526. StreamPos := Stream.Position;
  4527. Stream.Read(signature, 8);
  4528. Stream.Position := StreamPos;
  4529. if png_check_sig(@signature, 8) <> 0 then begin
  4530. // png read struct
  4531. png := png_create_read_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
  4532. if png = nil then
  4533. raise EglBitmapException.Create('LoadPng - couldn''t create read struct.');
  4534. // png info
  4535. png_info := png_create_info_struct(png);
  4536. if png_info = nil then begin
  4537. png_destroy_read_struct(@png, nil, nil);
  4538. raise EglBitmapException.Create('LoadPng - couldn''t create info struct.');
  4539. end;
  4540. // set read callback
  4541. png_set_read_fn(png, stream, glBitmap_libPNG_read_func);
  4542. // read informations
  4543. png_read_info(png, png_info);
  4544. // size
  4545. TempHeight := png_get_image_height(png, png_info);
  4546. TempWidth := png_get_image_width(png, png_info);
  4547. // format
  4548. case png_get_color_type(png, png_info) of
  4549. PNG_COLOR_TYPE_GRAY:
  4550. Format := tfLuminance8;
  4551. PNG_COLOR_TYPE_GRAY_ALPHA:
  4552. Format := tfLuminance8Alpha8;
  4553. PNG_COLOR_TYPE_RGB:
  4554. Format := tfRGB8;
  4555. PNG_COLOR_TYPE_RGB_ALPHA:
  4556. Format := tfRGBA8;
  4557. else
  4558. raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
  4559. end;
  4560. // cut upper 8 bit from 16 bit formats
  4561. if png_get_bit_depth(png, png_info) > 8 then
  4562. png_set_strip_16(png);
  4563. // expand bitdepth smaller than 8
  4564. if png_get_bit_depth(png, png_info) < 8 then
  4565. png_set_expand(png);
  4566. // allocating mem for scanlines
  4567. LineSize := png_get_rowbytes(png, png_info);
  4568. GetMem(png_data, TempHeight * LineSize);
  4569. try
  4570. SetLength(png_rows, TempHeight);
  4571. for Row := Low(png_rows) to High(png_rows) do begin
  4572. png_rows[Row] := png_data;
  4573. Inc(png_rows[Row], Row * LineSize);
  4574. end;
  4575. // read complete image into scanlines
  4576. png_read_image(png, @png_rows[0]);
  4577. // read end
  4578. png_read_end(png, png_info);
  4579. // destroy read struct
  4580. png_destroy_read_struct(@png, @png_info, nil);
  4581. SetLength(png_rows, 0);
  4582. // set new data
  4583. SetDataPointer(png_data, Format, TempWidth, TempHeight);
  4584. result := true;
  4585. except
  4586. FreeMem(png_data);
  4587. raise;
  4588. end;
  4589. end;
  4590. finally
  4591. quit_libPNG;
  4592. end;
  4593. end;
  4594. {$ELSEIF DEFINED(GLB_PNGIMAGE)}
  4595. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4596. function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
  4597. var
  4598. StreamPos: Int64;
  4599. Png: TPNGObject;
  4600. Header: Array[0..7] of Byte;
  4601. Row, Col, PixSize, LineSize: Integer;
  4602. NewImage, pSource, pDest, pAlpha: pByte;
  4603. Format: TglBitmapInternalFormat;
  4604. const
  4605. PngHeader: Array[0..7] of Byte = (#137, #80, #78, #71, #13, #10, #26, #10);
  4606. begin
  4607. result := false;
  4608. StreamPos := Stream.Position;
  4609. Stream.Read(Header[0], SizeOf(Header));
  4610. Stream.Position := StreamPos;
  4611. {Test if the header matches}
  4612. if Header = PngHeader then begin
  4613. Png := TPNGObject.Create;
  4614. try
  4615. Png.LoadFromStream(Stream);
  4616. case Png.Header.ColorType of
  4617. COLOR_GRAYSCALE:
  4618. Format := ifLuminance;
  4619. COLOR_GRAYSCALEALPHA:
  4620. Format := ifLuminanceAlpha;
  4621. COLOR_RGB:
  4622. Format := ifBGR8;
  4623. COLOR_RGBALPHA:
  4624. Format := ifBGRA8;
  4625. else
  4626. raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
  4627. end;
  4628. PixSize := Trunc(FormatGetSize(Format));
  4629. LineSize := Integer(Png.Header.Width) * PixSize;
  4630. GetMem(NewImage, LineSize * Integer(Png.Header.Height));
  4631. try
  4632. pDest := NewImage;
  4633. case Png.Header.ColorType of
  4634. COLOR_RGB, COLOR_GRAYSCALE:
  4635. begin
  4636. for Row := 0 to Png.Height -1 do begin
  4637. Move (Png.Scanline[Row]^, pDest^, LineSize);
  4638. Inc(pDest, LineSize);
  4639. end;
  4640. end;
  4641. COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA:
  4642. begin
  4643. PixSize := PixSize -1;
  4644. for Row := 0 to Png.Height -1 do begin
  4645. pSource := Png.Scanline[Row];
  4646. pAlpha := pByte(Png.AlphaScanline[Row]);
  4647. for Col := 0 to Png.Width -1 do begin
  4648. Move (pSource^, pDest^, PixSize);
  4649. Inc(pSource, PixSize);
  4650. Inc(pDest, PixSize);
  4651. pDest^ := pAlpha^;
  4652. inc(pAlpha);
  4653. Inc(pDest);
  4654. end;
  4655. end;
  4656. end;
  4657. else
  4658. raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
  4659. end;
  4660. SetDataPointer(NewImage, Format, Png.Header.Width, Png.Header.Height);
  4661. result := true;
  4662. except
  4663. FreeMem(NewImage);
  4664. raise;
  4665. end;
  4666. finally
  4667. Png.Free;
  4668. end;
  4669. end;
  4670. end;
  4671. {$IFEND}
  4672. {$ENDIF}
  4673. {$IFDEF GLB_SUPPORT_PNG_WRITE}
  4674. {$IFDEF GLB_LIB_PNG}
  4675. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4676. procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
  4677. begin
  4678. TStream(png_get_io_ptr(png)).Write(buffer^, size);
  4679. end;
  4680. {$ENDIF}
  4681. {$IF DEFINED(GLB_LIB_PNG)}
  4682. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4683. procedure TglBitmap.SavePNG(const aStream: TStream);
  4684. var
  4685. png: png_structp;
  4686. png_info: png_infop;
  4687. png_rows: array of pByte;
  4688. LineSize: Integer;
  4689. ColorType: Integer;
  4690. Row: Integer;
  4691. begin
  4692. if not (ftPNG in FormatGetSupportedFiles (InternalFormat)) then
  4693. raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
  4694. if not init_libPNG then
  4695. raise Exception.Create('SavePNG - unable to initialize libPNG.');
  4696. try
  4697. case FInternalFormat of
  4698. ifAlpha, ifLuminance, ifDepth8:
  4699. ColorType := PNG_COLOR_TYPE_GRAY;
  4700. ifLuminanceAlpha:
  4701. ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
  4702. ifBGR8, ifRGB8:
  4703. ColorType := PNG_COLOR_TYPE_RGB;
  4704. ifBGRA8, ifRGBA8:
  4705. ColorType := PNG_COLOR_TYPE_RGBA;
  4706. else
  4707. raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
  4708. end;
  4709. LineSize := Trunc(FormatGetSize(FInternalFormat) * Width);
  4710. // creating array for scanline
  4711. SetLength(png_rows, Height);
  4712. try
  4713. for Row := 0 to Height - 1 do begin
  4714. png_rows[Row] := Data;
  4715. Inc(png_rows[Row], Row * LineSize)
  4716. end;
  4717. // write struct
  4718. png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
  4719. if png = nil then
  4720. raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
  4721. // create png info
  4722. png_info := png_create_info_struct(png);
  4723. if png_info = nil then begin
  4724. png_destroy_write_struct(@png, nil);
  4725. raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
  4726. end;
  4727. // set read callback
  4728. png_set_write_fn(png, stream, glBitmap_libPNG_write_func, nil);
  4729. // set compression
  4730. png_set_compression_level(png, 6);
  4731. if InternalFormat in [ifBGR8, ifBGRA8] then
  4732. png_set_bgr(png);
  4733. png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
  4734. png_write_info(png, png_info);
  4735. png_write_image(png, @png_rows[0]);
  4736. png_write_end(png, png_info);
  4737. png_destroy_write_struct(@png, @png_info);
  4738. finally
  4739. SetLength(png_rows, 0);
  4740. end;
  4741. finally
  4742. quit_libPNG;
  4743. end;
  4744. end;
  4745. {$ELSEIF DEFINED(GLB_PNGIMAGE)}
  4746. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4747. procedure TglBitmap.SavePNG(const aStream: TStream);
  4748. var
  4749. Png: TPNGObject;
  4750. pSource, pDest: pByte;
  4751. X, Y, PixSize: Integer;
  4752. ColorType: Cardinal;
  4753. Alpha: Boolean;
  4754. pTemp: pByte;
  4755. Temp: Byte;
  4756. begin
  4757. if not (ftPNG in FormatGetSupportedFiles (InternalFormat)) then
  4758. raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
  4759. case FInternalFormat of
  4760. ifAlpha, ifLuminance, ifDepth8: begin
  4761. ColorType := COLOR_GRAYSCALE;
  4762. PixSize := 1;
  4763. Alpha := false;
  4764. end;
  4765. ifLuminanceAlpha: begin
  4766. ColorType := COLOR_GRAYSCALEALPHA;
  4767. PixSize := 1;
  4768. Alpha := true;
  4769. end;
  4770. ifBGR8, ifRGB8: begin
  4771. ColorType := COLOR_RGB;
  4772. PixSize := 3;
  4773. Alpha := false;
  4774. end;
  4775. ifBGRA8, ifRGBA8: begin
  4776. ColorType := COLOR_RGBALPHA;
  4777. PixSize := 3;
  4778. Alpha := true
  4779. end;
  4780. else
  4781. raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
  4782. end;
  4783. Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
  4784. try
  4785. // Copy ImageData
  4786. pSource := Data;
  4787. for Y := 0 to Height -1 do begin
  4788. pDest := png.ScanLine[Y];
  4789. for X := 0 to Width -1 do begin
  4790. Move(pSource^, pDest^, PixSize);
  4791. Inc(pDest, PixSize);
  4792. Inc(pSource, PixSize);
  4793. if Alpha then begin
  4794. png.AlphaScanline[Y]^[X] := pSource^;
  4795. Inc(pSource);
  4796. end;
  4797. end;
  4798. // convert RGB line to BGR
  4799. if InternalFormat in [ifRGB8, ifRGBA8] then begin
  4800. pTemp := png.ScanLine[Y];
  4801. for X := 0 to Width -1 do begin
  4802. Temp := pByteArray(pTemp)^[0];
  4803. pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
  4804. pByteArray(pTemp)^[2] := Temp;
  4805. Inc(pTemp, 3);
  4806. end;
  4807. end;
  4808. end;
  4809. // Save to Stream
  4810. Png.CompressionLevel := 6;
  4811. Png.SaveToStream(Stream);
  4812. finally
  4813. FreeAndNil(Png);
  4814. end;
  4815. end;
  4816. {$IFEND}
  4817. {$ENDIF}
  4818. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4819. //JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4820. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4821. {$IFDEF GLB_LIB_JPEG}
  4822. type
  4823. glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
  4824. glBitmap_libJPEG_source_mgr = record
  4825. pub: jpeg_source_mgr;
  4826. SrcStream: TStream;
  4827. SrcBuffer: array [1..4096] of byte;
  4828. end;
  4829. glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
  4830. glBitmap_libJPEG_dest_mgr = record
  4831. pub: jpeg_destination_mgr;
  4832. DestStream: TStream;
  4833. DestBuffer: array [1..4096] of byte;
  4834. end;
  4835. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4836. {
  4837. procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
  4838. var
  4839. Msg: String;
  4840. begin
  4841. SetLength(Msg, 256);
  4842. cinfo^.err^.format_message(cinfo, pChar(Msg));
  4843. Writeln('ERROR [' + IntToStr(cinfo^.err^.msg_code) + '] ' + Msg);
  4844. cinfo^.global_state := 0;
  4845. jpeg_abort(cinfo);
  4846. end;
  4847. }
  4848. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4849. {
  4850. procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
  4851. var
  4852. Msg: String;
  4853. begin
  4854. SetLength(Msg, 256);
  4855. cinfo^.err^.format_message(cinfo, pChar(Msg));
  4856. Writeln('OUTPUT [' + IntToStr(cinfo^.err^.msg_code) + '] ' + Msg);
  4857. cinfo^.global_state := 0;
  4858. end;
  4859. }
  4860. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4861. {
  4862. procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
  4863. begin
  4864. end;
  4865. }
  4866. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4867. function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
  4868. var
  4869. src: glBitmap_libJPEG_source_mgr_ptr;
  4870. bytes: integer;
  4871. begin
  4872. src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
  4873. bytes := src^.SrcStream.Read(src^.SrcBuffer[1], 4096);
  4874. if (bytes <= 0) then begin
  4875. src^.SrcBuffer[1] := $FF;
  4876. src^.SrcBuffer[2] := JPEG_EOI;
  4877. bytes := 2;
  4878. end;
  4879. src^.pub.next_input_byte := @(src^.SrcBuffer[1]);
  4880. src^.pub.bytes_in_buffer := bytes;
  4881. result := true;
  4882. end;
  4883. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4884. procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
  4885. var
  4886. src: glBitmap_libJPEG_source_mgr_ptr;
  4887. begin
  4888. src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
  4889. if num_bytes > 0 then begin
  4890. // wanted byte isn't in buffer so set stream position and read buffer
  4891. if num_bytes > src^.pub.bytes_in_buffer then begin
  4892. src^.SrcStream.Position := src^.SrcStream.Position + num_bytes - src^.pub.bytes_in_buffer;
  4893. src^.pub.fill_input_buffer(cinfo);
  4894. end else begin
  4895. // wanted byte is in buffer so only skip
  4896. inc(src^.pub.next_input_byte, num_bytes);
  4897. dec(src^.pub.bytes_in_buffer, num_bytes);
  4898. end;
  4899. end;
  4900. end;
  4901. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4902. {
  4903. procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
  4904. begin
  4905. end;
  4906. }
  4907. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4908. {
  4909. procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
  4910. begin
  4911. end;
  4912. }
  4913. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4914. function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
  4915. var
  4916. dest: glBitmap_libJPEG_dest_mgr_ptr;
  4917. begin
  4918. dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
  4919. if dest^.pub.free_in_buffer < Cardinal(Length(dest^.DestBuffer)) then begin
  4920. // write complete buffer
  4921. dest^.DestStream.Write(dest^.DestBuffer[1], SizeOf(dest^.DestBuffer));
  4922. // reset buffer
  4923. dest^.pub.next_output_byte := @dest^.DestBuffer[1];
  4924. dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
  4925. end;
  4926. result := true;
  4927. end;
  4928. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4929. procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
  4930. var
  4931. Idx: Integer;
  4932. dest: glBitmap_libJPEG_dest_mgr_ptr;
  4933. begin
  4934. dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
  4935. for Idx := Low(dest^.DestBuffer) to High(dest^.DestBuffer) do begin
  4936. // check for endblock
  4937. if (Idx < High(dest^.DestBuffer)) and (dest^.DestBuffer[Idx] = $FF) and (dest^.DestBuffer[Idx +1] = JPEG_EOI) then begin
  4938. // write endblock
  4939. dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
  4940. // leave
  4941. break;
  4942. end else
  4943. dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
  4944. end;
  4945. end;
  4946. {$ENDIF}
  4947. {$IFDEF GLB_SUPPORT_JPEG_READ}
  4948. {$IF DEFINED(GLB_SDL_IMAGE)}
  4949. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4950. function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
  4951. var
  4952. Surface: PSDL_Surface;
  4953. RWops: PSDL_RWops;
  4954. begin
  4955. result := false;
  4956. RWops := glBitmapCreateRWops(Stream);
  4957. try
  4958. if IMG_isJPG(RWops) > 0 then begin
  4959. Surface := IMG_LoadJPG_RW(RWops);
  4960. try
  4961. AssignFromSurface(Surface);
  4962. result := true;
  4963. finally
  4964. SDL_FreeSurface(Surface);
  4965. end;
  4966. end;
  4967. finally
  4968. SDL_FreeRW(RWops);
  4969. end;
  4970. end;
  4971. {$ELSEIF DEFINED(GLB_LIB_JPEG)}
  4972. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4973. function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
  4974. var
  4975. StreamPos: Int64;
  4976. Temp: array[0..1]of Byte;
  4977. jpeg: jpeg_decompress_struct;
  4978. jpeg_err: jpeg_error_mgr;
  4979. IntFormat: TglBitmapInternalFormat;
  4980. pImage: pByte;
  4981. TempHeight, TempWidth: Integer;
  4982. pTemp: pByte;
  4983. Row: Integer;
  4984. begin
  4985. result := false;
  4986. if not init_libJPEG then
  4987. raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
  4988. try
  4989. // reading first two bytes to test file and set cursor back to begin
  4990. StreamPos := Stream.Position;
  4991. Stream.Read(Temp[0], 2);
  4992. Stream.Position := StreamPos;
  4993. // if Bitmap then read file.
  4994. if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
  4995. FillChar(jpeg, SizeOf(jpeg_decompress_struct), $00);
  4996. FillChar(jpeg_err, SizeOf(jpeg_error_mgr), $00);
  4997. // error managment
  4998. jpeg.err := jpeg_std_error(@jpeg_err);
  4999. jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
  5000. jpeg_err.output_message := glBitmap_libJPEG_output_message;
  5001. // decompression struct
  5002. jpeg_create_decompress(@jpeg);
  5003. // allocation space for streaming methods
  5004. jpeg.src := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_source_mgr));
  5005. // seeting up custom functions
  5006. with glBitmap_libJPEG_source_mgr_ptr(jpeg.src)^ do begin
  5007. pub.init_source := glBitmap_libJPEG_init_source;
  5008. pub.fill_input_buffer := glBitmap_libJPEG_fill_input_buffer;
  5009. pub.skip_input_data := glBitmap_libJPEG_skip_input_data;
  5010. pub.resync_to_restart := jpeg_resync_to_restart; // use default method
  5011. pub.term_source := glBitmap_libJPEG_term_source;
  5012. pub.bytes_in_buffer := 0; // forces fill_input_buffer on first read
  5013. pub.next_input_byte := nil; // until buffer loaded
  5014. SrcStream := Stream;
  5015. end;
  5016. // set global decoding state
  5017. jpeg.global_state := DSTATE_START;
  5018. // read header of jpeg
  5019. jpeg_read_header(@jpeg, false);
  5020. // setting output parameter
  5021. case jpeg.jpeg_color_space of
  5022. JCS_GRAYSCALE:
  5023. begin
  5024. jpeg.out_color_space := JCS_GRAYSCALE;
  5025. IntFormat := ifLuminance;
  5026. end;
  5027. else
  5028. jpeg.out_color_space := JCS_RGB;
  5029. IntFormat := ifRGB8;
  5030. end;
  5031. // reading image
  5032. jpeg_start_decompress(@jpeg);
  5033. TempHeight := jpeg.output_height;
  5034. TempWidth := jpeg.output_width;
  5035. // creating new image
  5036. GetMem(pImage, FormatGetImageSize(glBitmapPosition(TempWidth, TempHeight), IntFormat));
  5037. try
  5038. pTemp := pImage;
  5039. for Row := 0 to TempHeight -1 do begin
  5040. jpeg_read_scanlines(@jpeg, @pTemp, 1);
  5041. Inc(pTemp, Trunc(FormatGetSize(IntFormat) * TempWidth));
  5042. end;
  5043. // finish decompression
  5044. jpeg_finish_decompress(@jpeg);
  5045. // destroy decompression
  5046. jpeg_destroy_decompress(@jpeg);
  5047. SetDataPointer(pImage, IntFormat, TempWidth, TempHeight);
  5048. result := true;
  5049. except
  5050. FreeMem(pImage);
  5051. raise;
  5052. end;
  5053. end;
  5054. finally
  5055. quit_libJPEG;
  5056. end;
  5057. end;
  5058. {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
  5059. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5060. function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
  5061. var
  5062. bmp: TBitmap;
  5063. jpg: TJPEGImage;
  5064. StreamPos: Int64;
  5065. Temp: array[0..1]of Byte;
  5066. begin
  5067. result := false;
  5068. // reading first two bytes to test file and set cursor back to begin
  5069. StreamPos := Stream.Position;
  5070. Stream.Read(Temp[0], 2);
  5071. Stream.Position := StreamPos;
  5072. // if Bitmap then read file.
  5073. if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
  5074. bmp := TBitmap.Create;
  5075. try
  5076. jpg := TJPEGImage.Create;
  5077. try
  5078. jpg.LoadFromStream(Stream);
  5079. bmp.Assign(jpg);
  5080. result := AssignFromBitmap(bmp);
  5081. finally
  5082. jpg.Free;
  5083. end;
  5084. finally
  5085. bmp.Free;
  5086. end;
  5087. end;
  5088. end;
  5089. {$IFEND}
  5090. {$ENDIF}
  5091. {$IFDEF GLB_SUPPORT_JPEG_WRITE}
  5092. {$IF DEFEFINED(GLB_LIB_JPEG)}
  5093. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5094. procedure TglBitmap.SaveJPEG(Stream: TStream);
  5095. var
  5096. jpeg: jpeg_compress_struct;
  5097. jpeg_err: jpeg_error_mgr;
  5098. Row: Integer;
  5099. pTemp, pTemp2: pByte;
  5100. procedure CopyRow(pDest, pSource: pByte);
  5101. var
  5102. X: Integer;
  5103. begin
  5104. for X := 0 to Width - 1 do begin
  5105. pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
  5106. pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
  5107. pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
  5108. Inc(pDest, 3);
  5109. Inc(pSource, 3);
  5110. end;
  5111. end;
  5112. begin
  5113. if not (ftJPEG in FormatGetSupportedFiles(Format)) then
  5114. raise EglBitmapUnsupportedInternalFormat.Create('SaveJpg - ' + UNSUPPORTED_INTERNAL_FORMAT);
  5115. if not init_libJPEG then
  5116. raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
  5117. try
  5118. FillChar(jpeg, SizeOf(jpeg_compress_struct), $00);
  5119. FillChar(jpeg_err, SizeOf(jpeg_error_mgr), $00);
  5120. // error managment
  5121. jpeg.err := jpeg_std_error(@jpeg_err);
  5122. jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
  5123. jpeg_err.output_message := glBitmap_libJPEG_output_message;
  5124. // compression struct
  5125. jpeg_create_compress(@jpeg);
  5126. // allocation space for streaming methods
  5127. jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
  5128. // seeting up custom functions
  5129. with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
  5130. pub.init_destination := glBitmap_libJPEG_init_destination;
  5131. pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
  5132. pub.term_destination := glBitmap_libJPEG_term_destination;
  5133. pub.next_output_byte := @DestBuffer[1];
  5134. pub.free_in_buffer := Length(DestBuffer);
  5135. DestStream := Stream;
  5136. end;
  5137. // very important state
  5138. jpeg.global_state := CSTATE_START;
  5139. jpeg.image_width := Width;
  5140. jpeg.image_height := Height;
  5141. case InternalFormat of
  5142. ifAlpha, ifLuminance, ifDepth8: begin
  5143. jpeg.input_components := 1;
  5144. jpeg.in_color_space := JCS_GRAYSCALE;
  5145. end;
  5146. ifRGB8, ifBGR8: begin
  5147. jpeg.input_components := 3;
  5148. jpeg.in_color_space := JCS_RGB;
  5149. end;
  5150. end;
  5151. jpeg_set_defaults(@jpeg);
  5152. jpeg_set_quality(@jpeg, 95, true);
  5153. jpeg_start_compress(@jpeg, true);
  5154. pTemp := Data;
  5155. if InternalFormat = ifBGR8 then
  5156. GetMem(pTemp2, fRowSize)
  5157. else
  5158. pTemp2 := pTemp;
  5159. try
  5160. for Row := 0 to jpeg.image_height -1 do begin
  5161. // prepare row
  5162. if InternalFormat = ifBGR8 then
  5163. CopyRow(pTemp2, pTemp)
  5164. else
  5165. pTemp2 := pTemp;
  5166. // write row
  5167. jpeg_write_scanlines(@jpeg, @pTemp2, 1);
  5168. inc(pTemp, fRowSize);
  5169. end;
  5170. finally
  5171. // free memory
  5172. if InternalFormat = ifBGR8 then
  5173. FreeMem(pTemp2);
  5174. end;
  5175. jpeg_finish_compress(@jpeg);
  5176. jpeg_destroy_compress(@jpeg);
  5177. finally
  5178. quit_libJPEG;
  5179. end;
  5180. end;
  5181. {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
  5182. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5183. procedure TglBitmap.SaveJPEG(Stream: TStream);
  5184. var
  5185. Bmp: TBitmap;
  5186. Jpg: TJPEGImage;
  5187. begin
  5188. if not (ftJPEG in FormatGetSupportedFiles (InternalFormat)) then
  5189. raise EglBitmapUnsupportedInternalFormat.Create('SaveJpg - ' + UNSUPPORTED_INTERNAL_FORMAT);
  5190. Bmp := TBitmap.Create;
  5191. try
  5192. Jpg := TJPEGImage.Create;
  5193. try
  5194. AssignToBitmap(Bmp);
  5195. if FInternalFormat in [ifAlpha, ifLuminance, ifDepth8] then begin
  5196. Jpg.Grayscale := true;
  5197. Jpg.PixelFormat := jf8Bit;
  5198. end;
  5199. Jpg.Assign(Bmp);
  5200. Jpg.SaveToStream(Stream);
  5201. finally
  5202. FreeAndNil(Jpg);
  5203. end;
  5204. finally
  5205. FreeAndNil(Bmp);
  5206. end;
  5207. end;
  5208. {$ENDIF}
  5209. {$ENDIF}
  5210. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5211. //BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5212. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5213. const
  5214. BMP_MAGIC = $4D42;
  5215. BMP_COMP_RGB = 0;
  5216. BMP_COMP_RLE8 = 1;
  5217. BMP_COMP_RLE4 = 2;
  5218. BMP_COMP_BITFIELDS = 3;
  5219. type
  5220. TBMPHeader = packed record
  5221. bfType: Word;
  5222. bfSize: Cardinal;
  5223. bfReserved1: Word;
  5224. bfReserved2: Word;
  5225. bfOffBits: Cardinal;
  5226. end;
  5227. TBMPInfo = packed record
  5228. biSize: Cardinal;
  5229. biWidth: Longint;
  5230. biHeight: Longint;
  5231. biPlanes: Word;
  5232. biBitCount: Word;
  5233. biCompression: Cardinal;
  5234. biSizeImage: Cardinal;
  5235. biXPelsPerMeter: Longint;
  5236. biYPelsPerMeter: Longint;
  5237. biClrUsed: Cardinal;
  5238. biClrImportant: Cardinal;
  5239. end;
  5240. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5241. function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
  5242. //////////////////////////////////////////////////////////////////////////////////////////////////
  5243. function ReadInfo(var aInfo: TBMPInfo; var aMask: TglBitmapColorRec): TglBitmapFormat;
  5244. begin
  5245. result := tfEmpty;
  5246. aStream.Read(aInfo, SizeOf(aInfo));
  5247. FillChar(aMask, SizeOf(aMask), 0);
  5248. //Read Compression
  5249. case aInfo.biCompression of
  5250. BMP_COMP_RLE4,
  5251. BMP_COMP_RLE8: begin
  5252. raise EglBitmapException.Create('RLE compression is not supported');
  5253. end;
  5254. BMP_COMP_BITFIELDS: begin
  5255. if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
  5256. aStream.Read(aMask.r, SizeOf(aMask.r));
  5257. aStream.Read(aMask.g, SizeOf(aMask.g));
  5258. aStream.Read(aMask.b, SizeOf(aMask.b));
  5259. aStream.Read(aMask.a, SizeOf(aMask.a));
  5260. end else
  5261. raise EglBitmapException.Create('Bitfields are only supported for 16bit and 32bit formats');
  5262. end;
  5263. end;
  5264. //get suitable format
  5265. case aInfo.biBitCount of
  5266. 8: result := tfLuminance8;
  5267. 16: result := tfBGR5;
  5268. 24: result := tfBGR8;
  5269. 32: result := tfBGRA8;
  5270. end;
  5271. end;
  5272. function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TbmpColorTableFormat;
  5273. var
  5274. i, c: Integer;
  5275. ColorTable: TbmpColorTable;
  5276. begin
  5277. result := nil;
  5278. if (aInfo.biBitCount >= 16) then
  5279. exit;
  5280. aFormat := tfLuminance8;
  5281. c := aInfo.biClrUsed;
  5282. if (c = 0) then
  5283. c := 1 shl aInfo.biBitCount;
  5284. SetLength(ColorTable, c);
  5285. for i := 0 to c-1 do begin
  5286. aStream.Read(ColorTable[i], SizeOf(TbmpColorTableEnty));
  5287. if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then
  5288. aFormat := tfRGB8;
  5289. end;
  5290. result := TbmpColorTableFormat.Create;
  5291. result.PixelSize := aInfo.biBitCount / 8;
  5292. result.ColorTable := ColorTable;
  5293. result.Range := glBitmapColorRec($FF, $FF, $FF, $00);
  5294. end;
  5295. //////////////////////////////////////////////////////////////////////////////////////////////////
  5296. function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapColorRec;
  5297. const aInfo: TBMPInfo): TbmpBitfieldFormat;
  5298. var
  5299. TmpFormat: TglBitmapFormat;
  5300. FormatDesc: TFormatDescriptor;
  5301. begin
  5302. result := nil;
  5303. if (aMask.r <> 0) or (aMask.g <> 0) or (aMask.b <> 0) or (aMask.a <> 0) then begin
  5304. for TmpFormat := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
  5305. FormatDesc := TFormatDescriptor.Get(TmpFormat);
  5306. if FormatDesc.MaskMatch(aMask.r, aMask.g, aMask.b, aMask.a) then begin
  5307. aFormat := FormatDesc.Format;
  5308. exit;
  5309. end;
  5310. end;
  5311. if (aMask.a = 0) and TFormatDescriptor.Get(aFormat).HasAlpha then
  5312. aFormat := TFormatDescriptor.Get(aFormat).WithoutAlpha;
  5313. if (aMask.a <> 0) and not TFormatDescriptor.Get(aFormat).HasAlpha then
  5314. aFormat := TFormatDescriptor.Get(aFormat).WithAlpha;
  5315. result := TbmpBitfieldFormat.Create;
  5316. result.PixelSize := aInfo.biBitCount / 8;
  5317. result.RedMask := aMask.r;
  5318. result.GreenMask := aMask.g;
  5319. result.BlueMask := aMask.b;
  5320. result.AlphaMask := aMask.a;
  5321. end;
  5322. end;
  5323. var
  5324. //simple types
  5325. StartPos: Int64;
  5326. ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
  5327. PaddingBuff: Cardinal;
  5328. LineBuf, ImageData, TmpData: PByte;
  5329. SourceMD, DestMD: Pointer;
  5330. BmpFormat: TglBitmapFormat;
  5331. ColorTable: TbmpColorTable;
  5332. //records
  5333. Mask: TglBitmapColorRec;
  5334. Header: TBMPHeader;
  5335. Info: TBMPInfo;
  5336. //classes
  5337. SpecialFormat: TFormatDescriptor;
  5338. FormatDesc: TFormatDescriptor;
  5339. //////////////////////////////////////////////////////////////////////////////////////////////////
  5340. procedure SpecialFormatReadLine(aData: PByte; aLineBuf: PByte);
  5341. var
  5342. i, j: Integer;
  5343. Pixel: TglBitmapPixelData;
  5344. begin
  5345. aStream.Read(aLineBuf^, rbLineSize);
  5346. SpecialFormat.PreparePixel(Pixel);
  5347. for i := 0 to Info.biWidth-1 do begin
  5348. SpecialFormat.Unmap(aLineBuf, Pixel, SourceMD);
  5349. with FormatDesc do begin
  5350. //TODO: use convert function
  5351. for j := 0 to 3 do
  5352. if (SpecialFormat.Range.arr[j] <> Range.arr[j]) then begin
  5353. if (SpecialFormat.Range.arr[j] > 0) then
  5354. Pixel.Data.arr[j] := Round(Pixel.Data.arr[j] / SpecialFormat.Range.arr[j] * Range.arr[j])
  5355. else
  5356. Pixel.Data.arr[j] := 0;
  5357. end;
  5358. end;
  5359. FormatDesc.Map(Pixel, aData, DestMD);
  5360. end;
  5361. end;
  5362. begin
  5363. result := false;
  5364. BmpFormat := tfEmpty;
  5365. SpecialFormat := nil;
  5366. LineBuf := nil;
  5367. SourceMD := nil;
  5368. DestMD := nil;
  5369. // Header
  5370. StartPos := aStream.Position;
  5371. aStream.Read(Header, SizeOf(Header));
  5372. if Header.bfType = BMP_MAGIC then begin
  5373. try try
  5374. BmpFormat := ReadInfo(Info, Mask);
  5375. SpecialFormat := ReadColorTable(BmpFormat, Info);
  5376. if not Assigned(SpecialFormat) then
  5377. SpecialFormat := CheckBitfields(BmpFormat, Mask, Info);
  5378. aStream.Position := StartPos + Header.bfOffBits;
  5379. if (BmpFormat <> tfEmpty) then begin
  5380. FormatDesc := TFormatDescriptor.Get(BmpFormat);
  5381. rbLineSize := Round(Info.biWidth * Info.biBitCount / 8); //ReadBuffer LineSize
  5382. wbLineSize := Trunc(Info.biWidth * FormatDesc.PixelSize);
  5383. Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
  5384. //get Memory
  5385. DestMD := FormatDesc.CreateMappingData;
  5386. ImageSize := FormatDesc.GetSize(Info.biWidth, abs(Info.biHeight));
  5387. GetMem(ImageData, ImageSize);
  5388. if Assigned(SpecialFormat) then begin
  5389. GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
  5390. SourceMD := SpecialFormat.CreateMappingData;
  5391. end;
  5392. //read Data
  5393. try try
  5394. FillChar(ImageData^, ImageSize, $FF);
  5395. TmpData := ImageData;
  5396. if (Info.biHeight > 0) then
  5397. Inc(TmpData, wbLineSize * (Info.biHeight-1));
  5398. for i := 0 to Abs(Info.biHeight)-1 do begin
  5399. if Assigned(SpecialFormat) then
  5400. SpecialFormatReadLine(TmpData, LineBuf) //if is special format read and convert data
  5401. else
  5402. aStream.Read(TmpData^, wbLineSize); //else only read data
  5403. if (Info.biHeight > 0) then
  5404. dec(TmpData, wbLineSize)
  5405. else
  5406. inc(TmpData, wbLineSize);
  5407. aStream.Read(PaddingBuff, Padding);
  5408. end;
  5409. SetDataPointer(ImageData, BmpFormat, Info.biWidth, abs(Info.biHeight));
  5410. result := true;
  5411. finally
  5412. if Assigned(LineBuf) then
  5413. FreeMem(LineBuf);
  5414. if Assigned(SourceMD) then
  5415. SpecialFormat.FreeMappingData(SourceMD);
  5416. FormatDesc.FreeMappingData(DestMD);
  5417. end;
  5418. except
  5419. FreeMem(ImageData);
  5420. raise;
  5421. end;
  5422. end else
  5423. raise EglBitmapException.Create('LoadBMP - No suitable format found');
  5424. except
  5425. aStream.Position := StartPos;
  5426. raise;
  5427. end;
  5428. finally
  5429. FreeAndNil(SpecialFormat);
  5430. end;
  5431. end
  5432. else aStream.Position := StartPos;
  5433. end;
  5434. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5435. procedure TglBitmap.SaveBMP(const aStream: TStream);
  5436. var
  5437. Header: TBMPHeader;
  5438. Info: TBMPInfo;
  5439. Converter: TbmpColorTableFormat;
  5440. FormatDesc: TFormatDescriptor;
  5441. SourceFD, DestFD: Pointer;
  5442. pData, srcData, dstData, ConvertBuffer: pByte;
  5443. Pixel: TglBitmapPixelData;
  5444. PixelFormat: TglBitmapPixelData;
  5445. ImageSize, wbLineSize, rbLineSize, Padding, LineIdx, PixelIdx, i: Integer;
  5446. RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
  5447. PaddingBuff: Cardinal;
  5448. function GetLineWidth : Integer;
  5449. begin
  5450. result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
  5451. end;
  5452. begin
  5453. if not (ftBMP in FormatGetSupportedFiles(Format)) then
  5454. raise EglBitmapUnsupportedFormatFormat.Create('SaveBMP - ' + UNSUPPORTED_FORMAT);
  5455. Converter := nil;
  5456. FormatDesc := TFormatDescriptor.Get(Format);
  5457. ImageSize := FormatDesc.GetSize(Dimension);
  5458. FillChar(Header, SizeOf(Header), 0);
  5459. Header.bfType := BMP_MAGIC;
  5460. Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
  5461. Header.bfReserved1 := 0;
  5462. Header.bfReserved2 := 0;
  5463. Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
  5464. FillChar(Info, SizeOf(Info), 0);
  5465. Info.biSize := SizeOf(Info);
  5466. Info.biWidth := Width;
  5467. Info.biHeight := Height;
  5468. Info.biPlanes := 1;
  5469. Info.biCompression := BMP_COMP_RGB;
  5470. Info.biSizeImage := ImageSize;
  5471. try
  5472. case Format of
  5473. tfLuminance4: begin
  5474. Info.biBitCount := 4;
  5475. Header.bfSize := Header.bfSize + 16 * SizeOf(Cardinal);
  5476. Header.bfOffBits := Header.bfOffBits + 16 * SizeOf(Cardinal); //16 ColorTable entries
  5477. Converter := TbmpColorTableFormat.Create;
  5478. Converter.PixelSize := 0.5;
  5479. Converter.Format := Format;
  5480. Converter.Range := glBitmapColorRec($F, $F, $F, $0);
  5481. Converter.CreateColorTable;
  5482. end;
  5483. tfR3G3B2, tfLuminance8: begin
  5484. Info.biBitCount := 8;
  5485. Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
  5486. Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal); //256 ColorTable entries
  5487. Converter := TbmpColorTableFormat.Create;
  5488. Converter.PixelSize := 1;
  5489. Converter.Format := Format;
  5490. if (Format = tfR3G3B2) then begin
  5491. Converter.Range := glBitmapColorRec($7, $7, $3, $0);
  5492. Converter.Shift := glBitmapShiftRec(0, 3, 6, 0);
  5493. end else
  5494. Converter.Range := glBitmapColorRec($FF, $FF, $FF, $0);
  5495. Converter.CreateColorTable;
  5496. end;
  5497. tfRGB4, tfRGB5, tfR5G6B5, tfRGB5A1, tfRGBA4,
  5498. tfBGR4, tfBGR5, tfB5G6R5, tfBGR5A1, tfBGRA4: begin
  5499. Info.biBitCount := 16;
  5500. Info.biCompression := BMP_COMP_BITFIELDS;
  5501. end;
  5502. tfBGR8, tfRGB8: begin
  5503. Info.biBitCount := 24;
  5504. end;
  5505. tfRGB10, tfRGB10A2, tfRGBA8,
  5506. tfBGR10, tfBGR10A2, tfBGRA8: begin
  5507. Info.biBitCount := 32;
  5508. Info.biCompression := BMP_COMP_BITFIELDS;
  5509. end;
  5510. else
  5511. raise EglBitmapUnsupportedFormatFormat.Create('SaveBMP - ' + UNSUPPORTED_FORMAT);
  5512. end;
  5513. Info.biXPelsPerMeter := 2835;
  5514. Info.biYPelsPerMeter := 2835;
  5515. // prepare bitmasks
  5516. if Info.biCompression = BMP_COMP_BITFIELDS then begin
  5517. Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
  5518. Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
  5519. RedMask := FormatDesc.RedMask;
  5520. GreenMask := FormatDesc.GreenMask;
  5521. BlueMask := FormatDesc.BlueMask;
  5522. AlphaMask := FormatDesc.AlphaMask;
  5523. end;
  5524. // headers
  5525. aStream.Write(Header, SizeOf(Header));
  5526. aStream.Write(Info, SizeOf(Info));
  5527. // colortable
  5528. if Assigned(Converter) then
  5529. aStream.Write(Converter.ColorTable[0].b,
  5530. SizeOf(TbmpColorTableEnty) * Length(Converter.ColorTable));
  5531. // bitmasks
  5532. if Info.biCompression = BMP_COMP_BITFIELDS then begin
  5533. aStream.Write(RedMask, SizeOf(Cardinal));
  5534. aStream.Write(GreenMask, SizeOf(Cardinal));
  5535. aStream.Write(BlueMask, SizeOf(Cardinal));
  5536. aStream.Write(AlphaMask, SizeOf(Cardinal));
  5537. end;
  5538. // image data
  5539. rbLineSize := Round(Info.biWidth * FormatDesc.PixelSize);
  5540. wbLineSize := Round(Info.biWidth * Info.biBitCount / 8);
  5541. Padding := GetLineWidth - wbLineSize;
  5542. PaddingBuff := 0;
  5543. pData := Data;
  5544. inc(pData, (Height-1) * rbLineSize);
  5545. // prepare row buffer. But only for RGB because RGBA supports color masks
  5546. // so it's possible to change color within the image.
  5547. if Assigned(Converter) then begin
  5548. FormatDesc.PreparePixel(Pixel);
  5549. GetMem(ConvertBuffer, wbLineSize);
  5550. SourceFD := FormatDesc.CreateMappingData;
  5551. DestFD := Converter.CreateMappingData;
  5552. end else
  5553. ConvertBuffer := nil;
  5554. try
  5555. for LineIdx := 0 to Height - 1 do begin
  5556. // preparing row
  5557. if Assigned(Converter) then begin
  5558. srcData := pData;
  5559. dstData := ConvertBuffer;
  5560. for PixelIdx := 0 to Info.biWidth-1 do begin
  5561. FormatDesc.Unmap(srcData, Pixel, SourceFD);
  5562. with FormatDesc do begin
  5563. //TODO use convert function
  5564. for i := 0 to 3 do
  5565. if (Converter.Range.arr[i] <> Range.arr[i]) then begin
  5566. if (Range.arr[i] > 0) then
  5567. Pixel.Data.arr[i] := Round(Pixel.Data.arr[i] / Range.arr[i] * Converter.Range.arr[i])
  5568. else
  5569. Pixel.Data.arr[i] := 0;
  5570. end;
  5571. end;
  5572. Converter.Map(Pixel, dstData, DestFD);
  5573. end;
  5574. aStream.Write(ConvertBuffer^, wbLineSize);
  5575. end else begin
  5576. aStream.Write(pData^, rbLineSize);
  5577. end;
  5578. dec(pData, rbLineSize);
  5579. if (Padding > 0) then
  5580. aStream.Write(PaddingBuff, Padding);
  5581. end;
  5582. finally
  5583. // destroy row buffer
  5584. if Assigned(ConvertBuffer) then begin
  5585. FormatDesc.FreeMappingData(SourceFD);
  5586. Converter.FreeMappingData(DestFD);
  5587. FreeMem(ConvertBuffer);
  5588. end;
  5589. end;
  5590. finally
  5591. if Assigned(Converter) then
  5592. Converter.Free;
  5593. end;
  5594. end;
  5595. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5596. //TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5597. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5598. type
  5599. TTGAHeader = packed record
  5600. ImageID: Byte;
  5601. ColorMapType: Byte;
  5602. ImageType: Byte;
  5603. ColorMapSpec: Array[0..4] of Byte;
  5604. OrigX: Word;
  5605. OrigY: Word;
  5606. Width: Word;
  5607. Height: Word;
  5608. Bpp: Byte;
  5609. ImageDes: Byte;
  5610. end;
  5611. const
  5612. TGA_UNCOMPRESSED_RGB = 2;
  5613. TGA_UNCOMPRESSED_GRAY = 3;
  5614. TGA_COMPRESSED_RGB = 10;
  5615. TGA_COMPRESSED_GRAY = 11;
  5616. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5617. function TglBitmap.LoadTGA(const aStream: TStream): Boolean;
  5618. var
  5619. Header: TTGAHeader;
  5620. NewImage, pData: PByte;
  5621. StreamPos: Int64;
  5622. PixelSize, LineSize, YStart, YEnd, YInc: Integer;
  5623. Format: TglBitmapFormat;
  5624. const
  5625. CACHE_SIZE = $4000;
  5626. ////////////////////////////////////////////////////////////////////////////////////////
  5627. procedure ReadUncompressed;
  5628. var
  5629. RowSize: Integer;
  5630. begin
  5631. RowSize := Header.Width * PixelSize;
  5632. // copy line by line
  5633. while YStart <> YEnd + YInc do begin
  5634. pData := NewImage;
  5635. Inc(pData, YStart * LineSize);
  5636. aStream.Read(pData^, RowSize);
  5637. Inc(YStart, YInc);
  5638. end;
  5639. end;
  5640. ////////////////////////////////////////////////////////////////////////////////////////
  5641. procedure ReadCompressed;
  5642. var
  5643. HeaderWidth, HeaderHeight: Integer;
  5644. LinePixelsRead, ImgPixelsRead, ImgPixelsToRead: Integer;
  5645. Cache: PByte;
  5646. CacheSize, CachePos: Integer;
  5647. Temp: Byte;
  5648. TempBuf: Array [0..15] of Byte;
  5649. PixelRepeat: Boolean;
  5650. PixelToRead, TempPixels: Integer;
  5651. /////////////////////////////////////////////////////////////////
  5652. procedure CheckLine;
  5653. begin
  5654. if LinePixelsRead >= HeaderWidth then begin
  5655. LinePixelsRead := 0;
  5656. pData := NewImage;
  5657. Inc(YStart, YInc);
  5658. Inc(pData, YStart * LineSize);
  5659. end;
  5660. end;
  5661. /////////////////////////////////////////////////////////////////
  5662. procedure CachedRead(out Buffer; Count: Integer);
  5663. var
  5664. BytesRead: Integer;
  5665. begin
  5666. if (CachePos + Count) > CacheSize then begin
  5667. BytesRead := 0;
  5668. // Read Data
  5669. if CacheSize - CachePos > 0 then begin
  5670. BytesRead := CacheSize - CachePos;
  5671. Move(pByteArray(Cache)^[CachePos], Buffer, BytesRead);
  5672. Inc(CachePos, BytesRead);
  5673. end;
  5674. // Reload Data
  5675. CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
  5676. aStream.Read(Cache^, CacheSize);
  5677. CachePos := 0;
  5678. // Read else
  5679. if Count - BytesRead > 0 then begin
  5680. Move(pByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
  5681. Inc(CachePos, Count - BytesRead);
  5682. end;
  5683. end else begin
  5684. Move(pByteArray(Cache)^[CachePos], Buffer, Count);
  5685. Inc(CachePos, Count);
  5686. end;
  5687. end;
  5688. begin
  5689. CacheSize := 0;
  5690. CachePos := 0;
  5691. HeaderWidth := Header.Width;
  5692. HeaderHeight := Header.Height;
  5693. GetMem(Cache, CACHE_SIZE); // 16K Buffer
  5694. try
  5695. ImgPixelsToRead := HeaderWidth * HeaderHeight;
  5696. ImgPixelsRead := 0;
  5697. LinePixelsRead := 0;
  5698. pData := NewImage;
  5699. Inc(pData, YStart * LineSize);
  5700. // Read until all Pixels
  5701. repeat
  5702. CachedRead(Temp, 1);
  5703. PixelRepeat := Temp and $80 > 0;
  5704. PixelToRead := (Temp and $7F) + 1;
  5705. Inc(ImgPixelsRead, PixelToRead);
  5706. if PixelRepeat then begin
  5707. // repeat one pixel x times
  5708. CachedRead(TempBuf[0], PixelSize);
  5709. // repeat Pixel
  5710. while PixelToRead > 0 do begin
  5711. CheckLine;
  5712. TempPixels := HeaderWidth - LinePixelsRead;
  5713. if PixelToRead < TempPixels then
  5714. TempPixels := PixelToRead;
  5715. Inc(LinePixelsRead, TempPixels);
  5716. Dec(PixelToRead, TempPixels);
  5717. while TempPixels > 0 do begin
  5718. case PixelSize of
  5719. 1: begin
  5720. pData^ := TempBuf[0];
  5721. Inc(pData);
  5722. end;
  5723. 2: begin
  5724. pWord(pData)^ := pWord(@TempBuf[0])^;
  5725. Inc(pData, 2);
  5726. end;
  5727. 3: begin
  5728. pWord(pData)^ := pWord(@TempBuf[0])^;
  5729. Inc(pData, 2);
  5730. pData^ := TempBuf[2];
  5731. Inc(pData);
  5732. end;
  5733. 4: begin
  5734. pDWord(pData)^ := pDWord(@TempBuf[0])^;
  5735. Inc(pData, 4);
  5736. end;
  5737. end;
  5738. Dec(TempPixels);
  5739. end;
  5740. end;
  5741. end else begin
  5742. // copy x pixels
  5743. while PixelToRead > 0 do begin
  5744. CheckLine;
  5745. TempPixels := HeaderWidth - LinePixelsRead;
  5746. if PixelToRead < TempPixels then
  5747. TempPixels := PixelToRead;
  5748. CachedRead(pData^, PixelSize * TempPixels);
  5749. Inc(pData, PixelSize * TempPixels);
  5750. Inc(LinePixelsRead, TempPixels);
  5751. Dec(PixelToRead, TempPixels);
  5752. end;
  5753. end;
  5754. until ImgPixelsRead >= ImgPixelsToRead;
  5755. finally
  5756. FreeMem(Cache)
  5757. end;
  5758. end;
  5759. begin
  5760. result := false;
  5761. // reading header to test file and set cursor back to begin
  5762. StreamPos := aStream.Position;
  5763. aStream.Read(Header, SizeOf(Header));
  5764. // no colormapped files
  5765. if (Header.ColorMapType = 0) then begin
  5766. if Header.ImageType in [TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY] then begin
  5767. case Header.Bpp of
  5768. //TODO 8: Format := tfAlpha8;
  5769. 16: Format := tfLuminance8Alpha8;
  5770. 24: Format := tfBGR8;
  5771. 32: Format := tfBGRA8;
  5772. else
  5773. raise EglBitmapException.Create('LoadTga - unsupported BitsPerPixel found.');
  5774. end;
  5775. // skip image ID
  5776. if Header.ImageID <> 0 then
  5777. aStream.Position := aStream.Position + Header.ImageID;
  5778. PixelSize := TFormatDescriptor.Get(Format).GetSize(1, 1);
  5779. LineSize := Trunc(Header.Width * PixelSize);
  5780. GetMem(NewImage, LineSize * Header.Height);
  5781. try
  5782. // Row direction
  5783. if (Header.ImageDes and $20 > 0) then begin
  5784. YStart := 0;
  5785. YEnd := Header.Height -1;
  5786. YInc := 1;
  5787. end else begin
  5788. YStart := Header.Height -1;
  5789. YEnd := 0;
  5790. YInc := -1;
  5791. end;
  5792. // Read Image
  5793. case Header.ImageType of
  5794. TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY:
  5795. ReadUncompressed;
  5796. TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY:
  5797. ReadCompressed;
  5798. end;
  5799. SetDataPointer(NewImage, Format, Header.Width, Header.Height);
  5800. result := true;
  5801. except
  5802. FreeMem(NewImage);
  5803. raise;
  5804. end;
  5805. end
  5806. else aStream.Position := StreamPos;
  5807. end
  5808. else aStream.Position := StreamPos;
  5809. end;
  5810. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5811. procedure TglBitmap.SaveTGA(const aStream: TStream);
  5812. var
  5813. Header: TTGAHeader;
  5814. Size: Integer;
  5815. pTemp: pByte;
  5816. FormatDesc: TFormatDescriptor;
  5817. procedure ConvertData(pTemp: pByte);
  5818. var
  5819. Idx, PixelSize: Integer;
  5820. Temp: byte;
  5821. begin
  5822. PixelSize := fPixelSize;
  5823. for Idx := 1 to Height * Width do begin
  5824. Temp := pByteArray(pTemp)^[2];
  5825. pByteArray(pTemp)^[2] := pByteArray(pTemp)^[0];
  5826. pByteArray(pTemp)^[0] := Temp;
  5827. Inc(pTemp, PixelSize);
  5828. end;
  5829. end;
  5830. begin
  5831. if not (ftTGA in FormatGetSupportedFiles(Format)) then
  5832. raise EglBitmapUnsupportedFormatFormat.Create('SaveTGA - ' + UNSUPPORTED_FORMAT);
  5833. FillChar(Header, SizeOf(Header), 0);
  5834. case Format of
  5835. //TODO ifAlpha8, ifLuminance8, ifDepth8: begin
  5836. tfLuminance8: begin
  5837. Header.ImageType := TGA_UNCOMPRESSED_GRAY;
  5838. Header.Bpp := 8;
  5839. end;
  5840. tfLuminance8Alpha8: begin
  5841. Header.ImageType := TGA_UNCOMPRESSED_GRAY;
  5842. Header.Bpp := 16;
  5843. end;
  5844. tfRGB8, tfBGR8: begin
  5845. Header.ImageType := TGA_UNCOMPRESSED_RGB;
  5846. Header.Bpp := 24;
  5847. end;
  5848. tfRGBA8, tfBGRA8: begin
  5849. Header.ImageType := TGA_UNCOMPRESSED_RGB;
  5850. Header.Bpp := 32;
  5851. end;
  5852. else
  5853. raise EglBitmapUnsupportedFormatFormat.Create('SaveTGA - ' + UNSUPPORTED_FORMAT);
  5854. end;
  5855. Header.Width := Width;
  5856. Header.Height := Height;
  5857. Header.ImageDes := $20;
  5858. FormatDesc := TFormatDescriptor.Get(Format);
  5859. if FormatDesc.HasAlpha then
  5860. Header.ImageDes := Header.ImageDes or $08;
  5861. aStream.Write(Header, SizeOf(Header));
  5862. // convert RGB(A) to BGR(A)
  5863. Size := FormatDesc.GetSize(Dimension);
  5864. if Format in [tfRGB8, tfRGBA8] then begin
  5865. GetMem(pTemp, Size);
  5866. end else
  5867. pTemp := Data;
  5868. try
  5869. // convert data
  5870. if Format in [tfRGB8, tfRGBA8] then begin
  5871. Move(Data^, pTemp^, Size);
  5872. ConvertData(pTemp);
  5873. end;
  5874. // write data
  5875. aStream.Write(pTemp^, Size);
  5876. finally
  5877. // free tempdata
  5878. if Format in [tfRGB8, tfRGBA8] then
  5879. FreeMem(pTemp);
  5880. end;
  5881. end;
  5882. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5883. //DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5884. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5885. const
  5886. DDS_MAGIC = $20534444;
  5887. // DDS_header.dwFlags
  5888. DDSD_CAPS = $00000001;
  5889. DDSD_HEIGHT = $00000002;
  5890. DDSD_WIDTH = $00000004;
  5891. DDSD_PITCH = $00000008;
  5892. DDSD_PIXELFORMAT = $00001000;
  5893. DDSD_MIPMAPCOUNT = $00020000;
  5894. DDSD_LINEARSIZE = $00080000;
  5895. DDSD_DEPTH = $00800000;
  5896. // DDS_header.sPixelFormat.dwFlags
  5897. DDPF_ALPHAPIXELS = $00000001;
  5898. DDPF_FOURCC = $00000004;
  5899. DDPF_INDEXED = $00000020;
  5900. DDPF_RGB = $00000040;
  5901. // DDS_header.sCaps.dwCaps1
  5902. DDSCAPS_COMPLEX = $00000008;
  5903. DDSCAPS_TEXTURE = $00001000;
  5904. DDSCAPS_MIPMAP = $00400000;
  5905. // DDS_header.sCaps.dwCaps2
  5906. DDSCAPS2_CUBEMAP = $00000200;
  5907. DDSCAPS2_CUBEMAP_POSITIVEX = $00000400;
  5908. DDSCAPS2_CUBEMAP_NEGATIVEX = $00000800;
  5909. DDSCAPS2_CUBEMAP_POSITIVEY = $00001000;
  5910. DDSCAPS2_CUBEMAP_NEGATIVEY = $00002000;
  5911. DDSCAPS2_CUBEMAP_POSITIVEZ = $00004000;
  5912. DDSCAPS2_CUBEMAP_NEGATIVEZ = $00008000;
  5913. DDSCAPS2_VOLUME = $00200000;
  5914. D3DFMT_DXT1 = $31545844;
  5915. D3DFMT_DXT3 = $33545844;
  5916. D3DFMT_DXT5 = $35545844;
  5917. type
  5918. TDDSPixelFormat = packed record
  5919. dwSize: Cardinal;
  5920. dwFlags: Cardinal;
  5921. dwFourCC: Cardinal;
  5922. dwRGBBitCount: Cardinal;
  5923. dwRBitMask: Cardinal;
  5924. dwGBitMask: Cardinal;
  5925. dwBBitMask: Cardinal;
  5926. dwABitMask: Cardinal;
  5927. end;
  5928. TDDSCaps = packed record
  5929. dwCaps1: Cardinal;
  5930. dwCaps2: Cardinal;
  5931. dwDDSX: Cardinal;
  5932. dwReserved: Cardinal;
  5933. end;
  5934. TDDSHeader = packed record
  5935. dwMagic: Cardinal;
  5936. dwSize: Cardinal;
  5937. dwFlags: Cardinal;
  5938. dwHeight: Cardinal;
  5939. dwWidth: Cardinal;
  5940. dwPitchOrLinearSize: Cardinal;
  5941. dwDepth: Cardinal;
  5942. dwMipMapCount: Cardinal;
  5943. dwReserved: array[0..10] of Cardinal;
  5944. PixelFormat: TDDSPixelFormat;
  5945. Caps: TDDSCaps;
  5946. dwReserved2: Cardinal;
  5947. end;
  5948. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5949. function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
  5950. var
  5951. Header: TDDSHeader;
  5952. StreamPos: Int64;
  5953. Y, LineSize: Cardinal;
  5954. RowSize: Cardinal;
  5955. NewImage, pData: pByte;
  5956. ddsFormat: TglBitmapFormat;
  5957. function RaiseEx : Exception;
  5958. begin
  5959. result := EglBitmapException.Create('LoadDDS - unsupported Pixelformat found.');
  5960. end;
  5961. function GetDDSFormat: TglBitmapFormat;
  5962. begin
  5963. with Header.PixelFormat do begin
  5964. // Compresses
  5965. if (dwFlags and DDPF_FOURCC) > 0 then begin
  5966. (* TODO
  5967. case Header.PixelFormat.dwFourCC of
  5968. D3DFMT_DXT1: result := ifDXT1;
  5969. D3DFMT_DXT3: result := ifDXT3;
  5970. D3DFMT_DXT5: result := ifDXT5;
  5971. else
  5972. raise RaiseEx;
  5973. end;
  5974. *)
  5975. raise RaiseEx;
  5976. end else
  5977. // RGB
  5978. if (dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS)) > 0 then begin
  5979. case dwRGBBitCount of
  5980. 8: begin
  5981. (* TODO if dwFlags and DDPF_ALPHAPIXELS > 0 then
  5982. result := tfAlpha
  5983. else
  5984. *)
  5985. result := tfLuminance8;
  5986. end;
  5987. 16: begin
  5988. if dwFlags and DDPF_ALPHAPIXELS > 0 then begin
  5989. // Alpha
  5990. case CountSetBits(dwRBitMask) of
  5991. 5: result := tfRGB5A1;
  5992. //TODO 4: result := tfRGBA4;
  5993. else
  5994. result := tfLuminance8Alpha8;
  5995. end;
  5996. end else begin
  5997. // no Alpha
  5998. //TODO result := ifR5G6B5;
  5999. raise RaiseEx;
  6000. end;
  6001. end;
  6002. 24: begin
  6003. if dwRBitMask > dwBBitMask then
  6004. result := tfBGR8
  6005. else
  6006. result := tfRGB8;
  6007. end;
  6008. 32: begin
  6009. if CountSetBits(dwRBitMask) = 10 then
  6010. //TODO result := tfRGB10A2
  6011. raise RaiseEx
  6012. else
  6013. if dwRBitMask > dwBBitMask then
  6014. result := tfBGRA8
  6015. else
  6016. result := tfRGBA8;
  6017. end;
  6018. else
  6019. raise RaiseEx;
  6020. end;
  6021. end else
  6022. raise RaiseEx;
  6023. end;
  6024. end;
  6025. begin
  6026. result := false;
  6027. // Header
  6028. StreamPos := aStream.Position;
  6029. aStream.Read(Header, sizeof(Header));
  6030. if ((Header.dwMagic <> DDS_MAGIC) or (Header.dwSize <> 124) or
  6031. ((Header.dwFlags and DDSD_PIXELFORMAT) = 0) or ((Header.dwFlags and DDSD_CAPS) = 0)) then begin
  6032. aStream.Position := StreamPos;
  6033. exit;
  6034. end;
  6035. ddsFormat := GetDDSFormat;
  6036. LineSize := Trunc(Header.dwWidth * TFormatDescriptor.Get(ddsFormat).PixelSize);
  6037. GetMem(NewImage, Header.dwHeight * LineSize);
  6038. try
  6039. pData := NewImage;
  6040. // Compressed
  6041. if (Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0 then begin
  6042. RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
  6043. for Y := 0 to Header.dwHeight -1 do begin
  6044. aStream.Read(pData^, RowSize);
  6045. Inc(pData, LineSize);
  6046. end;
  6047. end else
  6048. // RGB(A)
  6049. if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS)) > 0 then begin
  6050. RowSize := Header.dwPitchOrLinearSize;
  6051. for Y := 0 to Header.dwHeight -1 do begin
  6052. aStream.Read(pData^, RowSize);
  6053. Inc(pData, LineSize);
  6054. end;
  6055. end else
  6056. raise RaiseEx;
  6057. SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight);
  6058. result := true;
  6059. except
  6060. FreeMem(NewImage);
  6061. raise;
  6062. end;
  6063. end;
  6064. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6065. procedure TglBitmap.SaveDDS(const aStream: TStream);
  6066. var
  6067. Header: TDDSHeader;
  6068. Pix: TglBitmapPixelData;
  6069. FormatDesc: TFormatDescriptor;
  6070. begin
  6071. //if not FormatIsUncompressed(InternalFormat) then
  6072. // raise EglBitmapUnsupportedFormatFormat.Create('SaveDDS - ' + UNSUPPORTED_FORMAT);
  6073. (* TODO if Format = tfAlpha8 then
  6074. FORMAT_DESCRIPTORS[tfLuminance8].PreparePixel(Pix);
  6075. else *)
  6076. TFormatDescriptor.Get(Format).PreparePixel(Pix);
  6077. // Generell
  6078. FillChar(Header, SizeOf(Header), 0);
  6079. Header.dwMagic := DDS_MAGIC;
  6080. Header.dwSize := 124;
  6081. Header.dwFlags := DDSD_PITCH or DDSD_CAPS or DDSD_PIXELFORMAT;
  6082. if Width > 0 then begin
  6083. Header.dwWidth := Width;
  6084. Header.dwFlags := Header.dwFlags or DDSD_WIDTH;
  6085. end;
  6086. if Height > 0 then begin
  6087. Header.dwHeight := Height;
  6088. Header.dwFlags := Header.dwFlags or DDSD_HEIGHT;
  6089. end;
  6090. Header.dwPitchOrLinearSize := fRowSize;
  6091. Header.dwMipMapCount := 1;
  6092. // Caps
  6093. Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
  6094. // Pixelformat
  6095. Header.PixelFormat.dwSize := Sizeof(Header.PixelFormat);
  6096. Header.PixelFormat.dwFlags := DDPF_RGB;
  6097. (* TODO tfAlpha8
  6098. if FORMAT_DESCRIPTORS[Format].HasAlpha and (Format <> tfAlpha8) then
  6099. Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
  6100. *)
  6101. FormatDesc := TFormatDescriptor.Get(Format);
  6102. Header.PixelFormat.dwRGBBitCount := Trunc(FormatDesc.PixelSize * 8);
  6103. Header.PixelFormat.dwRBitMask := FormatDesc.RedMask;
  6104. Header.PixelFormat.dwGBitMask := FormatDesc.GreenMask;
  6105. Header.PixelFormat.dwBBitMask := FormatDesc.BlueMask;
  6106. Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
  6107. aStream.Write(Header, SizeOf(Header));
  6108. aStream.Write(Data^, FormatDesc.GetSize(Dimension));
  6109. end;
  6110. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6111. //TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6112. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6113. function TglBitmap2D.GetScanline(const aIndex: Integer): Pointer;
  6114. begin
  6115. if (aIndex >= Low(fLines)) and (aIndex <= High(fLines)) then
  6116. result := fLines[aIndex]
  6117. else
  6118. result := nil;
  6119. end;
  6120. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6121. procedure TglBitmap2D.SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
  6122. const aWidth: Integer; const aHeight: Integer);
  6123. var
  6124. Idx, LineWidth: Integer;
  6125. begin
  6126. inherited SetDataPointer(aData, aFormat, aWidth, aHeight);
  6127. //TODO compression
  6128. if {FormatIsUncompressed(Format)} true then begin
  6129. (* TODO PixelFuncs
  6130. fGetPixelFunc := GetPixel2DUnmap;
  6131. fSetPixelFunc := SetPixel2DUnmap;
  6132. *)
  6133. // Assigning Data
  6134. if Assigned(Data) then begin
  6135. SetLength(fLines, GetHeight);
  6136. LineWidth := Trunc(GetWidth * TFormatDescriptor.Get(Format).PixelSize);
  6137. for Idx := 0 to GetHeight -1 do begin
  6138. fLines[Idx] := Data;
  6139. Inc(fLines[Idx], Idx * LineWidth);
  6140. end;
  6141. end
  6142. else SetLength(fLines, 0);
  6143. end else begin
  6144. (*
  6145. SetLength(fLines, 0);
  6146. fSetPixelFunc := nil;
  6147. case Format of
  6148. ifDXT1:
  6149. fGetPixelFunc := GetPixel2DDXT1;
  6150. ifDXT3:
  6151. fGetPixelFunc := GetPixel2DDXT3;
  6152. ifDXT5:
  6153. fGetPixelFunc := GetPixel2DDXT5;
  6154. else
  6155. fGetPixelFunc := nil;
  6156. end;
  6157. *)
  6158. end;
  6159. end;
  6160. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6161. procedure TglBitmap2D.UploadData(const aTarget: Cardinal; const aBuildWithGlu: Boolean);
  6162. var
  6163. FormatDesc: TFormatDescriptor;
  6164. begin
  6165. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  6166. (* TODO compression
  6167. if Self.InternalFormat in [ifDXT1, ifDXT3, ifDXT5] then
  6168. glCompressedTexImage2D(Target, 0, InternalFormat, Width, Height, 0, Trunc(Width * Height * FormatGetSize(Self.InternalFormat)), Data)
  6169. else
  6170. *)
  6171. FormatDesc := TFormatDescriptor.Get(Format);
  6172. if aBuildWithGlu then
  6173. gluBuild2DMipmaps(aTarget, FormatDesc.Components, Width, Height,
  6174. FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
  6175. else
  6176. glTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0,
  6177. FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
  6178. // Freigeben
  6179. if (FreeDataAfterGenTexture) then
  6180. FreeData;
  6181. end;
  6182. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6183. procedure TglBitmap2D.AfterConstruction;
  6184. begin
  6185. inherited;
  6186. Target := GL_TEXTURE_2D;
  6187. end;
  6188. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6189. procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
  6190. var
  6191. Temp: pByte;
  6192. Size, w, h: Integer;
  6193. FormatDesc: TFormatDescriptor;
  6194. begin
  6195. (* TODO compression
  6196. if not FormatIsUncompressed(Format) then
  6197. raise EglBitmapUnsupportedFormatFormat.Create('TglBitmap2D.GrabScreen - ' + UNSUPPORTED_FORMAT);
  6198. *)
  6199. w := aRight - aLeft;
  6200. h := aBottom - aTop;
  6201. FormatDesc := TFormatDescriptor.Get(Format);
  6202. Size := FormatDesc.GetSize(w, h);
  6203. GetMem(Temp, Size);
  6204. try
  6205. glPixelStorei(GL_PACK_ALIGNMENT, 1);
  6206. glReadPixels(aLeft, aTop, w, h, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
  6207. SetDataPointer(Temp, Format, w, h);
  6208. FlipVert;
  6209. except
  6210. FreeMem(Temp);
  6211. raise;
  6212. end;
  6213. end;
  6214. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6215. procedure TglBitmap2D.GetDataFromTexture;
  6216. var
  6217. Temp: PByte;
  6218. TempWidth, TempHeight: Integer;
  6219. TempType, TempIntFormat: Cardinal;
  6220. IntFormat, f: TglBitmapFormat;
  6221. FormatDesc: TFormatDescriptor;
  6222. begin
  6223. Bind;
  6224. // Request Data
  6225. glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
  6226. glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
  6227. glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
  6228. IntFormat := tfEmpty;
  6229. for f := Low(TglBitmapFormat) to High(TglBitmapFormat) do
  6230. if (TFormatDescriptor.Get(f).glInternalFormat = TempIntFormat) then begin
  6231. IntFormat := FormatDesc.Format;
  6232. break;
  6233. end;
  6234. // Getting data from OpenGL
  6235. FormatDesc := TFormatDescriptor.Get(IntFormat);
  6236. GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
  6237. try
  6238. (* TODO Compression
  6239. if FormatIsCompressed(IntFormat) and (GL_VERSION_1_3 or GL_ARB_texture_compression) then
  6240. glGetCompressedTexImage(Target, 0, Temp)
  6241. else
  6242. *)
  6243. glGetTexImage(Target, 0, FormatDesc.glInternalFormat, FormatDesc.glDataFormat, Temp);
  6244. SetDataPointer(Temp, IntFormat, TempWidth, TempHeight);
  6245. except
  6246. FreeMem(Temp);
  6247. raise;
  6248. end;
  6249. end;
  6250. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6251. procedure TglBitmap2D.GenTexture(const aTestTextureSize: Boolean);
  6252. var
  6253. BuildWithGlu, PotTex, TexRec: Boolean;
  6254. TexSize: Integer;
  6255. begin
  6256. if Assigned(Data) then begin
  6257. // Check Texture Size
  6258. if (aTestTextureSize) then begin
  6259. glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
  6260. if ((Height > TexSize) or (Width > TexSize)) then
  6261. raise EglBitmapSizeToLargeException.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
  6262. PotTex := IsPowerOfTwo(Height) and IsPowerOfTwo(Width);
  6263. TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE_ARB);
  6264. if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
  6265. raise EglBitmapNonPowerOfTwoException.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
  6266. end;
  6267. CreateId;
  6268. SetupParameters(BuildWithGlu);
  6269. UploadData(Target, BuildWithGlu);
  6270. glAreTexturesResident(1, @fID, @fIsResident);
  6271. end;
  6272. end;
  6273. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6274. function TglBitmap2D.FlipHorz: Boolean;
  6275. var
  6276. Col, Row: Integer;
  6277. TempDestData, DestData, SourceData: PByte;
  6278. ImgSize: Integer;
  6279. begin
  6280. result := inherited FlipHorz;
  6281. if Assigned(Data) then begin
  6282. SourceData := Data;
  6283. ImgSize := Height * fRowSize;
  6284. GetMem(DestData, ImgSize);
  6285. try
  6286. TempDestData := DestData;
  6287. Dec(TempDestData, fRowSize + fPixelSize);
  6288. for Row := 0 to Height -1 do begin
  6289. Inc(TempDestData, fRowSize * 2);
  6290. for Col := 0 to Width -1 do begin
  6291. Move(SourceData^, TempDestData^, fPixelSize);
  6292. Inc(SourceData, fPixelSize);
  6293. Dec(TempDestData, fPixelSize);
  6294. end;
  6295. end;
  6296. SetDataPointer(DestData, Format);
  6297. result := true;
  6298. except
  6299. FreeMem(DestData);
  6300. raise;
  6301. end;
  6302. end;
  6303. end;
  6304. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6305. function TglBitmap2D.FlipVert: Boolean;
  6306. var
  6307. Row: Integer;
  6308. TempDestData, DestData, SourceData: PByte;
  6309. begin
  6310. result := inherited FlipVert;
  6311. if Assigned(Data) then begin
  6312. SourceData := Data;
  6313. GetMem(DestData, Height * fRowSize);
  6314. try
  6315. TempDestData := DestData;
  6316. Inc(TempDestData, Width * (Height -1) * fPixelSize);
  6317. for Row := 0 to Height -1 do begin
  6318. Move(SourceData^, TempDestData^, fRowSize);
  6319. Dec(TempDestData, fRowSize);
  6320. Inc(SourceData, fRowSize);
  6321. end;
  6322. SetDataPointer(DestData, Format);
  6323. result := true;
  6324. except
  6325. FreeMem(DestData);
  6326. raise;
  6327. end;
  6328. end;
  6329. end;
  6330. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6331. //TglBitmap2D - ToNormalMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6332. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6333. type
  6334. TMatrixItem = record
  6335. X, Y: Integer;
  6336. W: Single;
  6337. end;
  6338. PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
  6339. TglBitmapToNormalMapRec = Record
  6340. Scale: Single;
  6341. Heights: array of Single;
  6342. MatrixU : array of TMatrixItem;
  6343. MatrixV : array of TMatrixItem;
  6344. end;
  6345. const
  6346. ONE_OVER_255 = 1 / 255;
  6347. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6348. procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
  6349. var
  6350. Val: Single;
  6351. begin
  6352. with FuncRec do begin
  6353. Val :=
  6354. Source.Data.r * LUMINANCE_WEIGHT_R +
  6355. Source.Data.g * LUMINANCE_WEIGHT_G +
  6356. Source.Data.b * LUMINANCE_WEIGHT_B;
  6357. PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255;
  6358. end;
  6359. end;
  6360. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6361. procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
  6362. begin
  6363. with FuncRec do
  6364. PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
  6365. end;
  6366. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6367. procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
  6368. type
  6369. TVec = Array[0..2] of Single;
  6370. var
  6371. Idx: Integer;
  6372. du, dv: Double;
  6373. Len: Single;
  6374. Vec: TVec;
  6375. function GetHeight(X, Y: Integer): Single;
  6376. begin
  6377. with FuncRec do begin
  6378. X := Max(0, Min(Size.X -1, X));
  6379. Y := Max(0, Min(Size.Y -1, Y));
  6380. result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
  6381. end;
  6382. end;
  6383. begin
  6384. with FuncRec do begin
  6385. with PglBitmapToNormalMapRec(Args)^ do begin
  6386. du := 0;
  6387. for Idx := Low(MatrixU) to High(MatrixU) do
  6388. du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
  6389. dv := 0;
  6390. for Idx := Low(MatrixU) to High(MatrixU) do
  6391. dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
  6392. Vec[0] := -du * Scale;
  6393. Vec[1] := -dv * Scale;
  6394. Vec[2] := 1;
  6395. end;
  6396. // Normalize
  6397. Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
  6398. if Len <> 0 then begin
  6399. Vec[0] := Vec[0] * Len;
  6400. Vec[1] := Vec[1] * Len;
  6401. Vec[2] := Vec[2] * Len;
  6402. end;
  6403. // Farbe zuweisem
  6404. Dest.Data.r := Trunc((Vec[0] + 1) * 127.5);
  6405. Dest.Data.g := Trunc((Vec[1] + 1) * 127.5);
  6406. Dest.Data.b := Trunc((Vec[2] + 1) * 127.5);
  6407. end;
  6408. end;
  6409. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6410. procedure TglBitmap2D.ToNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
  6411. var
  6412. Rec: TglBitmapToNormalMapRec;
  6413. procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
  6414. begin
  6415. if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
  6416. Matrix[Index].X := X;
  6417. Matrix[Index].Y := Y;
  6418. Matrix[Index].W := W;
  6419. end;
  6420. end;
  6421. begin
  6422. (* TODO Compression
  6423. if not FormatIsUncompressed(InternalFormat) then
  6424. raise EglBitmapUnsupportedFormatFormat.Create('TglBitmap2D.ToNormalMap - ' + UNSUPPORTED_FORMAT);
  6425. *)
  6426. if aScale > 100 then
  6427. Rec.Scale := 100
  6428. else if aScale < -100 then
  6429. Rec.Scale := -100
  6430. else
  6431. Rec.Scale := aScale;
  6432. SetLength(Rec.Heights, Width * Height);
  6433. try
  6434. case aFunc of
  6435. nm4Samples: begin
  6436. SetLength(Rec.MatrixU, 2);
  6437. SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
  6438. SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
  6439. SetLength(Rec.MatrixV, 2);
  6440. SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
  6441. SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
  6442. end;
  6443. nmSobel: begin
  6444. SetLength(Rec.MatrixU, 6);
  6445. SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
  6446. SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
  6447. SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
  6448. SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
  6449. SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
  6450. SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
  6451. SetLength(Rec.MatrixV, 6);
  6452. SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
  6453. SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
  6454. SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
  6455. SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
  6456. SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
  6457. SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
  6458. end;
  6459. nm3x3: begin
  6460. SetLength(Rec.MatrixU, 6);
  6461. SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
  6462. SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
  6463. SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
  6464. SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
  6465. SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
  6466. SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
  6467. SetLength(Rec.MatrixV, 6);
  6468. SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
  6469. SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
  6470. SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
  6471. SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
  6472. SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
  6473. SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
  6474. end;
  6475. nm5x5: begin
  6476. SetLength(Rec.MatrixU, 20);
  6477. SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
  6478. SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
  6479. SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
  6480. SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
  6481. SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
  6482. SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
  6483. SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
  6484. SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
  6485. SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
  6486. SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
  6487. SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
  6488. SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
  6489. SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
  6490. SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
  6491. SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
  6492. SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
  6493. SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
  6494. SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
  6495. SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
  6496. SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
  6497. SetLength(Rec.MatrixV, 20);
  6498. SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
  6499. SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
  6500. SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
  6501. SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
  6502. SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
  6503. SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
  6504. SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
  6505. SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
  6506. SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
  6507. SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
  6508. SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
  6509. SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
  6510. SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
  6511. SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
  6512. SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
  6513. SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
  6514. SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
  6515. SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
  6516. SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
  6517. SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
  6518. end;
  6519. end;
  6520. // Daten Sammeln
  6521. if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
  6522. AddFunc(glBitmapToNormalMapPrepareAlphaFunc, false, PtrInt(@Rec))
  6523. else
  6524. AddFunc(glBitmapToNormalMapPrepareFunc, false, PtrInt(@Rec));
  6525. AddFunc(glBitmapToNormalMapFunc, false, PtrInt(@Rec));
  6526. finally
  6527. SetLength(Rec.Heights, 0);
  6528. end;
  6529. end;
  6530. (*
  6531. procedure TglBitmap1D.SetDataPointer(Data: pByte; Format: TglBitmapInternalFormat; Width, Height: Integer);
  6532. var
  6533. pTemp: pByte;
  6534. Size: Integer;
  6535. begin
  6536. if Height > 1 then begin
  6537. // extract first line of the data
  6538. Size := FormatGetImageSize(glBitmapPosition(Width), Format);
  6539. GetMem(pTemp, Size);
  6540. Move(Data^, pTemp^, Size);
  6541. FreeMem(Data);
  6542. end else
  6543. pTemp := Data;
  6544. // set data pointer
  6545. inherited SetDataPointer(pTemp, Format, Width);
  6546. if FormatIsUncompressed(Format) then begin
  6547. fUnmapFunc := FormatGetUnMapFunc(Format);
  6548. fGetPixelFunc := GetPixel1DUnmap;
  6549. end;
  6550. end;
  6551. procedure TglBitmap1D.GetPixel1DUnmap(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
  6552. var
  6553. pTemp: pByte;
  6554. begin
  6555. pTemp := Data;
  6556. Inc(pTemp, Pos.X * fPixelSize);
  6557. fUnmapFunc(pTemp, Pixel);
  6558. end;
  6559. function TglBitmap1D.FlipHorz: Boolean;
  6560. var
  6561. Col: Integer;
  6562. pTempDest, pDest, pSource: pByte;
  6563. begin
  6564. result := inherited FlipHorz;
  6565. if Assigned(Data) and FormatIsUncompressed(InternalFormat) then begin
  6566. pSource := Data;
  6567. GetMem(pDest, fRowSize);
  6568. try
  6569. pTempDest := pDest;
  6570. Inc(pTempDest, fRowSize);
  6571. for Col := 0 to Width -1 do begin
  6572. Move(pSource^, pTempDest^, fPixelSize);
  6573. Inc(pSource, fPixelSize);
  6574. Dec(pTempDest, fPixelSize);
  6575. end;
  6576. SetDataPointer(pDest, InternalFormat);
  6577. result := true;
  6578. finally
  6579. FreeMem(pDest);
  6580. end;
  6581. end;
  6582. end;
  6583. procedure TglBitmap1D.UploadData (Target, Format, InternalFormat, Typ: Cardinal; BuildWithGlu: Boolean);
  6584. begin
  6585. // Upload data
  6586. if Self.InternalFormat in [ifDXT1, ifDXT3, ifDXT5] then
  6587. glCompressedTexImage1D(Target, 0, InternalFormat, Width, 0, Trunc(Width * FormatGetSize(Self.InternalFormat)), Data)
  6588. else
  6589. // Upload data
  6590. if BuildWithGlu then
  6591. gluBuild1DMipmaps(Target, InternalFormat, Width, Format, Typ, Data)
  6592. else
  6593. glTexImage1D(Target, 0, InternalFormat, Width, 0, Format, Typ, Data);
  6594. // Freigeben
  6595. if (FreeDataAfterGenTexture) then
  6596. FreeData;
  6597. end;
  6598. procedure TglBitmap1D.GenTexture(TestTextureSize: Boolean);
  6599. var
  6600. BuildWithGlu, TexRec: Boolean;
  6601. glFormat, glInternalFormat, glType: Cardinal;
  6602. TexSize: Integer;
  6603. begin
  6604. if Assigned(Data) then begin
  6605. // Check Texture Size
  6606. if (TestTextureSize) then begin
  6607. glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
  6608. if (Width > TexSize) then
  6609. raise EglBitmapSizeToLargeException.Create('TglBitmap1D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
  6610. TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
  6611. (Target = GL_TEXTURE_RECTANGLE_ARB);
  6612. if not (IsPowerOfTwo (Width) or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
  6613. raise EglBitmapNonPowerOfTwoException.Create('TglBitmap1D.GenTexture - Rendercontex dosn''t support non power of two texture.');
  6614. end;
  6615. CreateId;
  6616. SetupParameters(BuildWithGlu);
  6617. SelectFormat(InternalFormat, glFormat, glInternalFormat, glType);
  6618. UploadData(Target, glFormat, glInternalFormat, glType, BuildWithGlu);
  6619. // Infos sammeln
  6620. glAreTexturesResident(1, @fID, @fIsResident);
  6621. end;
  6622. end;
  6623. procedure TglBitmap1D.AfterConstruction;
  6624. begin
  6625. inherited;
  6626. Target := GL_TEXTURE_1D;
  6627. end;
  6628. { TglBitmapCubeMap }
  6629. procedure TglBitmapCubeMap.AfterConstruction;
  6630. begin
  6631. inherited;
  6632. if not (GL_VERSION_1_3 or GL_ARB_texture_cube_map or GL_EXT_texture_cube_map) then
  6633. raise EglBitmapException.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
  6634. SetWrap; // set all to GL_CLAMP_TO_EDGE
  6635. Target := GL_TEXTURE_CUBE_MAP;
  6636. fGenMode := GL_REFLECTION_MAP;
  6637. end;
  6638. procedure TglBitmapCubeMap.Bind(EnableTexCoordsGen, EnableTextureUnit: Boolean);
  6639. begin
  6640. inherited Bind (EnableTextureUnit);
  6641. if EnableTexCoordsGen then begin
  6642. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, fGenMode);
  6643. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, fGenMode);
  6644. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, fGenMode);
  6645. glEnable(GL_TEXTURE_GEN_S);
  6646. glEnable(GL_TEXTURE_GEN_T);
  6647. glEnable(GL_TEXTURE_GEN_R);
  6648. end;
  6649. end;
  6650. procedure TglBitmapCubeMap.GenerateCubeMap(CubeTarget: Cardinal; TestTextureSize: Boolean);
  6651. var
  6652. glFormat, glInternalFormat, glType: Cardinal;
  6653. BuildWithGlu: Boolean;
  6654. TexSize: Integer;
  6655. begin
  6656. // Check Texture Size
  6657. if (TestTextureSize) then begin
  6658. glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @TexSize);
  6659. if ((Height > TexSize) or (Width > TexSize)) then
  6660. raise EglBitmapSizeToLargeException.Create('TglBitmapCubeMap.GenTexture - The size for the Cubemap is to large. It''s may be not conform with the Hardware.');
  6661. if not ((IsPowerOfTwo (Height) and IsPowerOfTwo (Width)) or GL_VERSION_2_0 or GL_ARB_texture_non_power_of_two) then
  6662. raise EglBitmapNonPowerOfTwoException.Create('TglBitmapCubeMap.GenTexture - Cubemaps dosn''t support non power of two texture.');
  6663. end;
  6664. // create Texture
  6665. if ID = 0 then begin
  6666. CreateID;
  6667. SetupParameters(BuildWithGlu);
  6668. end;
  6669. SelectFormat(InternalFormat, glFormat, glInternalFormat, glType);
  6670. UploadData (CubeTarget, glFormat, glInternalFormat, glType, BuildWithGlu);
  6671. end;
  6672. procedure TglBitmapCubeMap.GenTexture(TestTextureSize: Boolean);
  6673. begin
  6674. Assert(false, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
  6675. end;
  6676. procedure TglBitmapCubeMap.Unbind(DisableTexCoordsGen,
  6677. DisableTextureUnit: Boolean);
  6678. begin
  6679. inherited Unbind (DisableTextureUnit);
  6680. if DisableTexCoordsGen then begin
  6681. glDisable(GL_TEXTURE_GEN_S);
  6682. glDisable(GL_TEXTURE_GEN_T);
  6683. glDisable(GL_TEXTURE_GEN_R);
  6684. end;
  6685. end;
  6686. { TglBitmapNormalMap }
  6687. type
  6688. TVec = Array[0..2] of Single;
  6689. TglBitmapNormalMapGetVectorFunc = procedure (var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
  6690. PglBitmapNormalMapRec = ^TglBitmapNormalMapRec;
  6691. TglBitmapNormalMapRec = record
  6692. HalfSize : Integer;
  6693. Func: TglBitmapNormalMapGetVectorFunc;
  6694. end;
  6695. procedure glBitmapNormalMapPosX(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
  6696. begin
  6697. Vec[0] := HalfSize;
  6698. Vec[1] := - (Position.Y + 0.5 - HalfSize);
  6699. Vec[2] := - (Position.X + 0.5 - HalfSize);
  6700. end;
  6701. procedure glBitmapNormalMapNegX(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
  6702. begin
  6703. Vec[0] := - HalfSize;
  6704. Vec[1] := - (Position.Y + 0.5 - HalfSize);
  6705. Vec[2] := Position.X + 0.5 - HalfSize;
  6706. end;
  6707. procedure glBitmapNormalMapPosY(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
  6708. begin
  6709. Vec[0] := Position.X + 0.5 - HalfSize;
  6710. Vec[1] := HalfSize;
  6711. Vec[2] := Position.Y + 0.5 - HalfSize;
  6712. end;
  6713. procedure glBitmapNormalMapNegY(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
  6714. begin
  6715. Vec[0] := Position.X + 0.5 - HalfSize;
  6716. Vec[1] := - HalfSize;
  6717. Vec[2] := - (Position.Y + 0.5 - HalfSize);
  6718. end;
  6719. procedure glBitmapNormalMapPosZ(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
  6720. begin
  6721. Vec[0] := Position.X + 0.5 - HalfSize;
  6722. Vec[1] := - (Position.Y + 0.5 - HalfSize);
  6723. Vec[2] := HalfSize;
  6724. end;
  6725. procedure glBitmapNormalMapNegZ(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
  6726. begin
  6727. Vec[0] := - (Position.X + 0.5 - HalfSize);
  6728. Vec[1] := - (Position.Y + 0.5 - HalfSize);
  6729. Vec[2] := - HalfSize;
  6730. end;
  6731. procedure glBitmapNormalMapFunc(var FuncRec: TglBitmapFunctionRec);
  6732. var
  6733. Vec : TVec;
  6734. Len: Single;
  6735. begin
  6736. with FuncRec do begin
  6737. with PglBitmapNormalMapRec (CustomData)^ do begin
  6738. Func(Vec, Position, HalfSize);
  6739. // Normalize
  6740. Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
  6741. if Len <> 0 then begin
  6742. Vec[0] := Vec[0] * Len;
  6743. Vec[1] := Vec[1] * Len;
  6744. Vec[2] := Vec[2] * Len;
  6745. end;
  6746. // Scale Vector and AddVectro
  6747. Vec[0] := Vec[0] * 0.5 + 0.5;
  6748. Vec[1] := Vec[1] * 0.5 + 0.5;
  6749. Vec[2] := Vec[2] * 0.5 + 0.5;
  6750. end;
  6751. // Set Color
  6752. Dest.Red := Round(Vec[0] * 255);
  6753. Dest.Green := Round(Vec[1] * 255);
  6754. Dest.Blue := Round(Vec[2] * 255);
  6755. end;
  6756. end;
  6757. procedure TglBitmapNormalMap.AfterConstruction;
  6758. begin
  6759. inherited;
  6760. fGenMode := GL_NORMAL_MAP;
  6761. end;
  6762. procedure TglBitmapNormalMap.GenerateNormalMap(Size: Integer;
  6763. TestTextureSize: Boolean);
  6764. var
  6765. Rec: TglBitmapNormalMapRec;
  6766. SizeRec: TglBitmapPixelPosition;
  6767. begin
  6768. Rec.HalfSize := Size div 2;
  6769. FreeDataAfterGenTexture := false;
  6770. SizeRec.Fields := [ffX, ffY];
  6771. SizeRec.X := Size;
  6772. SizeRec.Y := Size;
  6773. // Positive X
  6774. Rec.Func := glBitmapNormalMapPosX;
  6775. LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
  6776. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X, TestTextureSize);
  6777. // Negative X
  6778. Rec.Func := glBitmapNormalMapNegX;
  6779. LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
  6780. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, TestTextureSize);
  6781. // Positive Y
  6782. Rec.Func := glBitmapNormalMapPosY;
  6783. LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
  6784. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, TestTextureSize);
  6785. // Negative Y
  6786. Rec.Func := glBitmapNormalMapNegY;
  6787. LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
  6788. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, TestTextureSize);
  6789. // Positive Z
  6790. Rec.Func := glBitmapNormalMapPosZ;
  6791. LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
  6792. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, TestTextureSize);
  6793. // Negative Z
  6794. Rec.Func := glBitmapNormalMapNegZ;
  6795. LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
  6796. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, TestTextureSize);
  6797. end;
  6798. *)
  6799. initialization
  6800. glBitmapSetDefaultFormat(tfEmpty);
  6801. glBitmapSetDefaultMipmap(mmMipmap);
  6802. glBitmapSetDefaultFilter(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
  6803. glBitmapSetDefaultWrap (GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
  6804. glBitmapSetDefaultFreeDataAfterGenTexture(true);
  6805. glBitmapSetDefaultDeleteTextureOnFree (true);
  6806. TFormatDescriptor.Init;
  6807. finalization
  6808. TFormatDescriptor.Finalize;
  6809. end.