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.

8285 regels
278 KiB

  1. {***********************************************************
  2. glBitmap by Steffen Xonna aka Lossy eX (2003-2008)
  3. http://www.opengl24.de/index.php?cat=header&file=glbitmap
  4. modified by Delphi OpenGL Community (http://delphigl.com/)
  5. ------------------------------------------------------------
  6. The contents of this file are used with permission, subject to
  7. the Mozilla Public License Version 1.1 (the "License"); you may
  8. not use this file except in compliance with the License. You may
  9. obtain a copy of the License at
  10. http://www.mozilla.org/MPL/MPL-1.1.html
  11. ------------------------------------------------------------
  12. Version 2.0.3
  13. ------------------------------------------------------------
  14. History
  15. 21-03-2010
  16. - The define GLB_DELPHI dosn't check versions anymore. If you say you are using delphi
  17. then it's your problem if that isn't true. This prevents the unit for incompatibility
  18. with newer versions of Delphi.
  19. - Problems with D2009+ resolved (Thanks noeska and all i forgot)
  20. - GetPixel isn't set if you are loading textures inside the constructor (Thanks Wilson)
  21. 10-08-2008
  22. - AddAlphaFromglBitmap used the custom pointer instead the imagedatapointer (Thanks Wilson)
  23. - Additional Datapointer for functioninterface now has the name CustomData
  24. 24-07-2008
  25. - AssigneAlphaToBitmap overwrites his own palette (Thanks Wilson)
  26. - If you load an texture from an file the property Filename will be set to the name of the file
  27. - Three new properties to attach custom data to the Texture objects
  28. - CustomName (free for use string)
  29. - CustomNameW (free for use widestring)
  30. - CustomDataPointer (free for use pointer to attach other objects or complex structures)
  31. 27-05-2008
  32. - RLE TGAs loaded much faster
  33. 26-05-2008
  34. - fixed some problem with reading RLE TGAs.
  35. 21-05-2008
  36. - function clone now only copys data if it's assigned and now it also copies the ID
  37. - it seems that lazarus dont like comments in comments.
  38. 01-05-2008
  39. - It's possible to set the id of the texture
  40. - define GLB_NO_NATIVE_GL deactivated by default
  41. 27-04-2008
  42. - Now supports the following libraries
  43. - SDL and SDL_image
  44. - libPNG
  45. - libJPEG
  46. - Linux compatibillity via free pascal compatibility (delphi sources optional)
  47. - BMPs now loaded manuel
  48. - Large restructuring
  49. - Property DataPtr now has the name Data
  50. - Functions are more flexible between RGB(A) and BGR(A). RGB can be saved as Bitmap and will be saved as BGR
  51. - Unused Depth removed
  52. - Function FreeData to freeing image data added
  53. 24-10-2007
  54. - ImageID flag of TGAs was ignored. (Thanks Zwoetzen)
  55. 15-11-2006
  56. - Function SetBorderColor implemented (only used by opengl if wrap is set to GL_CLAMP_TO_BORDER)
  57. - Function AddAlphaFromValue implemented to use an fixed Value as Alphachannel
  58. - Function ReadOpenGLExtension is now only intern
  59. 29-06-2006
  60. - pngimage now disabled by default like all other versions.
  61. 26-06-2006
  62. - Setting up an anisotropic filter of 0 isnt allowed by nvidia (Thanks Ogridi)
  63. 22-06-2006
  64. - Fixed some Problem with Delphi 5
  65. - Now uses the newest version of pngimage. Makes saving pngs much easier.
  66. 22-03-2006
  67. - Property IsCompressed and Size removed. Not really supported by Spec (Thanks Ogridi)
  68. 09-03-2006
  69. - Internal Format ifDepth8 added
  70. - function GrabScreen now supports all uncompressed formats
  71. 31-01-2006
  72. - AddAlphaFromglBitmap implemented
  73. 29-12-2005
  74. - LoadFromResource and LoadFromResourceId now needs an Instance and an ResourceType (for ID)
  75. 28-12-2005
  76. - Width, Height and Depth internal changed to TglBitmapPixelPosition.
  77. property Width, Height, Depth are still existing and new property Dimension are avail
  78. 11-12-2005
  79. - Added native OpenGL Support. Breaking the dglOpenGL "barrier".
  80. 19-10-2005
  81. - Added function GrabScreen to class TglBitmap2D
  82. 18-10-2005
  83. - Added support to Save images
  84. - Added function Clone to Clone Instance
  85. 11-10-2005
  86. - Functions now works with Cardinals for each channel. Up to 32 Bits per channel.
  87. Usefull for Future
  88. - Several speed optimizations
  89. 09-10-2005
  90. - Internal structure change. Loading of TGA, PNG and DDS improved.
  91. Data, format and size will now set directly with SetDataPtr.
  92. - AddFunc now works with all Types of Images and Formats
  93. - Some Funtions moved to Baseclass TglBitmap
  94. 06-10-2005
  95. - Added Support to decompress DXT3 and DXT5 compressed Images.
  96. - Added Mapping to convert data from one format into an other.
  97. 05-10-2005
  98. - Added method ConvertTo in Class TglBitmap2D. Method allows to convert every
  99. supported Input format (supported by GetPixel) into any uncompresed Format
  100. - Added Support to decompress DXT1 compressed Images.
  101. - SwapColors replaced by ConvertTo
  102. 04-10-2005
  103. - Added Support for compressed DDSs
  104. - Added new internal formats (DXT1, DXT3, DXT5)
  105. 29-09-2005
  106. - Parameter Components renamed to InternalFormat
  107. 23-09-2005
  108. - Some AllocMem replaced with GetMem (little speed change)
  109. - better exception handling. Better protection from memory leaks.
  110. 22-09-2005
  111. - Added support for Direct Draw Surfaces (.DDS) (uncompressed images only)
  112. - Added new internal formats (RGB8, RGBA8, RGBA4, RGB5A1, RGB10A2, R5G6B5)
  113. 07-09-2005
  114. - Added support for Grayscale textures
  115. - Added internal formats (Alpha, Luminance, LuminanceAlpha, BGR8, BGRA8)
  116. 10-07-2005
  117. - Added support for GL_VERSION_2_0
  118. - Added support for GL_EXT_texture_filter_anisotropic
  119. 04-07-2005
  120. - Function FillWithColor fills the Image with one Color
  121. - Function LoadNormalMap added
  122. 30-06-2005
  123. - ToNormalMap allows to Create an NormalMap from the Alphachannel
  124. - ToNormalMap now supports Sobel (nmSobel) function.
  125. 29-06-2005
  126. - support for RLE Compressed RGB TGAs added
  127. 28-06-2005
  128. - Class TglBitmapNormalMap added to support Normalmap generation
  129. - Added function ToNormalMap in class TglBitmap2D to genereate normal maps from textures.
  130. 3 Filters are supported. (4 Samples, 3x3 and 5x5)
  131. 16-06-2005
  132. - Method LoadCubeMapClass removed
  133. - LoadCubeMap returnvalue is now the Texture paramter. Such as LoadTextures
  134. - virtual abstract method GenTexture in class TglBitmap now is protected
  135. 12-06-2005
  136. - now support DescriptionFlag in LoadTga. Allows vertical flipped images to be loaded as normal
  137. 10-06-2005
  138. - little enhancement for IsPowerOfTwo
  139. - TglBitmap1D.GenTexture now tests NPOT Textures
  140. 06-06-2005
  141. - some little name changes. All properties or function with Texture in name are
  142. now without texture in name. We have allways texture so we dosn't name it.
  143. 03-06-2005
  144. - GenTexture now tests if texture is NPOT and NPOT-Texture are supported or
  145. TextureTarget is GL_TEXTURE_RECTANGLE. Else it raised an exception.
  146. 02-06-2005
  147. - added support for GL_ARB_texture_rectangle, GL_EXT_texture_rectangle and GL_NV_texture_rectangle
  148. 25-04-2005
  149. - Function Unbind added
  150. - call of SetFilter or SetTextureWrap if TextureID exists results in setting properties to opengl texture.
  151. 21-04-2005
  152. - class TglBitmapCubeMap added (allows to Create Cubemaps)
  153. 29-03-2005
  154. - Added Support for PNG Images. (http://pngdelphi.sourceforge.net/)
  155. To Enable png's use the define pngimage
  156. 22-03-2005
  157. - New Functioninterface added
  158. - Function GetPixel added
  159. 27-11-2004
  160. - Property BuildMipMaps renamed to MipMap
  161. 21-11-2004
  162. - property Name removed.
  163. - BuildMipMaps is now a set of 3 values. None, GluBuildMipmaps and SGIS_generate_mipmap
  164. 22-05-2004
  165. - property name added. Only used in glForms!
  166. 26-11-2003
  167. - property FreeDataAfterGenTexture is now available as default (default = true)
  168. - BuildMipmaps now implemented in TglBitmap1D (i've forgotten it)
  169. - function MoveMemory replaced with function Move (little speed change)
  170. - several calculations stored in variables (little speed change)
  171. 29-09-2003
  172. - property BuildMipsMaps added (default = true)
  173. if BuildMipMaps isn't set GenTextures uses glTexImage[12]D else it use gluBuild[12]dMipmaps
  174. - property FreeDataAfterGenTexture added (default = true)
  175. if FreeDataAfterGenTexture is set the texturedata were deleted after the texture was generated.
  176. - parameter DisableOtherTextureUnits of Bind removed
  177. - parameter FreeDataAfterGeneration of GenTextures removed
  178. 12-09-2003
  179. - TglBitmap dosn't delete data if class was destroyed (fixed)
  180. 09-09-2003
  181. - Bind now enables TextureUnits (by params)
  182. - GenTextures can leave data (by param)
  183. - LoadTextures now optimal
  184. 03-09-2003
  185. - Performance optimization in AddFunc
  186. - procedure Bind moved to subclasses
  187. - Added new Class TglBitmap1D to support real OpenGL 1D Textures
  188. 19-08-2003
  189. - Texturefilter and texturewrap now also as defaults
  190. Minfilter = GL_LINEAR_MIPMAP_LINEAR
  191. Magfilter = GL_LINEAR
  192. Wrap(str) = GL_CLAMP_TO_EDGE
  193. - Added new format tfCompressed to create a compressed texture.
  194. - propertys IsCompressed, TextureSize and IsResident added
  195. IsCompressed and TextureSize only contains data from level 0
  196. 18-08-2003
  197. - Added function AddFunc to add PerPixelEffects to Image
  198. - LoadFromFunc now based on AddFunc
  199. - Invert now based on AddFunc
  200. - SwapColors now based on AddFunc
  201. 16-08-2003
  202. - Added function FlipHorz
  203. 15-08-2003
  204. - Added function LaodFromFunc to create images with function
  205. - Added function FlipVert
  206. - Added internal format RGB(A) if GL_EXT_bgra or OpenGL 1.2 isn't supported
  207. 29-07-2003
  208. - Added Alphafunctions to calculate alpha per function
  209. - Added Alpha from ColorKey using alphafunctions
  210. 28-07-2003
  211. - First full functionally Version of glBitmap
  212. - Support for 24Bit and 32Bit TGA Pictures added
  213. 25-07-2003
  214. - begin of programming
  215. ***********************************************************}
  216. unit glBitmap;
  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. {$MESSAGE warn 'Hey. I''m the glBitmap.pas and i need to be configured. My master tell me your preferences! ;)'}
  220. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  221. // Preferences ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  222. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  223. // activate to enable build-in OpenGL support with statically linked methods
  224. // use dglOpenGL.pas if not enabled
  225. {.$DEFINE GLB_NATIVE_OGL_STATIC}
  226. // activate to enable build-in OpenGL support with dynamically linked methods
  227. // use dglOpenGL.pas if not enabled
  228. {.$DEFINE GLB_NATIVE_OGL_DYNAMIC}
  229. // activate to enable the support for SDL_surfaces
  230. {.$DEFINE GLB_SDL}
  231. // activate to enable the support for TBitmap from Delphi (not lazarus)
  232. {.$DEFINE GLB_DELPHI}
  233. // activate to enable the support for TLazIntfImage from Lazarus
  234. {.$DEFINE GLB_LAZARUS}
  235. // activate to enable the support of SDL_image to load files. (READ ONLY)
  236. // If you enable SDL_image all other libraries will be ignored!
  237. {.$DEFINE GLB_SDL_IMAGE}
  238. // activate to enable png support with the unit pngimage -> http://pngdelphi.sourceforge.net/
  239. // if you enable pngimage the libPNG will be ignored
  240. {.$DEFINE GLB_PNGIMAGE}
  241. // activate to use the libPNG -> http://www.libpng.org/
  242. // You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libpng
  243. {.$DEFINE GLB_LIB_PNG}
  244. // if you enable delphi jpegs the libJPEG will be ignored
  245. {.$DEFINE GLB_DELPHI_JPEG}
  246. // activate to use the libJPEG -> http://www.ijg.org/
  247. // You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libjpeg
  248. {.$DEFINE GLB_LIB_JPEG}
  249. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  250. // PRIVATE: do not change anything! //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  251. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  252. // Delphi Versions
  253. {$IFDEF fpc}
  254. {$MODE Delphi}
  255. {$IFDEF CPUI386}
  256. {$DEFINE CPU386}
  257. {$ASMMODE INTEL}
  258. {$ENDIF}
  259. {$IFNDEF WINDOWS}
  260. {$linklib c}
  261. {$ENDIF}
  262. {$ENDIF}
  263. // Operation System
  264. {$IF DEFINED(WIN32) or DEFINED(WIN64) or DEFINED(WINDOWS)}
  265. {$DEFINE GLB_WIN}
  266. {$ELSEIF DEFINED(LINUX)}
  267. {$DEFINE GLB_LINUX}
  268. {$IFEND}
  269. // native OpenGL Support
  270. {$IF DEFINED(GLB_NATIVE_OGL_STATIC) OR DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
  271. {$DEFINE GLB_NATIVE_OGL}
  272. {$IFEND}
  273. // checking define combinations
  274. //SDL Image
  275. {$IFDEF GLB_SDL_IMAGE}
  276. {$IFNDEF GLB_SDL}
  277. {$MESSAGE warn 'SDL_image won''t work without SDL. SDL will be activated.'}
  278. {$DEFINE GLB_SDL}
  279. {$ENDIF}
  280. {$IFDEF GLB_PNGIMAGE}
  281. {$MESSAGE warn 'The unit pngimage will be ignored because you are using SDL_image.'}
  282. {$undef GLB_PNGIMAGE}
  283. {$ENDIF}
  284. {$IFDEF GLB_DELPHI_JPEG}
  285. {$MESSAGE warn 'The unit JPEG will be ignored because you are using SDL_image.'}
  286. {$undef GLB_DELPHI_JPEG}
  287. {$ENDIF}
  288. {$IFDEF GLB_LIB_PNG}
  289. {$MESSAGE warn 'The library libPNG will be ignored because you are using SDL_image.'}
  290. {$undef GLB_LIB_PNG}
  291. {$ENDIF}
  292. {$IFDEF GLB_LIB_JPEG}
  293. {$MESSAGE warn 'The library libJPEG will be ignored because you are using SDL_image.'}
  294. {$undef GLB_LIB_JPEG}
  295. {$ENDIF}
  296. {$DEFINE GLB_SUPPORT_PNG_READ}
  297. {$DEFINE GLB_SUPPORT_JPEG_READ}
  298. {$ENDIF}
  299. // PNG Image
  300. {$IFDEF GLB_PNGIMAGE}
  301. {$IFDEF GLB_LIB_PNG}
  302. {$MESSAGE warn 'The library libPNG will be ignored if you are using pngimage.'}
  303. {$undef GLB_LIB_PNG}
  304. {$ENDIF}
  305. {$DEFINE GLB_SUPPORT_PNG_READ}
  306. {$DEFINE GLB_SUPPORT_PNG_WRITE}
  307. {$ENDIF}
  308. // libPNG
  309. {$IFDEF GLB_LIB_PNG}
  310. {$DEFINE GLB_SUPPORT_PNG_READ}
  311. {$DEFINE GLB_SUPPORT_PNG_WRITE}
  312. {$ENDIF}
  313. // JPEG Image
  314. {$IFDEF GLB_DELPHI_JPEG}
  315. {$IFDEF GLB_LIB_JPEG}
  316. {$MESSAGE warn 'The library libJPEG will be ignored if you are using the unit JPEG.'}
  317. {$undef GLB_LIB_JPEG}
  318. {$ENDIF}
  319. {$DEFINE GLB_SUPPORT_JPEG_READ}
  320. {$DEFINE GLB_SUPPORT_JPEG_WRITE}
  321. {$ENDIF}
  322. // libJPEG
  323. {$IFDEF GLB_LIB_JPEG}
  324. {$DEFINE GLB_SUPPORT_JPEG_READ}
  325. {$DEFINE GLB_SUPPORT_JPEG_WRITE}
  326. {$ENDIF}
  327. // native OpenGL
  328. {$IF DEFINED(GLB_NATIVE_OGL_STATIC) AND DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
  329. {$MESSAGE warn 'GLB_NATIVE_OGL_STATIC will be ignored because you enabled GLB_NATIVE_OGL_DYNAMIC'}
  330. {$IFEND}
  331. // general options
  332. {$EXTENDEDSYNTAX ON}
  333. {$LONGSTRINGS ON}
  334. {$ALIGN ON}
  335. {$IFNDEF FPC}
  336. {$OPTIMIZATION ON}
  337. {$ENDIF}
  338. interface
  339. uses
  340. {$IFNDEF GLB_NATIVE_OGL} dglOpenGL, {$ENDIF}
  341. {$IF DEFINED(GLB_WIN) AND
  342. DEFINED(GLB_NATIVE_OGL)} windows, {$IFEND}
  343. {$IFDEF GLB_SDL} SDL, {$ENDIF}
  344. {$IFDEF GLB_LAZARUS} IntfGraphics, GraphType, {$ENDIF}
  345. {$IFDEF GLB_DELPHI} Dialogs, Graphics, {$ENDIF}
  346. {$IFDEF GLB_SDL_IMAGE} SDL_image, {$ENDIF}
  347. {$IFDEF GLB_PNGIMAGE} pngimage, {$ENDIF}
  348. {$IFDEF GLB_LIB_PNG} libPNG, {$ENDIF}
  349. {$IFDEF GLB_DELPHI_JPEG} JPEG, {$ENDIF}
  350. {$IFDEF GLB_LIB_JPEG} libJPEG, {$ENDIF}
  351. Classes, SysUtils;
  352. {$IFDEF GLB_NATIVE_OGL}
  353. const
  354. GL_TRUE = 1;
  355. GL_FALSE = 0;
  356. GL_VERSION = $1F02;
  357. GL_EXTENSIONS = $1F03;
  358. GL_TEXTURE_1D = $0DE0;
  359. GL_TEXTURE_2D = $0DE1;
  360. GL_TEXTURE_RECTANGLE = $84F5;
  361. GL_TEXTURE_WIDTH = $1000;
  362. GL_TEXTURE_HEIGHT = $1001;
  363. GL_TEXTURE_INTERNAL_FORMAT = $1003;
  364. GL_ALPHA = $1906;
  365. GL_ALPHA4 = $803B;
  366. GL_ALPHA8 = $803C;
  367. GL_ALPHA12 = $803D;
  368. GL_ALPHA16 = $803E;
  369. GL_LUMINANCE = $1909;
  370. GL_LUMINANCE4 = $803F;
  371. GL_LUMINANCE8 = $8040;
  372. GL_LUMINANCE12 = $8041;
  373. GL_LUMINANCE16 = $8042;
  374. GL_LUMINANCE_ALPHA = $190A;
  375. GL_LUMINANCE4_ALPHA4 = $8043;
  376. GL_LUMINANCE6_ALPHA2 = $8044;
  377. GL_LUMINANCE8_ALPHA8 = $8045;
  378. GL_LUMINANCE12_ALPHA4 = $8046;
  379. GL_LUMINANCE12_ALPHA12 = $8047;
  380. GL_LUMINANCE16_ALPHA16 = $8048;
  381. GL_RGB = $1907;
  382. GL_BGR = $80E0;
  383. GL_R3_G3_B2 = $2A10;
  384. GL_RGB4 = $804F;
  385. GL_RGB5 = $8050;
  386. GL_RGB565 = $8D62;
  387. GL_RGB8 = $8051;
  388. GL_RGB10 = $8052;
  389. GL_RGB12 = $8053;
  390. GL_RGB16 = $8054;
  391. GL_RGBA = $1908;
  392. GL_BGRA = $80E1;
  393. GL_RGBA2 = $8055;
  394. GL_RGBA4 = $8056;
  395. GL_RGB5_A1 = $8057;
  396. GL_RGBA8 = $8058;
  397. GL_RGB10_A2 = $8059;
  398. GL_RGBA12 = $805A;
  399. GL_RGBA16 = $805B;
  400. GL_DEPTH_COMPONENT = $1902;
  401. GL_DEPTH_COMPONENT16 = $81A5;
  402. GL_DEPTH_COMPONENT24 = $81A6;
  403. GL_DEPTH_COMPONENT32 = $81A7;
  404. GL_COMPRESSED_RGB = $84ED;
  405. GL_COMPRESSED_RGBA = $84EE;
  406. GL_COMPRESSED_RGB_S3TC_DXT1_EXT = $83F0;
  407. GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = $83F1;
  408. GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = $83F2;
  409. GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = $83F3;
  410. GL_UNSIGNED_BYTE = $1401;
  411. GL_UNSIGNED_BYTE_3_3_2 = $8032;
  412. GL_UNSIGNED_BYTE_2_3_3_REV = $8362;
  413. GL_UNSIGNED_SHORT = $1403;
  414. GL_UNSIGNED_SHORT_5_6_5 = $8363;
  415. GL_UNSIGNED_SHORT_4_4_4_4 = $8033;
  416. GL_UNSIGNED_SHORT_5_5_5_1 = $8034;
  417. GL_UNSIGNED_SHORT_5_6_5_REV = $8364;
  418. GL_UNSIGNED_SHORT_4_4_4_4_REV = $8365;
  419. GL_UNSIGNED_SHORT_1_5_5_5_REV = $8366;
  420. GL_UNSIGNED_INT = $1405;
  421. GL_UNSIGNED_INT_8_8_8_8 = $8035;
  422. GL_UNSIGNED_INT_10_10_10_2 = $8036;
  423. GL_UNSIGNED_INT_8_8_8_8_REV = $8367;
  424. GL_UNSIGNED_INT_2_10_10_10_REV = $8368;
  425. { Texture Filter }
  426. GL_TEXTURE_MAG_FILTER = $2800;
  427. GL_TEXTURE_MIN_FILTER = $2801;
  428. GL_NEAREST = $2600;
  429. GL_NEAREST_MIPMAP_NEAREST = $2700;
  430. GL_NEAREST_MIPMAP_LINEAR = $2702;
  431. GL_LINEAR = $2601;
  432. GL_LINEAR_MIPMAP_NEAREST = $2701;
  433. GL_LINEAR_MIPMAP_LINEAR = $2703;
  434. { Texture Wrap }
  435. GL_TEXTURE_WRAP_S = $2802;
  436. GL_TEXTURE_WRAP_T = $2803;
  437. GL_TEXTURE_WRAP_R = $8072;
  438. GL_CLAMP = $2900;
  439. GL_REPEAT = $2901;
  440. GL_CLAMP_TO_EDGE = $812F;
  441. GL_CLAMP_TO_BORDER = $812D;
  442. GL_MIRRORED_REPEAT = $8370;
  443. { Other }
  444. GL_GENERATE_MIPMAP = $8191;
  445. GL_TEXTURE_BORDER_COLOR = $1004;
  446. GL_MAX_TEXTURE_SIZE = $0D33;
  447. GL_PACK_ALIGNMENT = $0D05;
  448. GL_UNPACK_ALIGNMENT = $0CF5;
  449. GL_TEXTURE_MAX_ANISOTROPY_EXT = $84FE;
  450. GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = $84FF;
  451. {$IF DEFINED(GLB_WIN)}
  452. libglu = 'glu32.dll';
  453. libopengl = 'opengl32.dll';
  454. {$ELSEIF DEFINED(GLB_LINUX)}
  455. libglu = 'libGLU.so.1';
  456. libopengl = 'libGL.so.1';
  457. {$IFEND}
  458. type
  459. GLboolean = BYTEBOOL;
  460. GLint = Integer;
  461. GLsizei = Integer;
  462. GLuint = Cardinal;
  463. GLfloat = Single;
  464. GLenum = Cardinal;
  465. PGLvoid = Pointer;
  466. PGLboolean = ^GLboolean;
  467. PGLint = ^GLint;
  468. PGLuint = ^GLuint;
  469. PGLfloat = ^GLfloat;
  470. TglCompressedTexImage1D = procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  471. TglCompressedTexImage2D = procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  472. TglGetCompressedTexImage = procedure(target: GLenum; level: GLint; img: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  473. {$IF DEFINED(GLB_WIN)}
  474. TwglGetProcAddress = function (ProcName: PAnsiChar): Pointer; stdcall;
  475. {$ELSEIF DEFINED(GLB_LINUX)}
  476. TglXGetProcAddress = function(ProcName: PAnsiChar): Pointer; cdecl;
  477. TglXGetProcAddressARB = function(const name: PAnsiChar): pointer; cdecl;
  478. {$IFEND}
  479. {$IF DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
  480. TglEnable = procedure(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  481. TglDisable = procedure(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  482. TglGetString = function(name: GLenum): PAnsiChar; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  483. TglGetIntegerv = procedure(pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  484. TglTexParameteri = procedure(target: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  485. TglTexParameterfv = procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  486. TglGetTexParameteriv = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  487. TglGetTexParameterfv = procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  488. TglGetTexLevelParameteriv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  489. TglGetTexLevelParameterfv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  490. TglGenTextures = procedure(n: GLsizei; textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  491. TglBindTexture = procedure(target: GLenum; texture: GLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  492. TglDeleteTextures = procedure(n: GLsizei; const textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  493. TglAreTexturesResident = function(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  494. TglReadPixels = procedure(x: GLint; y: GLint; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  495. TglPixelStorei = procedure(pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  496. TglTexImage1D = procedure(target: GLenum; level: GLint; internalformat: GLint; width: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  497. TglTexImage2D = procedure(target: GLenum; level: GLint; internalformat: GLint; width: GLsizei; height: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  498. TglGetTexImage = procedure(target: GLenum; level: GLint; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  499. TgluBuild1DMipmaps = function(target: GLEnum; components, width: GLint; format, atype: GLEnum; const data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  500. TgluBuild2DMipmaps = function(target: GLEnum; components, width, height: GLint; format, atype: GLEnum; const Data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
  501. {$ELSEIF DEFINED(GLB_NATIVE_OGL_STATIC)}
  502. procedure glEnable(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  503. procedure glDisable(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  504. function glGetString(name: GLenum): PAnsiChar; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  505. procedure glGetIntegerv(pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  506. procedure glTexParameteri(target: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  507. procedure glTexParameterfv(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  508. procedure glGetTexParameteriv(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  509. procedure glGetTexParameterfv(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  510. procedure glGetTexLevelParameteriv(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  511. procedure glGetTexLevelParameterfv(target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  512. procedure glGenTextures(n: GLsizei; textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  513. procedure glBindTexture(target: GLenum; texture: GLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  514. procedure glDeleteTextures(n: GLsizei; const textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  515. function glAreTexturesResident(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  516. procedure glReadPixels(x: GLint; y: GLint; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  517. procedure glPixelStorei(pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  518. procedure glTexImage1D(target: GLenum; level: GLint; internalformat: GLint; width: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  519. procedure glTexImage2D(target: GLenum; level: GLint; internalformat: GLint; width: GLsizei; height: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  520. procedure glGetTexImage(target: GLenum; level: GLint; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
  521. function gluBuild1DMipmaps(target: GLEnum; components, width: GLint; format, atype: GLEnum; const data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libglu;
  522. function gluBuild2DMipmaps(target: GLEnum; components, width, height: GLint; format, atype: GLEnum; const Data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libglu;
  523. {$IFEND}
  524. var
  525. GL_VERSION_1_2,
  526. GL_VERSION_1_3,
  527. GL_VERSION_1_4,
  528. GL_VERSION_2_0,
  529. GL_SGIS_generate_mipmap,
  530. GL_ARB_texture_border_clamp,
  531. GL_ARB_texture_mirrored_repeat,
  532. GL_ARB_texture_rectangle,
  533. GL_ARB_texture_non_power_of_two,
  534. GL_IBM_texture_mirrored_repeat,
  535. GL_NV_texture_rectangle,
  536. GL_EXT_texture_edge_clamp,
  537. GL_EXT_texture_rectangle,
  538. GL_EXT_texture_filter_anisotropic: Boolean;
  539. glCompressedTexImage1D: TglCompressedTexImage1D;
  540. glCompressedTexImage2D: TglCompressedTexImage2D;
  541. glGetCompressedTexImage: TglGetCompressedTexImage;
  542. {$IF DEFINED(GLB_WIN)}
  543. wglGetProcAddress: TwglGetProcAddress;
  544. {$ELSEIF DEFINED(GLB_LINUX)}
  545. glXGetProcAddress: TglXGetProcAddress;
  546. glXGetProcAddressARB: TglXGetProcAddress;
  547. {$IFEND}
  548. {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
  549. glEnable: TglEnable;
  550. glDisable: TglDisable;
  551. glGetString: TglGetString;
  552. glGetIntegerv: TglGetIntegerv;
  553. glTexParameteri: TglTexParameteri;
  554. glTexParameterfv: TglTexParameterfv;
  555. glGetTexParameteriv: TglGetTexParameteriv;
  556. glGetTexParameterfv: TglGetTexParameterfv;
  557. glGetTexLevelParameteriv: TglGetTexLevelParameteriv;
  558. glGetTexLevelParameterfv: TglGetTexLevelParameterfv;
  559. glGenTextures: TglGenTextures;
  560. glBindTexture: TglBindTexture;
  561. glDeleteTextures: TglDeleteTextures;
  562. glAreTexturesResident: TglAreTexturesResident;
  563. glReadPixels: TglReadPixels;
  564. glPixelStorei: TglPixelStorei;
  565. glTexImage1D: TglTexImage1D;
  566. glTexImage2D: TglTexImage2D;
  567. glGetTexImage: TglGetTexImage;
  568. gluBuild1DMipmaps: TgluBuild1DMipmaps;
  569. gluBuild2DMipmaps: TgluBuild2DMipmaps;
  570. {$ENDIF}
  571. {$ENDIF}
  572. type
  573. ////////////////////////////////////////////////////////////////////////////////////////////////////
  574. TglBitmapFormat = (
  575. tfEmpty = 0, //must be smallest value!
  576. tfAlpha4,
  577. tfAlpha8,
  578. tfAlpha12,
  579. tfAlpha16,
  580. tfLuminance4,
  581. tfLuminance8,
  582. tfLuminance12,
  583. tfLuminance16,
  584. tfLuminance4Alpha4,
  585. tfLuminance6Alpha2,
  586. tfLuminance8Alpha8,
  587. tfLuminance12Alpha4,
  588. tfLuminance12Alpha12,
  589. tfLuminance16Alpha16,
  590. tfR3G3B2,
  591. tfRGB4,
  592. tfR5G6B5,
  593. tfRGB5,
  594. tfRGB8,
  595. tfRGB10,
  596. tfRGB12,
  597. tfRGB16,
  598. tfRGBA2,
  599. tfRGBA4,
  600. tfRGB5A1,
  601. tfRGBA8,
  602. tfRGB10A2,
  603. tfRGBA12,
  604. tfRGBA16,
  605. tfBGR4,
  606. tfB5G6R5,
  607. tfBGR5,
  608. tfBGR8,
  609. tfBGR10,
  610. tfBGR12,
  611. tfBGR16,
  612. tfBGRA2,
  613. tfBGRA4,
  614. tfBGR5A1,
  615. tfBGRA8,
  616. tfBGR10A2,
  617. tfBGRA12,
  618. tfBGRA16,
  619. tfDepth16,
  620. tfDepth24,
  621. tfDepth32,
  622. tfS3tcDtx1RGBA,
  623. tfS3tcDtx3RGBA,
  624. tfS3tcDtx5RGBA
  625. );
  626. TglBitmapFileType = (
  627. {$IFDEF GLB_SUPPORT_PNG_WRITE} ftPNG, {$ENDIF}
  628. {$IFDEF GLB_SUPPORT_JPEG_WRITE}ftJPEG, {$ENDIF}
  629. ftDDS,
  630. ftTGA,
  631. ftBMP);
  632. TglBitmapFileTypes = set of TglBitmapFileType;
  633. TglBitmapMipMap = (
  634. mmNone,
  635. mmMipmap,
  636. mmMipmapGlu);
  637. TglBitmapNormalMapFunc = (
  638. nm4Samples,
  639. nmSobel,
  640. nm3x3,
  641. nm5x5);
  642. ////////////////////////////////////////////////////////////////////////////////////////////////////
  643. EglBitmapException = class(Exception);
  644. EglBitmapSizeToLargeException = class(EglBitmapException);
  645. EglBitmapNonPowerOfTwoException = class(EglBitmapException);
  646. EglBitmapUnsupportedFormat = class(EglBitmapException)
  647. constructor Create(const aFormat: TglBitmapFormat); overload;
  648. constructor Create(const aMsg: String; const aFormat: TglBitmapFormat); overload;
  649. end;
  650. ////////////////////////////////////////////////////////////////////////////////////////////////////
  651. TglBitmapColorRec = packed record
  652. case Integer of
  653. 0: (r, g, b, a: Cardinal);
  654. 1: (arr: array[0..3] of Cardinal);
  655. end;
  656. TglBitmapPixelData = packed record
  657. Data, Range: TglBitmapColorRec;
  658. Format: TglBitmapFormat;
  659. end;
  660. PglBitmapPixelData = ^TglBitmapPixelData;
  661. ////////////////////////////////////////////////////////////////////////////////////////////////////
  662. TglBitmapPixelPositionFields = set of (ffX, ffY);
  663. TglBitmapPixelPosition = record
  664. Fields : TglBitmapPixelPositionFields;
  665. X : Word;
  666. Y : Word;
  667. end;
  668. ////////////////////////////////////////////////////////////////////////////////////////////////////
  669. TglBitmap = class;
  670. TglBitmapFunctionRec = record
  671. Sender: TglBitmap;
  672. Size: TglBitmapPixelPosition;
  673. Position: TglBitmapPixelPosition;
  674. Source: TglBitmapPixelData;
  675. Dest: TglBitmapPixelData;
  676. Args: Pointer;
  677. end;
  678. TglBitmapFunction = procedure(var FuncRec: TglBitmapFunctionRec);
  679. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  680. TglBitmap = class
  681. protected
  682. fID: GLuint;
  683. fTarget: GLuint;
  684. fAnisotropic: Integer;
  685. fDeleteTextureOnFree: Boolean;
  686. fFreeDataAfterGenTexture: Boolean;
  687. fData: PByte;
  688. fIsResident: Boolean;
  689. fBorderColor: array[0..3] of Single;
  690. fDimension: TglBitmapPixelPosition;
  691. fMipMap: TglBitmapMipMap;
  692. fFormat: TglBitmapFormat;
  693. // Mapping
  694. fPixelSize: Integer;
  695. fRowSize: Integer;
  696. // Filtering
  697. fFilterMin: Cardinal;
  698. fFilterMag: Cardinal;
  699. // TexturWarp
  700. fWrapS: Cardinal;
  701. fWrapT: Cardinal;
  702. fWrapR: Cardinal;
  703. // CustomData
  704. fFilename: String;
  705. fCustomName: String;
  706. fCustomNameW: WideString;
  707. fCustomData: Pointer;
  708. //Getter
  709. function GetWidth: Integer; virtual;
  710. function GetHeight: Integer; virtual;
  711. function GetFileWidth: Integer; virtual;
  712. function GetFileHeight: Integer; virtual;
  713. //Setter
  714. procedure SetCustomData(const aValue: Pointer);
  715. procedure SetCustomName(const aValue: String);
  716. procedure SetCustomNameW(const aValue: WideString);
  717. procedure SetDeleteTextureOnFree(const aValue: Boolean);
  718. procedure SetFormat(const aValue: TglBitmapFormat);
  719. procedure SetFreeDataAfterGenTexture(const aValue: Boolean);
  720. procedure SetID(const aValue: Cardinal);
  721. procedure SetMipMap(const aValue: TglBitmapMipMap);
  722. procedure SetTarget(const aValue: Cardinal);
  723. procedure SetAnisotropic(const aValue: Integer);
  724. procedure CreateID;
  725. procedure SetupParameters(out aBuildWithGlu: Boolean);
  726. procedure SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
  727. const aWidth: Integer = -1; const aHeight: Integer = -1); virtual;
  728. procedure GenTexture(const aTestTextureSize: Boolean = true); virtual; abstract;
  729. function FlipHorz: Boolean; virtual;
  730. function FlipVert: Boolean; virtual;
  731. property Width: Integer read GetWidth;
  732. property Height: Integer read GetHeight;
  733. property FileWidth: Integer read GetFileWidth;
  734. property FileHeight: Integer read GetFileHeight;
  735. public
  736. //Properties
  737. property ID: Cardinal read fID write SetID;
  738. property Target: Cardinal read fTarget write SetTarget;
  739. property Format: TglBitmapFormat read fFormat write SetFormat;
  740. property MipMap: TglBitmapMipMap read fMipMap write SetMipMap;
  741. property Anisotropic: Integer read fAnisotropic write SetAnisotropic;
  742. property Filename: String read fFilename;
  743. property CustomName: String read fCustomName write SetCustomName;
  744. property CustomNameW: WideString read fCustomNameW write SetCustomNameW;
  745. property CustomData: Pointer read fCustomData write SetCustomData;
  746. property DeleteTextureOnFree: Boolean read fDeleteTextureOnFree write SetDeleteTextureOnFree;
  747. property FreeDataAfterGenTexture: Boolean read fFreeDataAfterGenTexture write SetFreeDataAfterGenTexture;
  748. property Dimension: TglBitmapPixelPosition read fDimension;
  749. property Data: PByte read fData;
  750. property IsResident: Boolean read fIsResident;
  751. procedure AfterConstruction; override;
  752. procedure BeforeDestruction; override;
  753. procedure PrepareResType(var aResource: String; var aResType: PChar);
  754. //Load
  755. procedure LoadFromFile(const aFilename: String);
  756. procedure LoadFromStream(const aStream: TStream); virtual;
  757. procedure LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
  758. const aFormat: TglBitmapFormat; const aArgs: Pointer = nil);
  759. procedure LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil);
  760. procedure LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
  761. //Save
  762. procedure SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
  763. procedure SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType); virtual;
  764. //Convert
  765. function AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer = nil): Boolean; overload;
  766. function AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
  767. const aFormat: TglBitmapFormat; const aArgs: Pointer = nil): Boolean; overload;
  768. public
  769. //Alpha & Co
  770. {$IFDEF GLB_SDL}
  771. function AssignToSurface(out aSurface: PSDL_Surface): Boolean;
  772. function AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
  773. function AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
  774. function AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil;
  775. const aArgs: Pointer = nil): Boolean;
  776. {$ENDIF}
  777. {$IFDEF GLB_DELPHI}
  778. function AssignToBitmap(const aBitmap: TBitmap): Boolean;
  779. function AssignFromBitmap(const aBitmap: TBitmap): Boolean;
  780. function AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
  781. function AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction = nil;
  782. const aArgs: Pointer = nil): Boolean;
  783. {$ENDIF}
  784. {$IFDEF GLB_LAZARUS}
  785. function AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
  786. function AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
  787. function AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
  788. function AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction = nil;
  789. const aArgs: Pointer = nil): Boolean;
  790. {$ENDIF}
  791. function AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil;
  792. const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  793. function AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
  794. const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  795. function AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer = nil): Boolean; virtual;
  796. function AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  797. function AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  798. function AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  799. function AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte = 0): Boolean;
  800. function AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal = 0): Boolean;
  801. function AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single = 0): Boolean;
  802. function AddAlphaFromValue(const aAlpha: Byte): Boolean;
  803. function AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
  804. function AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
  805. function RemoveAlpha: Boolean; virtual;
  806. public
  807. //Common
  808. function Clone: TglBitmap;
  809. function ConvertTo(const aFormat: TglBitmapFormat): Boolean; virtual;
  810. procedure Invert(const aUseRGB: Boolean = true; const aUseAlpha: Boolean = false);
  811. procedure SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
  812. procedure FreeData;
  813. //ColorFill
  814. procedure FillWithColor(const aRed, aGreen, aBlue: Byte; const aAlpha: Byte = 255);
  815. procedure FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal = $FFFFFFFF);
  816. procedure FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha : Single = 1);
  817. //TexParameters
  818. procedure SetFilter(const aMin, aMag: Cardinal);
  819. procedure SetWrap(
  820. const S: Cardinal = GL_CLAMP_TO_EDGE;
  821. const T: Cardinal = GL_CLAMP_TO_EDGE;
  822. const R: Cardinal = GL_CLAMP_TO_EDGE);
  823. procedure Bind(const aEnableTextureUnit: Boolean = true); virtual;
  824. procedure Unbind(const aDisableTextureUnit: Boolean = true); virtual;
  825. //Constructors
  826. constructor Create; overload;
  827. constructor Create(const aFileName: String); overload;
  828. constructor Create(const aStream: TStream); overload;
  829. constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat); overload;
  830. constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer = nil); overload;
  831. constructor Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil); overload;
  832. constructor Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar); overload;
  833. private
  834. {$IFDEF GLB_SUPPORT_PNG_READ} function LoadPNG(const aStream: TStream): Boolean; virtual; {$ENDIF}
  835. {$ifdef GLB_SUPPORT_PNG_WRITE} procedure SavePNG(const aStream: TStream); virtual; {$ENDIF}
  836. {$IFDEF GLB_SUPPORT_JPEG_READ} function LoadJPEG(const aStream: TStream): Boolean; virtual; {$ENDIF}
  837. {$IFDEF GLB_SUPPORT_JPEG_WRITE} procedure SaveJPEG(const aStream: TStream); virtual; {$ENDIF}
  838. function LoadBMP(const aStream: TStream): Boolean; virtual;
  839. procedure SaveBMP(const aStream: TStream); virtual;
  840. function LoadTGA(const aStream: TStream): Boolean; virtual;
  841. procedure SaveTGA(const aStream: TStream); virtual;
  842. function LoadDDS(const aStream: TStream): Boolean; virtual;
  843. procedure SaveDDS(const aStream: TStream); virtual;
  844. end;
  845. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  846. TglBitmap2D = class(TglBitmap)
  847. protected
  848. // Bildeinstellungen
  849. fLines: array of PByte;
  850. function GetScanline(const aIndex: Integer): Pointer;
  851. procedure SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
  852. const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
  853. procedure UploadData(const aTarget: Cardinal; const aBuildWithGlu: Boolean);
  854. public
  855. property Width;
  856. property Height;
  857. property Scanline[const aIndex: Integer]: Pointer read GetScanline;
  858. procedure AfterConstruction; override;
  859. procedure GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
  860. procedure GetDataFromTexture;
  861. procedure GenTexture(const aTestTextureSize: Boolean = true); override;
  862. function FlipHorz: Boolean; override;
  863. function FlipVert: Boolean; override;
  864. procedure ToNormalMap(const aFunc: TglBitmapNormalMapFunc = nm3x3;
  865. const aScale: Single = 2; const aUseAlpha: Boolean = false);
  866. end;
  867. (* TODO
  868. TglBitmapCubeMap = class(TglBitmap2D)
  869. protected
  870. fGenMode: Integer;
  871. // Hide GenTexture
  872. procedure GenTexture(TestTextureSize: Boolean = true); reintroduce;
  873. public
  874. procedure AfterConstruction; override;
  875. procedure GenerateCubeMap(CubeTarget: Cardinal; TestTextureSize: Boolean = true);
  876. procedure Unbind(DisableTexCoordsGen: Boolean = true; DisableTextureUnit: Boolean = true); reintroduce; virtual;
  877. procedure Bind(EnableTexCoordsGen: Boolean = true; EnableTextureUnit: Boolean = true); reintroduce; virtual;
  878. end;
  879. TglBitmapNormalMap = class(TglBitmapCubeMap)
  880. public
  881. procedure AfterConstruction; override;
  882. procedure GenerateNormalMap(Size: Integer = 32; TestTextureSize: Boolean = true);
  883. end;
  884. TglBitmap1D = class(TglBitmap)
  885. protected
  886. procedure GetPixel1DUnmap(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
  887. procedure SetDataPointer(Data: pByte; Format: TglBitmapInternalFormat; Width: Integer = -1; Height: Integer = -1); override;
  888. procedure UploadData (Target, Format, InternalFormat, Typ: Cardinal; BuildWithGlu: Boolean);
  889. public
  890. // propertys
  891. property Width;
  892. procedure AfterConstruction; override;
  893. // Other
  894. function FlipHorz: Boolean; override;
  895. // Generation
  896. procedure GenTexture(TestTextureSize: Boolean = true); override;
  897. end;
  898. *)
  899. const
  900. NULL_SIZE: TglBitmapPixelPosition = (Fields: []; X: 0; Y: 0);
  901. procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
  902. procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
  903. procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
  904. procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
  905. procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
  906. procedure glBitmapSetDefaultWrap(
  907. const S: Cardinal = GL_CLAMP_TO_EDGE;
  908. const T: Cardinal = GL_CLAMP_TO_EDGE;
  909. const R: Cardinal = GL_CLAMP_TO_EDGE);
  910. function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
  911. function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
  912. function glBitmapGetDefaultMipmap: TglBitmapMipMap;
  913. function glBitmapGetDefaultFormat: TglBitmapFormat;
  914. procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
  915. procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
  916. function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
  917. function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
  918. function glBitmapColorRecCmp(const r1, r2: TglBitmapColorRec): Boolean;
  919. var
  920. glBitmapDefaultDeleteTextureOnFree: Boolean;
  921. glBitmapDefaultFreeDataAfterGenTextures: Boolean;
  922. glBitmapDefaultFormat: TglBitmapFormat;
  923. glBitmapDefaultMipmap: TglBitmapMipMap;
  924. glBitmapDefaultFilterMin: Cardinal;
  925. glBitmapDefaultFilterMag: Cardinal;
  926. glBitmapDefaultWrapS: Cardinal;
  927. glBitmapDefaultWrapT: Cardinal;
  928. glBitmapDefaultWrapR: Cardinal;
  929. {$IFDEF GLB_DELPHI}
  930. function CreateGrayPalette: HPALETTE;
  931. {$ENDIF}
  932. implementation
  933. uses
  934. Math, syncobjs, typinfo;
  935. type
  936. {$IFNDEF fpc}
  937. QWord = System.UInt64;
  938. PQWord = ^QWord;
  939. PtrInt = Longint;
  940. PtrUInt = DWord;
  941. {$ENDIF}
  942. ////////////////////////////////////////////////////////////////////////////////////////////////////
  943. TShiftRec = packed record
  944. case Integer of
  945. 0: (r, g, b, a: Byte);
  946. 1: (arr: array[0..3] of Byte);
  947. end;
  948. TFormatDescriptor = class(TObject)
  949. private
  950. function GetRedMask: QWord;
  951. function GetGreenMask: QWord;
  952. function GetBlueMask: QWord;
  953. function GetAlphaMask: QWord;
  954. protected
  955. fFormat: TglBitmapFormat;
  956. fWithAlpha: TglBitmapFormat;
  957. fWithoutAlpha: TglBitmapFormat;
  958. fRGBInverted: TglBitmapFormat;
  959. fUncompressed: TglBitmapFormat;
  960. fPixelSize: Single;
  961. fIsCompressed: Boolean;
  962. fRange: TglBitmapColorRec;
  963. fShift: TShiftRec;
  964. fglFormat: Cardinal;
  965. fglInternalFormat: Cardinal;
  966. fglDataFormat: Cardinal;
  967. function GetComponents: Integer; virtual;
  968. public
  969. property Format: TglBitmapFormat read fFormat;
  970. property WithAlpha: TglBitmapFormat read fWithAlpha;
  971. property WithoutAlpha: TglBitmapFormat read fWithoutAlpha;
  972. property RGBInverted: TglBitmapFormat read fRGBInverted;
  973. property Components: Integer read GetComponents;
  974. property PixelSize: Single read fPixelSize;
  975. property IsCompressed: Boolean read fIsCompressed;
  976. property glFormat: Cardinal read fglFormat;
  977. property glInternalFormat: Cardinal read fglInternalFormat;
  978. property glDataFormat: Cardinal read fglDataFormat;
  979. property Range: TglBitmapColorRec read fRange;
  980. property Shift: TShiftRec read fShift;
  981. property RedMask: QWord read GetRedMask;
  982. property GreenMask: QWord read GetGreenMask;
  983. property BlueMask: QWord read GetBlueMask;
  984. property AlphaMask: QWord read GetAlphaMask;
  985. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); virtual; abstract;
  986. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract;
  987. function GetSize(const aSize: TglBitmapPixelPosition): Integer; overload; virtual;
  988. function GetSize(const aWidth, aHeight: Integer): Integer; overload; virtual;
  989. function CreateMappingData: Pointer; virtual;
  990. procedure FreeMappingData(var aMappingData: Pointer); virtual;
  991. function IsEmpty: Boolean; virtual;
  992. function HasAlpha: Boolean; virtual;
  993. function MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: QWord): Boolean; virtual;
  994. procedure PreparePixel(out aPixel: TglBitmapPixelData); virtual;
  995. constructor Create; virtual;
  996. public
  997. class procedure Init;
  998. class function Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
  999. class function GetWithAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
  1000. class procedure Clear;
  1001. class procedure Finalize;
  1002. end;
  1003. TFormatDescriptorClass = class of TFormatDescriptor;
  1004. TfdEmpty = class(TFormatDescriptor);
  1005. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1006. TfdAlpha_UB1 = class(TFormatDescriptor) //1* unsigned byte
  1007. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1008. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1009. constructor Create; override;
  1010. end;
  1011. TfdLuminance_UB1 = class(TFormatDescriptor) //1* unsigned byte
  1012. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1013. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1014. constructor Create; override;
  1015. end;
  1016. TfdUniversal_UB1 = class(TFormatDescriptor) //1* unsigned byte
  1017. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1018. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1019. constructor Create; override;
  1020. end;
  1021. TfdLuminanceAlpha_UB2 = class(TfdLuminance_UB1) //2* unsigned byte
  1022. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1023. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1024. constructor Create; override;
  1025. end;
  1026. TfdRGB_UB3 = class(TFormatDescriptor) //3* unsigned byte
  1027. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1028. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1029. constructor Create; override;
  1030. end;
  1031. TfdBGR_UB3 = class(TFormatDescriptor) //3* unsigned byte (inverse)
  1032. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1033. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1034. constructor Create; override;
  1035. end;
  1036. TfdRGBA_UB4 = class(TfdRGB_UB3) //4* unsigned byte
  1037. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1038. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1039. constructor Create; override;
  1040. end;
  1041. TfdBGRA_UB4 = class(TfdBGR_UB3) //4* unsigned byte (inverse)
  1042. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1043. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1044. constructor Create; override;
  1045. end;
  1046. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1047. TfdAlpha_US1 = class(TFormatDescriptor) //1* unsigned short
  1048. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1049. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1050. constructor Create; override;
  1051. end;
  1052. TfdLuminance_US1 = class(TFormatDescriptor) //1* unsigned short
  1053. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1054. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1055. constructor Create; override;
  1056. end;
  1057. TfdUniversal_US1 = class(TFormatDescriptor) //1* unsigned short
  1058. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1059. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1060. constructor Create; override;
  1061. end;
  1062. TfdDepth_US1 = class(TFormatDescriptor) //1* unsigned short
  1063. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1064. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1065. constructor Create; override;
  1066. end;
  1067. TfdLuminanceAlpha_US2 = class(TfdLuminance_US1) //2* unsigned short
  1068. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1069. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1070. constructor Create; override;
  1071. end;
  1072. TfdRGB_US3 = class(TFormatDescriptor) //3* unsigned short
  1073. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1074. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1075. constructor Create; override;
  1076. end;
  1077. TfdBGR_US3 = class(TFormatDescriptor) //3* unsigned short (inverse)
  1078. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1079. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1080. constructor Create; override;
  1081. end;
  1082. TfdRGBA_US4 = class(TfdRGB_US3) //4* unsigned short
  1083. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1084. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1085. constructor Create; override;
  1086. end;
  1087. TfdBGRA_US4 = class(TfdBGR_US3) //4* unsigned short (inverse)
  1088. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1089. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1090. constructor Create; override;
  1091. end;
  1092. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1093. TfdUniversal_UI1 = class(TFormatDescriptor) //1* unsigned int
  1094. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1095. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1096. constructor Create; override;
  1097. end;
  1098. TfdDepth_UI1 = class(TFormatDescriptor) //1* unsigned int
  1099. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1100. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1101. constructor Create; override;
  1102. end;
  1103. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1104. TfdAlpha4 = class(TfdAlpha_UB1)
  1105. constructor Create; override;
  1106. end;
  1107. TfdAlpha8 = class(TfdAlpha_UB1)
  1108. constructor Create; override;
  1109. end;
  1110. TfdAlpha12 = class(TfdAlpha_US1)
  1111. constructor Create; override;
  1112. end;
  1113. TfdAlpha16 = class(TfdAlpha_US1)
  1114. constructor Create; override;
  1115. end;
  1116. TfdLuminance4 = class(TfdLuminance_UB1)
  1117. constructor Create; override;
  1118. end;
  1119. TfdLuminance8 = class(TfdLuminance_UB1)
  1120. constructor Create; override;
  1121. end;
  1122. TfdLuminance12 = class(TfdLuminance_US1)
  1123. constructor Create; override;
  1124. end;
  1125. TfdLuminance16 = class(TfdLuminance_US1)
  1126. constructor Create; override;
  1127. end;
  1128. TfdLuminance4Alpha4 = class(TfdLuminanceAlpha_UB2)
  1129. constructor Create; override;
  1130. end;
  1131. TfdLuminance6Alpha2 = class(TfdLuminanceAlpha_UB2)
  1132. constructor Create; override;
  1133. end;
  1134. TfdLuminance8Alpha8 = class(TfdLuminanceAlpha_UB2)
  1135. constructor Create; override;
  1136. end;
  1137. TfdLuminance12Alpha4 = class(TfdLuminanceAlpha_US2)
  1138. constructor Create; override;
  1139. end;
  1140. TfdLuminance12Alpha12 = class(TfdLuminanceAlpha_US2)
  1141. constructor Create; override;
  1142. end;
  1143. TfdLuminance16Alpha16 = class(TfdLuminanceAlpha_US2)
  1144. constructor Create; override;
  1145. end;
  1146. TfdR3G3B2 = class(TfdUniversal_UB1)
  1147. constructor Create; override;
  1148. end;
  1149. TfdRGB4 = class(TfdUniversal_US1)
  1150. constructor Create; override;
  1151. end;
  1152. TfdR5G6B5 = class(TfdUniversal_US1)
  1153. constructor Create; override;
  1154. end;
  1155. TfdRGB5 = class(TfdUniversal_US1)
  1156. constructor Create; override;
  1157. end;
  1158. TfdRGB8 = class(TfdRGB_UB3)
  1159. constructor Create; override;
  1160. end;
  1161. TfdRGB10 = class(TfdUniversal_UI1)
  1162. constructor Create; override;
  1163. end;
  1164. TfdRGB12 = class(TfdRGB_US3)
  1165. constructor Create; override;
  1166. end;
  1167. TfdRGB16 = class(TfdRGB_US3)
  1168. constructor Create; override;
  1169. end;
  1170. TfdRGBA2 = class(TfdRGBA_UB4)
  1171. constructor Create; override;
  1172. end;
  1173. TfdRGBA4 = class(TfdUniversal_US1)
  1174. constructor Create; override;
  1175. end;
  1176. TfdRGB5A1 = class(TfdUniversal_US1)
  1177. constructor Create; override;
  1178. end;
  1179. TfdRGBA8 = class(TfdRGBA_UB4)
  1180. constructor Create; override;
  1181. end;
  1182. TfdRGB10A2 = class(TfdUniversal_UI1)
  1183. constructor Create; override;
  1184. end;
  1185. TfdRGBA12 = class(TfdRGBA_US4)
  1186. constructor Create; override;
  1187. end;
  1188. TfdRGBA16 = class(TfdRGBA_US4)
  1189. constructor Create; override;
  1190. end;
  1191. TfdBGR4 = class(TfdUniversal_US1)
  1192. constructor Create; override;
  1193. end;
  1194. TfdB5G6R5 = class(TfdUniversal_US1)
  1195. constructor Create; override;
  1196. end;
  1197. TfdBGR5 = class(TfdUniversal_US1)
  1198. constructor Create; override;
  1199. end;
  1200. TfdBGR8 = class(TfdBGR_UB3)
  1201. constructor Create; override;
  1202. end;
  1203. TfdBGR10 = class(TfdUniversal_UI1)
  1204. constructor Create; override;
  1205. end;
  1206. TfdBGR12 = class(TfdBGR_US3)
  1207. constructor Create; override;
  1208. end;
  1209. TfdBGR16 = class(TfdBGR_US3)
  1210. constructor Create; override;
  1211. end;
  1212. TfdBGRA2 = class(TfdBGRA_UB4)
  1213. constructor Create; override;
  1214. end;
  1215. TfdBGRA4 = class(TfdUniversal_US1)
  1216. constructor Create; override;
  1217. end;
  1218. TfdBGR5A1 = class(TfdUniversal_US1)
  1219. constructor Create; override;
  1220. end;
  1221. TfdBGRA8 = class(TfdBGRA_UB4)
  1222. constructor Create; override;
  1223. end;
  1224. TfdBGR10A2 = class(TfdUniversal_UI1)
  1225. constructor Create; override;
  1226. end;
  1227. TfdBGRA12 = class(TfdBGRA_US4)
  1228. constructor Create; override;
  1229. end;
  1230. TfdBGRA16 = class(TfdBGRA_US4)
  1231. constructor Create; override;
  1232. end;
  1233. TfdDepth16 = class(TfdDepth_US1)
  1234. constructor Create; override;
  1235. end;
  1236. TfdDepth24 = class(TfdDepth_UI1)
  1237. constructor Create; override;
  1238. end;
  1239. TfdDepth32 = class(TfdDepth_UI1)
  1240. constructor Create; override;
  1241. end;
  1242. TfdS3tcDtx1RGBA = class(TFormatDescriptor)
  1243. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1244. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1245. constructor Create; override;
  1246. end;
  1247. TfdS3tcDtx3RGBA = class(TFormatDescriptor)
  1248. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1249. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1250. constructor Create; override;
  1251. end;
  1252. TfdS3tcDtx5RGBA = class(TFormatDescriptor)
  1253. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1254. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1255. constructor Create; override;
  1256. end;
  1257. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1258. TbmpBitfieldFormat = class(TFormatDescriptor)
  1259. private
  1260. procedure SetRedMask (const aValue: QWord);
  1261. procedure SetGreenMask(const aValue: QWord);
  1262. procedure SetBlueMask (const aValue: QWord);
  1263. procedure SetAlphaMask(const aValue: QWord);
  1264. procedure Update(aMask: QWord; out aRange: Cardinal; out aShift: Byte);
  1265. public
  1266. property RedMask: QWord read GetRedMask write SetRedMask;
  1267. property GreenMask: QWord read GetGreenMask write SetGreenMask;
  1268. property BlueMask: QWord read GetBlueMask write SetBlueMask;
  1269. property AlphaMask: QWord read GetAlphaMask write SetAlphaMask;
  1270. property PixelSize: Single read fPixelSize write fPixelSize;
  1271. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1272. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1273. end;
  1274. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1275. TbmpColorTableEnty = packed record
  1276. b, g, r, a: Byte;
  1277. end;
  1278. TbmpColorTable = array of TbmpColorTableEnty;
  1279. TbmpColorTableFormat = class(TFormatDescriptor)
  1280. private
  1281. fColorTable: TbmpColorTable;
  1282. public
  1283. property PixelSize: Single read fPixelSize write fPixelSize;
  1284. property ColorTable: TbmpColorTable read fColorTable write fColorTable;
  1285. property Range: TglBitmapColorRec read fRange write fRange;
  1286. property Shift: TShiftRec read fShift write fShift;
  1287. property Format: TglBitmapFormat read fFormat write fFormat;
  1288. procedure CreateColorTable;
  1289. procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
  1290. procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
  1291. destructor Destroy; override;
  1292. end;
  1293. const
  1294. LUMINANCE_WEIGHT_R = 0.30;
  1295. LUMINANCE_WEIGHT_G = 0.59;
  1296. LUMINANCE_WEIGHT_B = 0.11;
  1297. ALPHA_WEIGHT_R = 0.30;
  1298. ALPHA_WEIGHT_G = 0.59;
  1299. ALPHA_WEIGHT_B = 0.11;
  1300. DEPTH_WEIGHT_R = 0.333333333;
  1301. DEPTH_WEIGHT_G = 0.333333333;
  1302. DEPTH_WEIGHT_B = 0.333333333;
  1303. UNSUPPORTED_FORMAT = 'the given format isn''t supported by this function.';
  1304. FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
  1305. TfdEmpty,
  1306. TfdAlpha4,
  1307. TfdAlpha8,
  1308. TfdAlpha12,
  1309. TfdAlpha16,
  1310. TfdLuminance4,
  1311. TfdLuminance8,
  1312. TfdLuminance12,
  1313. TfdLuminance16,
  1314. TfdLuminance4Alpha4,
  1315. TfdLuminance6Alpha2,
  1316. TfdLuminance8Alpha8,
  1317. TfdLuminance12Alpha4,
  1318. TfdLuminance12Alpha12,
  1319. TfdLuminance16Alpha16,
  1320. TfdR3G3B2,
  1321. TfdRGB4,
  1322. TfdR5G6B5,
  1323. TfdRGB5,
  1324. TfdRGB8,
  1325. TfdRGB10,
  1326. TfdRGB12,
  1327. TfdRGB16,
  1328. TfdRGBA2,
  1329. TfdRGBA4,
  1330. TfdRGB5A1,
  1331. TfdRGBA8,
  1332. TfdRGB10A2,
  1333. TfdRGBA12,
  1334. TfdRGBA16,
  1335. TfdBGR4,
  1336. TfdB5G6R5,
  1337. TfdBGR5,
  1338. TfdBGR8,
  1339. TfdBGR10,
  1340. TfdBGR12,
  1341. TfdBGR16,
  1342. TfdBGRA2,
  1343. TfdBGRA4,
  1344. TfdBGR5A1,
  1345. TfdBGRA8,
  1346. TfdBGR10A2,
  1347. TfdBGRA12,
  1348. TfdBGRA16,
  1349. TfdDepth16,
  1350. TfdDepth24,
  1351. TfdDepth32,
  1352. TfdS3tcDtx1RGBA,
  1353. TfdS3tcDtx3RGBA,
  1354. TfdS3tcDtx5RGBA
  1355. );
  1356. var
  1357. FormatDescriptorCS: TCriticalSection;
  1358. FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
  1359. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1360. constructor EglBitmapUnsupportedFormat.Create(const aFormat: TglBitmapFormat);
  1361. begin
  1362. inherited Create('unsupported format: ' + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
  1363. end;
  1364. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1365. constructor EglBitmapUnsupportedFormat.Create(const aMsg: String; const aFormat: TglBitmapFormat);
  1366. begin
  1367. inherited Create(aMsg + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
  1368. end;
  1369. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1370. function glBitmapPosition(X, Y: Integer): TglBitmapPixelPosition;
  1371. begin
  1372. result.Fields := [];
  1373. if X >= 0 then
  1374. result.Fields := result.Fields + [ffX];
  1375. if Y >= 0 then
  1376. result.Fields := result.Fields + [ffY];
  1377. result.X := Max(0, X);
  1378. result.Y := Max(0, Y);
  1379. end;
  1380. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1381. function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
  1382. begin
  1383. result.r := r;
  1384. result.g := g;
  1385. result.b := b;
  1386. result.a := a;
  1387. end;
  1388. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1389. function glBitmapColorRecCmp(const r1, r2: TglBitmapColorRec): Boolean;
  1390. var
  1391. i: Integer;
  1392. begin
  1393. result := false;
  1394. for i := 0 to high(r1.arr) do
  1395. if (r1.arr[i] <> r2.arr[i]) then
  1396. exit;
  1397. result := true;
  1398. end;
  1399. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1400. function glBitmapShiftRec(const r, g, b, a: Byte): TShiftRec;
  1401. begin
  1402. result.r := r;
  1403. result.g := g;
  1404. result.b := b;
  1405. result.a := a;
  1406. end;
  1407. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1408. function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
  1409. begin
  1410. result := [];
  1411. if (aFormat in [
  1412. //4 bbp
  1413. tfLuminance4,
  1414. //8bpp
  1415. tfR3G3B2, tfLuminance8,
  1416. //16bpp
  1417. tfRGB4, tfRGB5, tfR5G6B5, tfRGB5A1, tfRGBA4,
  1418. tfBGR4, tfBGR5, tfB5G6R5, tfBGR5A1, tfBGRA4,
  1419. //24bpp
  1420. tfBGR8, tfRGB8,
  1421. //32bpp
  1422. tfRGB10, tfRGB10A2, tfRGBA8,
  1423. tfBGR10, tfBGR10A2, tfBGRA8]) then
  1424. result := result + [ftBMP];
  1425. if (aFormat in [
  1426. //8 bpp
  1427. tfLuminance8, tfAlpha8,
  1428. //16 bpp
  1429. tfLuminance16, tfLuminance8Alpha8,
  1430. tfRGB5, tfRGB5A1, tfRGBA4,
  1431. tfBGR5, tfBGR5A1, tfBGRA4,
  1432. //24 bpp
  1433. tfRGB8, tfBGR8,
  1434. //32 bpp
  1435. tfRGB10A2, tfRGBA8, tfBGR10A2, tfBGRA8]) then
  1436. result := result + [ftTGA];
  1437. if (aFormat in [
  1438. //8 bpp
  1439. tfAlpha8, tfLuminance8, tfLuminance4Alpha4, tfLuminance6Alpha2,
  1440. tfR3G3B2, tfRGBA2, tfBGRA2,
  1441. //16 bpp
  1442. tfAlpha16, tfLuminance16, tfLuminance8Alpha8, tfLuminance12Alpha4,
  1443. tfRGB4, tfR5G6B5, tfRGB5, tfRGBA4, tfRGB5A1,
  1444. tfBGR4, tfB5G6R5, tfBGR5, tfBGRA4, tfBGR5A1,
  1445. //24 bpp
  1446. tfRGB8, tfBGR8,
  1447. //32 bbp
  1448. tfLuminance16Alpha16,
  1449. tfRGBA8, tfRGB10A2,
  1450. tfBGRA8, tfBGR10A2,
  1451. //compressed
  1452. tfS3tcDtx1RGBA, tfS3tcDtx3RGBA, tfS3tcDtx5RGBA]) then
  1453. result := result + [ftDDS];
  1454. {$IFDEF GLB_SUPPORT_PNG_WRITE}
  1455. if aFormat in [
  1456. tfAlpha8, tfLuminance8, tfLuminance8Alpha8,
  1457. tfRGB8, tfRGBA8,
  1458. tfBGR8, tfBGRA8] then
  1459. result := result + [ftPNG];
  1460. {$ENDIF}
  1461. {$IFDEF GLB_SUPPORT_JPEG_WRITE}
  1462. if aFormat in [tfAlpha8, tfLuminance8, tfRGB8, tfBGR8] then
  1463. result := result + [ftJPEG];
  1464. {$ENDIF}
  1465. end;
  1466. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1467. function IsPowerOfTwo(aNumber: Integer): Boolean;
  1468. begin
  1469. while (aNumber and 1) = 0 do
  1470. aNumber := aNumber shr 1;
  1471. result := aNumber = 1;
  1472. end;
  1473. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1474. function GetTopMostBit(aBitSet: QWord): Integer;
  1475. begin
  1476. result := 0;
  1477. while aBitSet > 0 do begin
  1478. inc(result);
  1479. aBitSet := aBitSet shr 1;
  1480. end;
  1481. end;
  1482. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1483. function CountSetBits(aBitSet: QWord): Integer;
  1484. begin
  1485. result := 0;
  1486. while aBitSet > 0 do begin
  1487. if (aBitSet and 1) = 1 then
  1488. inc(result);
  1489. aBitSet := aBitSet shr 1;
  1490. end;
  1491. end;
  1492. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1493. function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
  1494. begin
  1495. result := Trunc(
  1496. LUMINANCE_WEIGHT_R * aPixel.Data.r +
  1497. LUMINANCE_WEIGHT_G * aPixel.Data.g +
  1498. LUMINANCE_WEIGHT_B * aPixel.Data.b);
  1499. end;
  1500. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1501. function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
  1502. begin
  1503. result := Trunc(
  1504. DEPTH_WEIGHT_R * aPixel.Data.r +
  1505. DEPTH_WEIGHT_G * aPixel.Data.g +
  1506. DEPTH_WEIGHT_B * aPixel.Data.b);
  1507. end;
  1508. {$IFDEF GLB_NATIVE_OGL}
  1509. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1510. //OpenGLInitialization///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1511. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1512. var
  1513. GL_LibHandle: Pointer = nil;
  1514. function glbGetProcAddress(aProcName: PChar; aLibHandle: Pointer = nil): Pointer;
  1515. begin
  1516. if not Assigned(aLibHandle) then
  1517. aLibHandle := GL_LibHandle;
  1518. {$IF DEFINED(GLB_WIN)}
  1519. result := GetProcAddress({%H-}HMODULE(aLibHandle), aProcName);
  1520. if Assigned(result) then
  1521. exit;
  1522. if Assigned(wglGetProcAddress) then
  1523. result := wglGetProcAddress(aProcName);
  1524. {$ELSEIF DEFINED(GLB_LINUX)}
  1525. if Assigned(glXGetProcAddress) then begin
  1526. result := glXGetProcAddress(aProcName);
  1527. if Assigned(result) then
  1528. exit;
  1529. end;
  1530. if Assigned(glXGetProcAddressARB) then begin
  1531. result := glXGetProcAddressARB(aProcName);
  1532. if Assigned(result) then
  1533. exit;
  1534. end;
  1535. result := dlsym(aLibHandle, aProcName);
  1536. {$IFEND}
  1537. if not Assigned(result) then
  1538. raise EglBitmapException.Create('unable to load procedure form library: ' + aProcName);
  1539. end;
  1540. {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
  1541. var
  1542. GLU_LibHandle: Pointer = nil;
  1543. OpenGLInitialized: Boolean;
  1544. InitOpenGLCS: TCriticalSection;
  1545. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1546. procedure glbInitOpenGL;
  1547. ////////////////////////////////////////////////////////////////////////////////
  1548. function glbLoadLibrary(const aName: PChar): Pointer;
  1549. begin
  1550. {$IF DEFINED(GLB_WIN)}
  1551. result := {%H-}Pointer(LoadLibrary(aName));
  1552. {$ELSEIF DEFINED(GLB_LINUX)}
  1553. result := dlopen(Name, RTLD_LAZY);
  1554. {$ELSE}
  1555. result := nil;
  1556. {$IFEND}
  1557. end;
  1558. ////////////////////////////////////////////////////////////////////////////////
  1559. function glbFreeLibrary(const aLibHandle: Pointer): Boolean;
  1560. begin
  1561. result := false;
  1562. if not Assigned(aLibHandle) then
  1563. exit;
  1564. {$IF DEFINED(GLB_WIN)}
  1565. Result := FreeLibrary({%H-}HINST(aLibHandle));
  1566. {$ELSEIF DEFINED(GLB_LINUX)}
  1567. Result := dlclose(aLibHandle) = 0;
  1568. {$IFEND}
  1569. end;
  1570. begin
  1571. if Assigned(GL_LibHandle) then
  1572. glbFreeLibrary(GL_LibHandle);
  1573. if Assigned(GLU_LibHandle) then
  1574. glbFreeLibrary(GLU_LibHandle);
  1575. GL_LibHandle := glbLoadLibrary(libopengl);
  1576. if not Assigned(GL_LibHandle) then
  1577. raise EglBitmapException.Create('unable to load library: ' + libopengl);
  1578. GLU_LibHandle := glbLoadLibrary(libglu);
  1579. if not Assigned(GLU_LibHandle) then
  1580. raise EglBitmapException.Create('unable to load library: ' + libglu);
  1581. try
  1582. {$IF DEFINED(GLB_WIN)}
  1583. wglGetProcAddress := glbGetProcAddress('wglGetProcAddress');
  1584. {$ELSEIF DEFINED(GLB_LINUX)}
  1585. glXGetProcAddress := glbGetProcAddress('glXGetProcAddress');
  1586. glXGetProcAddressARB := glbGetProcAddress('glXGetProcAddressARB');
  1587. {$IFEND}
  1588. glEnable := glbGetProcAddress('glEnable');
  1589. glDisable := glbGetProcAddress('glDisable');
  1590. glGetString := glbGetProcAddress('glGetString');
  1591. glGetIntegerv := glbGetProcAddress('glGetIntegerv');
  1592. glTexParameteri := glbGetProcAddress('glTexParameteri');
  1593. glTexParameterfv := glbGetProcAddress('glTexParameterfv');
  1594. glGetTexParameteriv := glbGetProcAddress('glGetTexParameteriv');
  1595. glGetTexParameterfv := glbGetProcAddress('glGetTexParameterfv');
  1596. glGetTexLevelParameteriv := glbGetProcAddress('glGetTexLevelParameteriv');
  1597. glGetTexLevelParameterfv := glbGetProcAddress('glGetTexLevelParameterfv');
  1598. glGenTextures := glbGetProcAddress('glGenTextures');
  1599. glBindTexture := glbGetProcAddress('glBindTexture');
  1600. glDeleteTextures := glbGetProcAddress('glDeleteTextures');
  1601. glAreTexturesResident := glbGetProcAddress('glAreTexturesResident');
  1602. glReadPixels := glbGetProcAddress('glReadPixels');
  1603. glPixelStorei := glbGetProcAddress('glPixelStorei');
  1604. glTexImage1D := glbGetProcAddress('glTexImage1D');
  1605. glTexImage2D := glbGetProcAddress('glTexImage2D');
  1606. glGetTexImage := glbGetProcAddress('glGetTexImage');
  1607. gluBuild1DMipmaps := glbGetProcAddress('gluBuild1DMipmaps', GLU_LibHandle);
  1608. gluBuild2DMipmaps := glbGetProcAddress('gluBuild2DMipmaps', GLU_LibHandle);
  1609. finally
  1610. glbFreeLibrary(GL_LibHandle);
  1611. glbFreeLibrary(GLU_LibHandle);
  1612. end;
  1613. end;
  1614. {$ENDIF}
  1615. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1616. procedure glbReadOpenGLExtensions;
  1617. var
  1618. Buffer: AnsiString;
  1619. MajorVersion, MinorVersion: Integer;
  1620. ///////////////////////////////////////////////////////////////////////////////////////////
  1621. procedure TrimVersionString(aBuffer: AnsiString; out aMajor, aMinor: Integer);
  1622. var
  1623. Separator: Integer;
  1624. begin
  1625. aMinor := 0;
  1626. aMajor := 0;
  1627. Separator := Pos(AnsiString('.'), aBuffer);
  1628. if (Separator > 1) and (Separator < Length(aBuffer)) and
  1629. (aBuffer[Separator - 1] in ['0'..'9']) and
  1630. (aBuffer[Separator + 1] in ['0'..'9']) then begin
  1631. Dec(Separator);
  1632. while (Separator > 0) and (aBuffer[Separator] in ['0'..'9']) do
  1633. Dec(Separator);
  1634. Delete(aBuffer, 1, Separator);
  1635. Separator := Pos(AnsiString('.'), aBuffer) + 1;
  1636. while (Separator <= Length(aBuffer)) and (AnsiChar(aBuffer[Separator]) in ['0'..'9']) do
  1637. Inc(Separator);
  1638. Delete(aBuffer, Separator, 255);
  1639. Separator := Pos(AnsiString('.'), aBuffer);
  1640. aMajor := StrToInt(Copy(String(aBuffer), 1, Separator - 1));
  1641. aMinor := StrToInt(Copy(String(aBuffer), Separator + 1, 1));
  1642. end;
  1643. end;
  1644. ///////////////////////////////////////////////////////////////////////////////////////////
  1645. function CheckExtension(const Extension: AnsiString): Boolean;
  1646. var
  1647. ExtPos: Integer;
  1648. begin
  1649. ExtPos := Pos(Extension, Buffer);
  1650. result := ExtPos > 0;
  1651. if result then
  1652. result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
  1653. end;
  1654. begin
  1655. {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
  1656. InitOpenGLCS.Enter;
  1657. try
  1658. if not OpenGLInitialized then begin
  1659. glbInitOpenGL;
  1660. OpenGLInitialized := true;
  1661. end;
  1662. finally
  1663. InitOpenGLCS.Leave;
  1664. end;
  1665. {$ENDIF}
  1666. // Version
  1667. Buffer := glGetString(GL_VERSION);
  1668. TrimVersionString(Buffer, MajorVersion, MinorVersion);
  1669. GL_VERSION_1_2 := false;
  1670. GL_VERSION_1_3 := false;
  1671. GL_VERSION_1_4 := false;
  1672. GL_VERSION_2_0 := false;
  1673. if MajorVersion = 1 then begin
  1674. if MinorVersion >= 2 then
  1675. GL_VERSION_1_2 := true;
  1676. if MinorVersion >= 3 then
  1677. GL_VERSION_1_3 := true;
  1678. if MinorVersion >= 4 then
  1679. GL_VERSION_1_4 := true;
  1680. end else if MajorVersion >= 2 then begin
  1681. GL_VERSION_1_2 := true;
  1682. GL_VERSION_1_3 := true;
  1683. GL_VERSION_1_4 := true;
  1684. GL_VERSION_2_0 := true;
  1685. end;
  1686. // Extensions
  1687. Buffer := glGetString(GL_EXTENSIONS);
  1688. GL_ARB_texture_border_clamp := CheckExtension('GL_ARB_texture_border_clamp');
  1689. GL_ARB_texture_non_power_of_two := CheckExtension('GL_ARB_texture_non_power_of_two');
  1690. GL_ARB_texture_rectangle := CheckExtension('GL_ARB_texture_rectangle');
  1691. GL_ARB_texture_mirrored_repeat := CheckExtension('GL_ARB_texture_mirrored_repeat');
  1692. GL_EXT_texture_edge_clamp := CheckExtension('GL_EXT_texture_edge_clamp');
  1693. GL_EXT_texture_filter_anisotropic := CheckExtension('GL_EXT_texture_filter_anisotropic');
  1694. GL_EXT_texture_rectangle := CheckExtension('GL_EXT_texture_rectangle');
  1695. GL_NV_texture_rectangle := CheckExtension('GL_NV_texture_rectangle');
  1696. GL_IBM_texture_mirrored_repeat := CheckExtension('GL_IBM_texture_mirrored_repeat');
  1697. GL_SGIS_generate_mipmap := CheckExtension('GL_SGIS_generate_mipmap');
  1698. if GL_VERSION_1_3 then begin
  1699. glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1D');
  1700. glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2D');
  1701. glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImage');
  1702. end else begin
  1703. glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1DARB');
  1704. glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2DARB');
  1705. glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImageARB');
  1706. end;
  1707. end;
  1708. {$ENDIF}
  1709. (* TODO GLB_DELPHI
  1710. {$IFDEF GLB_DELPHI}
  1711. function CreateGrayPalette: HPALETTE;
  1712. var
  1713. Idx: Integer;
  1714. Pal: PLogPalette;
  1715. begin
  1716. GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
  1717. Pal.palVersion := $300;
  1718. Pal.palNumEntries := 256;
  1719. {$IFOPT R+}
  1720. {$DEFINE GLB_TEMPRANGECHECK}
  1721. {$R-}
  1722. {$ENDIF}
  1723. for Idx := 0 to 256 - 1 do begin
  1724. Pal.palPalEntry[Idx].peRed := Idx;
  1725. Pal.palPalEntry[Idx].peGreen := Idx;
  1726. Pal.palPalEntry[Idx].peBlue := Idx;
  1727. Pal.palPalEntry[Idx].peFlags := 0;
  1728. end;
  1729. {$IFDEF GLB_TEMPRANGECHECK}
  1730. {$UNDEF GLB_TEMPRANGECHECK}
  1731. {$R+}
  1732. {$ENDIF}
  1733. result := CreatePalette(Pal^);
  1734. FreeMem(Pal);
  1735. end;
  1736. {$ENDIF}
  1737. *)
  1738. {$IFDEF GLB_SDL_IMAGE}
  1739. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1740. // SDL Image Helper /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1741. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1742. function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
  1743. begin
  1744. result := TStream(context^.unknown.data1).Seek(offset, whence);
  1745. end;
  1746. function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
  1747. begin
  1748. result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
  1749. end;
  1750. function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
  1751. begin
  1752. result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
  1753. end;
  1754. function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
  1755. begin
  1756. result := 0;
  1757. end;
  1758. function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
  1759. begin
  1760. result := SDL_AllocRW;
  1761. if result = nil then
  1762. raise EglBitmapException.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
  1763. result^.seek := glBitmapRWseek;
  1764. result^.read := glBitmapRWread;
  1765. result^.write := glBitmapRWwrite;
  1766. result^.close := glBitmapRWclose;
  1767. result^.unknown.data1 := Stream;
  1768. end;
  1769. {$ENDIF}
  1770. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1771. procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
  1772. begin
  1773. glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
  1774. end;
  1775. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1776. procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
  1777. begin
  1778. glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
  1779. end;
  1780. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1781. procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
  1782. begin
  1783. glBitmapDefaultMipmap := aValue;
  1784. end;
  1785. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1786. procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
  1787. begin
  1788. glBitmapDefaultFormat := aFormat;
  1789. end;
  1790. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1791. procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
  1792. begin
  1793. glBitmapDefaultFilterMin := aMin;
  1794. glBitmapDefaultFilterMag := aMag;
  1795. end;
  1796. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1797. procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
  1798. begin
  1799. glBitmapDefaultWrapS := S;
  1800. glBitmapDefaultWrapT := T;
  1801. glBitmapDefaultWrapR := R;
  1802. end;
  1803. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1804. function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
  1805. begin
  1806. result := glBitmapDefaultDeleteTextureOnFree;
  1807. end;
  1808. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1809. function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
  1810. begin
  1811. result := glBitmapDefaultFreeDataAfterGenTextures;
  1812. end;
  1813. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1814. function glBitmapGetDefaultMipmap: TglBitmapMipMap;
  1815. begin
  1816. result := glBitmapDefaultMipmap;
  1817. end;
  1818. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1819. function glBitmapGetDefaultFormat: TglBitmapFormat;
  1820. begin
  1821. result := glBitmapDefaultFormat;
  1822. end;
  1823. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1824. procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
  1825. begin
  1826. aMin := glBitmapDefaultFilterMin;
  1827. aMag := glBitmapDefaultFilterMag;
  1828. end;
  1829. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1830. procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
  1831. begin
  1832. S := glBitmapDefaultWrapS;
  1833. T := glBitmapDefaultWrapT;
  1834. R := glBitmapDefaultWrapR;
  1835. end;
  1836. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1837. //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1838. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1839. function TFormatDescriptor.GetRedMask: QWord;
  1840. begin
  1841. result := fRange.r shl fShift.r;
  1842. end;
  1843. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1844. function TFormatDescriptor.GetGreenMask: QWord;
  1845. begin
  1846. result := fRange.g shl fShift.g;
  1847. end;
  1848. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1849. function TFormatDescriptor.GetBlueMask: QWord;
  1850. begin
  1851. result := fRange.b shl fShift.b;
  1852. end;
  1853. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1854. function TFormatDescriptor.GetAlphaMask: QWord;
  1855. begin
  1856. result := fRange.a shl fShift.a;
  1857. end;
  1858. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1859. function TFormatDescriptor.GetComponents: Integer;
  1860. var
  1861. i: Integer;
  1862. begin
  1863. result := 0;
  1864. for i := 0 to 3 do
  1865. if (fRange.arr[i] > 0) then
  1866. inc(result);
  1867. end;
  1868. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1869. function TFormatDescriptor.GetSize(const aSize: TglBitmapPixelPosition): Integer;
  1870. var
  1871. w, h: Integer;
  1872. begin
  1873. if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
  1874. w := Max(1, aSize.X);
  1875. h := Max(1, aSize.Y);
  1876. result := GetSize(w, h);
  1877. end else
  1878. result := 0;
  1879. end;
  1880. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1881. function TFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer;
  1882. begin
  1883. result := 0;
  1884. if (aWidth <= 0) or (aHeight <= 0) then
  1885. exit;
  1886. result := Ceil(aWidth * aHeight * fPixelSize);
  1887. end;
  1888. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1889. function TFormatDescriptor.CreateMappingData: Pointer;
  1890. begin
  1891. result := nil;
  1892. end;
  1893. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1894. procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
  1895. begin
  1896. //DUMMY
  1897. end;
  1898. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1899. function TFormatDescriptor.IsEmpty: Boolean;
  1900. begin
  1901. result := (fFormat = tfEmpty);
  1902. end;
  1903. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1904. function TFormatDescriptor.HasAlpha: Boolean;
  1905. begin
  1906. result := (fRange.a > 0);
  1907. end;
  1908. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1909. function TFormatDescriptor.MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: QWord): Boolean;
  1910. begin
  1911. result := false;
  1912. if (aRedMask = 0) and (aGreenMask = 0) and (aBlueMask = 0) and (aAlphaMask = 0) then
  1913. raise EglBitmapException.Create('FormatCheckFormat - All Masks are 0');
  1914. if (aRedMask <> RedMask) then
  1915. exit;
  1916. if (aGreenMask <> GreenMask) then
  1917. exit;
  1918. if (aBlueMask <> BlueMask) then
  1919. exit;
  1920. if (aAlphaMask <> AlphaMask) then
  1921. exit;
  1922. result := true;
  1923. end;
  1924. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1925. procedure TFormatDescriptor.PreparePixel(out aPixel: TglBitmapPixelData);
  1926. begin
  1927. FillChar(aPixel{%H-}, SizeOf(aPixel), 0);
  1928. aPixel.Data := fRange;
  1929. aPixel.Range := fRange;
  1930. aPixel.Format := fFormat;
  1931. end;
  1932. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1933. constructor TFormatDescriptor.Create;
  1934. begin
  1935. inherited Create;
  1936. fFormat := tfEmpty;
  1937. fWithAlpha := tfEmpty;
  1938. fWithoutAlpha := tfEmpty;
  1939. fRGBInverted := tfEmpty;
  1940. fUncompressed := tfEmpty;
  1941. fPixelSize := 0.0;
  1942. fIsCompressed := false;
  1943. fglFormat := 0;
  1944. fglInternalFormat := 0;
  1945. fglDataFormat := 0;
  1946. FillChar(fRange, 0, SizeOf(fRange));
  1947. FillChar(fShift, 0, SizeOf(fShift));
  1948. end;
  1949. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1950. //TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1951. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1952. procedure TfdAlpha_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  1953. begin
  1954. aData^ := aPixel.Data.a;
  1955. inc(aData);
  1956. end;
  1957. procedure TfdAlpha_UB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  1958. begin
  1959. aPixel.Data.r := 0;
  1960. aPixel.Data.g := 0;
  1961. aPixel.Data.b := 0;
  1962. aPixel.Data.a := aData^;
  1963. inc(aData);
  1964. end;
  1965. constructor TfdAlpha_UB1.Create;
  1966. begin
  1967. inherited Create;
  1968. fPixelSize := 1.0;
  1969. fRange.a := $FF;
  1970. fglFormat := GL_ALPHA;
  1971. fglDataFormat := GL_UNSIGNED_BYTE;
  1972. end;
  1973. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1974. //TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1975. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1976. procedure TfdLuminance_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  1977. begin
  1978. aData^ := LuminanceWeight(aPixel);
  1979. inc(aData);
  1980. end;
  1981. procedure TfdLuminance_UB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  1982. begin
  1983. aPixel.Data.r := aData^;
  1984. aPixel.Data.g := aData^;
  1985. aPixel.Data.b := aData^;
  1986. aPixel.Data.a := 0;
  1987. inc(aData);
  1988. end;
  1989. constructor TfdLuminance_UB1.Create;
  1990. begin
  1991. inherited Create;
  1992. fPixelSize := 1.0;
  1993. fRange.r := $FF;
  1994. fRange.g := $FF;
  1995. fRange.b := $FF;
  1996. fglFormat := GL_LUMINANCE;
  1997. fglDataFormat := GL_UNSIGNED_BYTE;
  1998. end;
  1999. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2000. //TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2001. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2002. procedure TfdUniversal_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2003. var
  2004. i: Integer;
  2005. begin
  2006. aData^ := 0;
  2007. for i := 0 to 3 do
  2008. if (fRange.arr[i] > 0) then
  2009. aData^ := aData^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
  2010. inc(aData);
  2011. end;
  2012. procedure TfdUniversal_UB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2013. var
  2014. i: Integer;
  2015. begin
  2016. for i := 0 to 3 do
  2017. aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and fRange.arr[i];
  2018. inc(aData);
  2019. end;
  2020. constructor TfdUniversal_UB1.Create;
  2021. begin
  2022. inherited Create;
  2023. fPixelSize := 1.0;
  2024. end;
  2025. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2026. //TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2027. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2028. procedure TfdLuminanceAlpha_UB2.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 TfdLuminanceAlpha_UB2.Unmap(var aData: PByte; out 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 TfdLuminanceAlpha_UB2.Create;
  2041. begin
  2042. inherited Create;
  2043. fPixelSize := 2.0;
  2044. fRange.a := $FF;
  2045. fShift.a := 8;
  2046. fglFormat := GL_LUMINANCE_ALPHA;
  2047. fglDataFormat := GL_UNSIGNED_BYTE;
  2048. end;
  2049. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2050. //TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2051. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2052. procedure TfdRGB_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2053. begin
  2054. aData^ := aPixel.Data.r;
  2055. inc(aData);
  2056. aData^ := aPixel.Data.g;
  2057. inc(aData);
  2058. aData^ := aPixel.Data.b;
  2059. inc(aData);
  2060. end;
  2061. procedure TfdRGB_UB3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2062. begin
  2063. aPixel.Data.r := aData^;
  2064. inc(aData);
  2065. aPixel.Data.g := aData^;
  2066. inc(aData);
  2067. aPixel.Data.b := aData^;
  2068. inc(aData);
  2069. aPixel.Data.a := 0;
  2070. end;
  2071. constructor TfdRGB_UB3.Create;
  2072. begin
  2073. inherited Create;
  2074. fPixelSize := 3.0;
  2075. fRange.r := $FF;
  2076. fRange.g := $FF;
  2077. fRange.b := $FF;
  2078. fShift.r := 0;
  2079. fShift.g := 8;
  2080. fShift.b := 16;
  2081. fglFormat := GL_RGB;
  2082. fglDataFormat := GL_UNSIGNED_BYTE;
  2083. end;
  2084. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2085. //TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2086. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2087. procedure TfdBGR_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2088. begin
  2089. aData^ := aPixel.Data.b;
  2090. inc(aData);
  2091. aData^ := aPixel.Data.g;
  2092. inc(aData);
  2093. aData^ := aPixel.Data.r;
  2094. inc(aData);
  2095. end;
  2096. procedure TfdBGR_UB3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2097. begin
  2098. aPixel.Data.b := aData^;
  2099. inc(aData);
  2100. aPixel.Data.g := aData^;
  2101. inc(aData);
  2102. aPixel.Data.r := aData^;
  2103. inc(aData);
  2104. aPixel.Data.a := 0;
  2105. end;
  2106. constructor TfdBGR_UB3.Create;
  2107. begin
  2108. fPixelSize := 3.0;
  2109. fRange.r := $FF;
  2110. fRange.g := $FF;
  2111. fRange.b := $FF;
  2112. fShift.r := 16;
  2113. fShift.g := 8;
  2114. fShift.b := 0;
  2115. fglFormat := GL_BGR;
  2116. fglDataFormat := GL_UNSIGNED_BYTE;
  2117. end;
  2118. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2119. //TdfRGBA_UB4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2120. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2121. procedure TfdRGBA_UB4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2122. begin
  2123. inherited Map(aPixel, aData, aMapData);
  2124. aData^ := aPixel.Data.a;
  2125. inc(aData);
  2126. end;
  2127. procedure TfdRGBA_UB4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2128. begin
  2129. inherited Unmap(aData, aPixel, aMapData);
  2130. aPixel.Data.a := aData^;
  2131. inc(aData);
  2132. end;
  2133. constructor TfdRGBA_UB4.Create;
  2134. begin
  2135. inherited Create;
  2136. fPixelSize := 4.0;
  2137. fRange.a := $FF;
  2138. fShift.a := 24;
  2139. fglFormat := GL_RGBA;
  2140. fglDataFormat := GL_UNSIGNED_BYTE;
  2141. end;
  2142. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2143. //TfdBGRA_UB4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2144. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2145. procedure TfdBGRA_UB4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2146. begin
  2147. inherited Map(aPixel, aData, aMapData);
  2148. aData^ := aPixel.Data.a;
  2149. inc(aData);
  2150. end;
  2151. procedure TfdBGRA_UB4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2152. begin
  2153. inherited Unmap(aData, aPixel, aMapData);
  2154. aPixel.Data.a := aData^;
  2155. inc(aData);
  2156. end;
  2157. constructor TfdBGRA_UB4.Create;
  2158. begin
  2159. inherited Create;
  2160. fPixelSize := 4.0;
  2161. fRange.a := $FF;
  2162. fShift.a := 24;
  2163. fglFormat := GL_BGRA;
  2164. fglDataFormat := GL_UNSIGNED_BYTE;
  2165. end;
  2166. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2167. //TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2168. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2169. procedure TfdAlpha_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2170. begin
  2171. PWord(aData)^ := aPixel.Data.a;
  2172. inc(aData, 2);
  2173. end;
  2174. procedure TfdAlpha_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2175. begin
  2176. aPixel.Data.r := 0;
  2177. aPixel.Data.g := 0;
  2178. aPixel.Data.b := 0;
  2179. aPixel.Data.a := PWord(aData)^;
  2180. inc(aData, 2);
  2181. end;
  2182. constructor TfdAlpha_US1.Create;
  2183. begin
  2184. inherited Create;
  2185. fPixelSize := 2.0;
  2186. fRange.a := $FFFF;
  2187. fglFormat := GL_ALPHA;
  2188. fglDataFormat := GL_UNSIGNED_SHORT;
  2189. end;
  2190. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2191. //TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2192. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2193. procedure TfdLuminance_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2194. begin
  2195. PWord(aData)^ := LuminanceWeight(aPixel);
  2196. inc(aData, 2);
  2197. end;
  2198. procedure TfdLuminance_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2199. begin
  2200. aPixel.Data.r := PWord(aData)^;
  2201. aPixel.Data.g := PWord(aData)^;
  2202. aPixel.Data.b := PWord(aData)^;
  2203. aPixel.Data.a := 0;
  2204. inc(aData, 2);
  2205. end;
  2206. constructor TfdLuminance_US1.Create;
  2207. begin
  2208. inherited Create;
  2209. fPixelSize := 2.0;
  2210. fRange.r := $FFFF;
  2211. fRange.g := $FFFF;
  2212. fRange.b := $FFFF;
  2213. fglFormat := GL_LUMINANCE;
  2214. fglDataFormat := GL_UNSIGNED_SHORT;
  2215. end;
  2216. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2217. //TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2218. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2219. procedure TfdUniversal_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2220. var
  2221. i: Integer;
  2222. begin
  2223. PWord(aData)^ := 0;
  2224. for i := 0 to 3 do
  2225. if (fRange.arr[i] > 0) then
  2226. PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
  2227. inc(aData, 2);
  2228. end;
  2229. procedure TfdUniversal_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2230. var
  2231. i: Integer;
  2232. begin
  2233. for i := 0 to 3 do
  2234. aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and fRange.arr[i];
  2235. inc(aData, 2);
  2236. end;
  2237. constructor TfdUniversal_US1.Create;
  2238. begin
  2239. inherited Create;
  2240. fPixelSize := 2.0;
  2241. end;
  2242. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2243. //TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2244. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2245. procedure TfdDepth_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2246. begin
  2247. PWord(aData)^ := DepthWeight(aPixel);
  2248. inc(aData, 2);
  2249. end;
  2250. procedure TfdDepth_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2251. begin
  2252. aPixel.Data.r := PWord(aData)^;
  2253. aPixel.Data.g := PWord(aData)^;
  2254. aPixel.Data.b := PWord(aData)^;
  2255. aPixel.Data.a := 0;
  2256. inc(aData, 2);
  2257. end;
  2258. constructor TfdDepth_US1.Create;
  2259. begin
  2260. inherited Create;
  2261. fPixelSize := 2.0;
  2262. fRange.r := $FFFF;
  2263. fRange.g := $FFFF;
  2264. fRange.b := $FFFF;
  2265. fglFormat := GL_DEPTH_COMPONENT;
  2266. fglDataFormat := GL_UNSIGNED_SHORT;
  2267. end;
  2268. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2269. //TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2270. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2271. procedure TfdLuminanceAlpha_US2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2272. begin
  2273. inherited Map(aPixel, aData, aMapData);
  2274. PWord(aData)^ := aPixel.Data.a;
  2275. inc(aData, 2);
  2276. end;
  2277. procedure TfdLuminanceAlpha_US2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2278. begin
  2279. inherited Unmap(aData, aPixel, aMapData);
  2280. aPixel.Data.a := PWord(aData)^;
  2281. inc(aData, 2);
  2282. end;
  2283. constructor TfdLuminanceAlpha_US2.Create;
  2284. begin
  2285. inherited Create;
  2286. fPixelSize := 4.0;
  2287. fRange.a := $FFFF;
  2288. fShift.a := 16;
  2289. fglFormat := GL_LUMINANCE_ALPHA;
  2290. fglDataFormat := GL_UNSIGNED_SHORT;
  2291. end;
  2292. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2293. //TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2294. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2295. procedure TfdRGB_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2296. begin
  2297. PWord(aData)^ := aPixel.Data.r;
  2298. inc(aData, 2);
  2299. PWord(aData)^ := aPixel.Data.g;
  2300. inc(aData, 2);
  2301. PWord(aData)^ := aPixel.Data.b;
  2302. inc(aData, 2);
  2303. end;
  2304. procedure TfdRGB_US3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2305. begin
  2306. aPixel.Data.r := PWord(aData)^;
  2307. inc(aData, 2);
  2308. aPixel.Data.g := PWord(aData)^;
  2309. inc(aData, 2);
  2310. aPixel.Data.b := PWord(aData)^;
  2311. inc(aData, 2);
  2312. aPixel.Data.a := 0;
  2313. end;
  2314. constructor TfdRGB_US3.Create;
  2315. begin
  2316. inherited Create;
  2317. fPixelSize := 6.0;
  2318. fRange.r := $FFFF;
  2319. fRange.g := $FFFF;
  2320. fRange.b := $FFFF;
  2321. fShift.r := 0;
  2322. fShift.g := 16;
  2323. fShift.b := 32;
  2324. fglFormat := GL_RGB;
  2325. fglDataFormat := GL_UNSIGNED_SHORT;
  2326. end;
  2327. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2328. //TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2329. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2330. procedure TfdBGR_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2331. begin
  2332. PWord(aData)^ := aPixel.Data.b;
  2333. inc(aData, 2);
  2334. PWord(aData)^ := aPixel.Data.g;
  2335. inc(aData, 2);
  2336. PWord(aData)^ := aPixel.Data.r;
  2337. inc(aData, 2);
  2338. end;
  2339. procedure TfdBGR_US3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2340. begin
  2341. aPixel.Data.b := PWord(aData)^;
  2342. inc(aData, 2);
  2343. aPixel.Data.g := PWord(aData)^;
  2344. inc(aData, 2);
  2345. aPixel.Data.r := PWord(aData)^;
  2346. inc(aData, 2);
  2347. aPixel.Data.a := 0;
  2348. end;
  2349. constructor TfdBGR_US3.Create;
  2350. begin
  2351. inherited Create;
  2352. fPixelSize := 6.0;
  2353. fRange.r := $FFFF;
  2354. fRange.g := $FFFF;
  2355. fRange.b := $FFFF;
  2356. fShift.r := 32;
  2357. fShift.g := 16;
  2358. fShift.b := 0;
  2359. fglFormat := GL_BGR;
  2360. fglDataFormat := GL_UNSIGNED_SHORT;
  2361. end;
  2362. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2363. //TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2364. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2365. procedure TfdRGBA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2366. begin
  2367. inherited Map(aPixel, aData, aMapData);
  2368. PWord(aData)^ := aPixel.Data.a;
  2369. inc(aData, 2);
  2370. end;
  2371. procedure TfdRGBA_US4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2372. begin
  2373. inherited Unmap(aData, aPixel, aMapData);
  2374. aPixel.Data.a := PWord(aData)^;
  2375. inc(aData, 2);
  2376. end;
  2377. constructor TfdRGBA_US4.Create;
  2378. begin
  2379. inherited Create;
  2380. fPixelSize := 8.0;
  2381. fRange.a := $FFFF;
  2382. fShift.a := 48;
  2383. fglFormat := GL_RGBA;
  2384. fglDataFormat := GL_UNSIGNED_SHORT;
  2385. end;
  2386. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2387. //TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2388. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2389. procedure TfdBGRA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2390. begin
  2391. inherited Map(aPixel, aData, aMapData);
  2392. PWord(aData)^ := aPixel.Data.a;
  2393. inc(aData, 2);
  2394. end;
  2395. procedure TfdBGRA_US4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2396. begin
  2397. inherited Unmap(aData, aPixel, aMapData);
  2398. aPixel.Data.a := PWord(aData)^;
  2399. inc(aData, 2);
  2400. end;
  2401. constructor TfdBGRA_US4.Create;
  2402. begin
  2403. inherited Create;
  2404. fPixelSize := 8.0;
  2405. fRange.a := $FFFF;
  2406. fShift.a := 48;
  2407. fglFormat := GL_BGRA;
  2408. fglDataFormat := GL_UNSIGNED_SHORT;
  2409. end;
  2410. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2411. //TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2412. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2413. procedure TfdUniversal_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2414. var
  2415. i: Integer;
  2416. begin
  2417. PCardinal(aData)^ := 0;
  2418. for i := 0 to 3 do
  2419. if (fRange.arr[i] > 0) then
  2420. PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
  2421. inc(aData, 4);
  2422. end;
  2423. procedure TfdUniversal_UI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2424. var
  2425. i: Integer;
  2426. begin
  2427. for i := 0 to 3 do
  2428. aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and fRange.arr[i];
  2429. inc(aData, 2);
  2430. end;
  2431. constructor TfdUniversal_UI1.Create;
  2432. begin
  2433. inherited Create;
  2434. fPixelSize := 4.0;
  2435. end;
  2436. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2437. //TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2438. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2439. procedure TfdDepth_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  2440. begin
  2441. PCardinal(aData)^ := DepthWeight(aPixel);
  2442. inc(aData, 4);
  2443. end;
  2444. procedure TfdDepth_UI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  2445. begin
  2446. aPixel.Data.r := PCardinal(aData)^;
  2447. aPixel.Data.g := PCardinal(aData)^;
  2448. aPixel.Data.b := PCardinal(aData)^;
  2449. aPixel.Data.a := 0;
  2450. inc(aData, 4);
  2451. end;
  2452. constructor TfdDepth_UI1.Create;
  2453. begin
  2454. inherited Create;
  2455. fPixelSize := 4.0;
  2456. fRange.r := $FFFFFFFF;
  2457. fRange.g := $FFFFFFFF;
  2458. fRange.b := $FFFFFFFF;
  2459. fglFormat := GL_DEPTH_COMPONENT;
  2460. fglDataFormat := GL_UNSIGNED_INT;
  2461. end;
  2462. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2463. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2464. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2465. constructor TfdAlpha4.Create;
  2466. begin
  2467. inherited Create;
  2468. fFormat := tfAlpha4;
  2469. fWithAlpha := tfAlpha4;
  2470. fglInternalFormat := GL_ALPHA4;
  2471. end;
  2472. constructor TfdAlpha8.Create;
  2473. begin
  2474. inherited Create;
  2475. fFormat := tfAlpha8;
  2476. fWithAlpha := tfAlpha8;
  2477. fglInternalFormat := GL_ALPHA8;
  2478. end;
  2479. constructor TfdAlpha12.Create;
  2480. begin
  2481. inherited Create;
  2482. fFormat := tfAlpha12;
  2483. fWithAlpha := tfAlpha12;
  2484. fglInternalFormat := GL_ALPHA12;
  2485. end;
  2486. constructor TfdAlpha16.Create;
  2487. begin
  2488. inherited Create;
  2489. fFormat := tfAlpha16;
  2490. fWithAlpha := tfAlpha16;
  2491. fglInternalFormat := GL_ALPHA16;
  2492. end;
  2493. constructor TfdLuminance4.Create;
  2494. begin
  2495. inherited Create;
  2496. fFormat := tfLuminance4;
  2497. fWithAlpha := tfLuminance4Alpha4;
  2498. fWithoutAlpha := tfLuminance4;
  2499. fglInternalFormat := GL_LUMINANCE4;
  2500. end;
  2501. constructor TfdLuminance8.Create;
  2502. begin
  2503. inherited Create;
  2504. fFormat := tfLuminance8;
  2505. fWithAlpha := tfLuminance8Alpha8;
  2506. fWithoutAlpha := tfLuminance8;
  2507. fglInternalFormat := GL_LUMINANCE8;
  2508. end;
  2509. constructor TfdLuminance12.Create;
  2510. begin
  2511. inherited Create;
  2512. fFormat := tfLuminance12;
  2513. fWithAlpha := tfLuminance12Alpha12;
  2514. fWithoutAlpha := tfLuminance12;
  2515. fglInternalFormat := GL_LUMINANCE12;
  2516. end;
  2517. constructor TfdLuminance16.Create;
  2518. begin
  2519. inherited Create;
  2520. fFormat := tfLuminance16;
  2521. fWithAlpha := tfLuminance16Alpha16;
  2522. fWithoutAlpha := tfLuminance16;
  2523. fglInternalFormat := GL_LUMINANCE16;
  2524. end;
  2525. constructor TfdLuminance4Alpha4.Create;
  2526. begin
  2527. inherited Create;
  2528. fFormat := tfLuminance4Alpha4;
  2529. fWithAlpha := tfLuminance4Alpha4;
  2530. fWithoutAlpha := tfLuminance4;
  2531. fglInternalFormat := GL_LUMINANCE4_ALPHA4;
  2532. end;
  2533. constructor TfdLuminance6Alpha2.Create;
  2534. begin
  2535. inherited Create;
  2536. fFormat := tfLuminance6Alpha2;
  2537. fWithAlpha := tfLuminance6Alpha2;
  2538. fWithoutAlpha := tfLuminance8;
  2539. fglInternalFormat := GL_LUMINANCE6_ALPHA2;
  2540. end;
  2541. constructor TfdLuminance8Alpha8.Create;
  2542. begin
  2543. inherited Create;
  2544. fFormat := tfLuminance8Alpha8;
  2545. fWithAlpha := tfLuminance8Alpha8;
  2546. fWithoutAlpha := tfLuminance8;
  2547. fglInternalFormat := GL_LUMINANCE8_ALPHA8;
  2548. end;
  2549. constructor TfdLuminance12Alpha4.Create;
  2550. begin
  2551. inherited Create;
  2552. fFormat := tfLuminance12Alpha4;
  2553. fWithAlpha := tfLuminance12Alpha4;
  2554. fWithoutAlpha := tfLuminance12;
  2555. fglInternalFormat := GL_LUMINANCE12_ALPHA4;
  2556. end;
  2557. constructor TfdLuminance12Alpha12.Create;
  2558. begin
  2559. inherited Create;
  2560. fFormat := tfLuminance12Alpha12;
  2561. fWithAlpha := tfLuminance12Alpha12;
  2562. fWithoutAlpha := tfLuminance12;
  2563. fglInternalFormat := GL_LUMINANCE12_ALPHA12;
  2564. end;
  2565. constructor TfdLuminance16Alpha16.Create;
  2566. begin
  2567. inherited Create;
  2568. fFormat := tfLuminance16Alpha16;
  2569. fWithAlpha := tfLuminance16Alpha16;
  2570. fWithoutAlpha := tfLuminance16;
  2571. fglInternalFormat := GL_LUMINANCE16_ALPHA16;
  2572. end;
  2573. constructor TfdR3G3B2.Create;
  2574. begin
  2575. inherited Create;
  2576. fFormat := tfR3G3B2;
  2577. fWithAlpha := tfRGBA2;
  2578. fWithoutAlpha := tfR3G3B2;
  2579. fRange.r := $7;
  2580. fRange.g := $7;
  2581. fRange.b := $3;
  2582. fShift.r := 0;
  2583. fShift.g := 3;
  2584. fShift.b := 6;
  2585. fglFormat := GL_RGB;
  2586. fglInternalFormat := GL_R3_G3_B2;
  2587. fglDataFormat := GL_UNSIGNED_BYTE_2_3_3_REV;
  2588. end;
  2589. constructor TfdRGB4.Create;
  2590. begin
  2591. inherited Create;
  2592. fFormat := tfRGB4;
  2593. fWithAlpha := tfRGBA4;
  2594. fWithoutAlpha := tfRGB4;
  2595. fRGBInverted := tfBGR4;
  2596. fRange.r := $F;
  2597. fRange.g := $F;
  2598. fRange.b := $F;
  2599. fShift.r := 0;
  2600. fShift.g := 4;
  2601. fShift.b := 8;
  2602. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2603. fglInternalFormat := GL_RGB4;
  2604. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
  2605. end;
  2606. constructor TfdR5G6B5.Create;
  2607. begin
  2608. inherited Create;
  2609. fFormat := tfR5G6B5;
  2610. fWithAlpha := tfRGBA4;
  2611. fWithoutAlpha := tfR5G6B5;
  2612. fRGBInverted := tfB5G6R5;
  2613. fRange.r := $1F;
  2614. fRange.g := $3F;
  2615. fRange.b := $1F;
  2616. fShift.r := 0;
  2617. fShift.g := 5;
  2618. fShift.b := 11;
  2619. fglFormat := GL_RGB;
  2620. fglInternalFormat := GL_RGB565;
  2621. fglDataFormat := GL_UNSIGNED_SHORT_5_6_5_REV;
  2622. end;
  2623. constructor TfdRGB5.Create;
  2624. begin
  2625. inherited Create;
  2626. fFormat := tfRGB5;
  2627. fWithAlpha := tfRGB5A1;
  2628. fWithoutAlpha := tfRGB5;
  2629. fRGBInverted := tfBGR5;
  2630. fRange.r := $1F;
  2631. fRange.g := $1F;
  2632. fRange.b := $1F;
  2633. fShift.r := 0;
  2634. fShift.g := 5;
  2635. fShift.b := 10;
  2636. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2637. fglInternalFormat := GL_RGB5;
  2638. fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
  2639. end;
  2640. constructor TfdRGB8.Create;
  2641. begin
  2642. inherited Create;
  2643. fFormat := tfRGB8;
  2644. fWithAlpha := tfRGBA8;
  2645. fWithoutAlpha := tfRGB8;
  2646. fRGBInverted := tfBGR8;
  2647. fglInternalFormat := GL_RGB8;
  2648. end;
  2649. constructor TfdRGB10.Create;
  2650. begin
  2651. inherited Create;
  2652. fFormat := tfRGB10;
  2653. fWithAlpha := tfRGB10A2;
  2654. fWithoutAlpha := tfRGB10;
  2655. fRGBInverted := tfBGR10;
  2656. fRange.r := $3FF;
  2657. fRange.g := $3FF;
  2658. fRange.b := $3FF;
  2659. fShift.r := 0;
  2660. fShift.g := 10;
  2661. fShift.b := 20;
  2662. fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2663. fglInternalFormat := GL_RGB10;
  2664. fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
  2665. end;
  2666. constructor TfdRGB12.Create;
  2667. begin
  2668. inherited Create;
  2669. fFormat := tfRGB12;
  2670. fWithAlpha := tfRGBA12;
  2671. fWithoutAlpha := tfRGB12;
  2672. fRGBInverted := tfBGR12;
  2673. fglInternalFormat := GL_RGB12;
  2674. end;
  2675. constructor TfdRGB16.Create;
  2676. begin
  2677. inherited Create;
  2678. fFormat := tfRGB16;
  2679. fWithAlpha := tfRGBA16;
  2680. fWithoutAlpha := tfRGB16;
  2681. fRGBInverted := tfBGR16;
  2682. fglInternalFormat := GL_RGB16;
  2683. end;
  2684. constructor TfdRGBA2.Create;
  2685. begin
  2686. inherited Create;
  2687. fFormat := tfRGBA2;
  2688. fWithAlpha := tfRGBA2;
  2689. fWithoutAlpha := tfR3G3B2;
  2690. fRGBInverted := tfBGRA2;
  2691. fglInternalFormat := GL_RGBA2;
  2692. end;
  2693. constructor TfdRGBA4.Create;
  2694. begin
  2695. inherited Create;
  2696. fFormat := tfRGBA4;
  2697. fWithAlpha := tfRGBA4;
  2698. fWithoutAlpha := tfRGB4;
  2699. fRGBInverted := tfBGRA4;
  2700. fRange.r := $F;
  2701. fRange.g := $F;
  2702. fRange.b := $F;
  2703. fRange.a := $F;
  2704. fShift.r := 0;
  2705. fShift.g := 4;
  2706. fShift.b := 8;
  2707. fShift.a := 12;
  2708. fglFormat := GL_RGBA;
  2709. fglInternalFormat := GL_RGBA4;
  2710. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
  2711. end;
  2712. constructor TfdRGB5A1.Create;
  2713. begin
  2714. inherited Create;
  2715. fFormat := tfRGB5A1;
  2716. fWithAlpha := tfRGB5A1;
  2717. fWithoutAlpha := tfRGB5;
  2718. fRGBInverted := tfBGR5A1;
  2719. fRange.r := $1F;
  2720. fRange.g := $1F;
  2721. fRange.b := $1F;
  2722. fRange.a := $01;
  2723. fShift.r := 0;
  2724. fShift.g := 5;
  2725. fShift.b := 10;
  2726. fShift.a := 15;
  2727. fglFormat := GL_RGBA;
  2728. fglInternalFormat := GL_RGB5_A1;
  2729. fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
  2730. end;
  2731. constructor TfdRGBA8.Create;
  2732. begin
  2733. inherited Create;
  2734. fFormat := tfRGBA8;
  2735. fWithAlpha := tfRGBA8;
  2736. fWithoutAlpha := tfRGB8;
  2737. fRGBInverted := tfBGRA8;
  2738. fglInternalFormat := GL_RGBA8;
  2739. end;
  2740. constructor TfdRGB10A2.Create;
  2741. begin
  2742. inherited Create;
  2743. fFormat := tfRGB10A2;
  2744. fWithAlpha := tfRGB10A2;
  2745. fWithoutAlpha := tfRGB10;
  2746. fRGBInverted := tfBGR10A2;
  2747. fRange.r := $3FF;
  2748. fRange.g := $3FF;
  2749. fRange.b := $3FF;
  2750. fRange.a := $003;
  2751. fShift.r := 0;
  2752. fShift.g := 10;
  2753. fShift.b := 20;
  2754. fShift.a := 30;
  2755. fglFormat := GL_RGBA;
  2756. fglInternalFormat := GL_RGB10_A2;
  2757. fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
  2758. end;
  2759. constructor TfdRGBA12.Create;
  2760. begin
  2761. inherited Create;
  2762. fFormat := tfRGBA12;
  2763. fWithAlpha := tfRGBA12;
  2764. fWithoutAlpha := tfRGB12;
  2765. fRGBInverted := tfBGRA12;
  2766. fglInternalFormat := GL_RGBA12;
  2767. end;
  2768. constructor TfdRGBA16.Create;
  2769. begin
  2770. inherited Create;
  2771. fFormat := tfRGBA16;
  2772. fWithAlpha := tfRGBA16;
  2773. fWithoutAlpha := tfRGB16;
  2774. fRGBInverted := tfBGRA16;
  2775. fglInternalFormat := GL_RGBA16;
  2776. end;
  2777. constructor TfdBGR4.Create;
  2778. begin
  2779. inherited Create;
  2780. fPixelSize := 2.0;
  2781. fFormat := tfBGR4;
  2782. fWithAlpha := tfBGRA4;
  2783. fWithoutAlpha := tfBGR4;
  2784. fRGBInverted := tfRGB4;
  2785. fRange.r := $F;
  2786. fRange.g := $F;
  2787. fRange.b := $F;
  2788. fRange.a := $0;
  2789. fShift.r := 8;
  2790. fShift.g := 4;
  2791. fShift.b := 0;
  2792. fShift.a := 0;
  2793. fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2794. fglInternalFormat := GL_RGB4;
  2795. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
  2796. end;
  2797. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2798. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2799. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2800. constructor TfdB5G6R5.Create;
  2801. begin
  2802. inherited Create;
  2803. fFormat := tfB5G6R5;
  2804. fWithAlpha := tfBGRA4;
  2805. fWithoutAlpha := tfB5G6R5;
  2806. fRGBInverted := tfR5G6B5;
  2807. fRange.r := $1F;
  2808. fRange.g := $3F;
  2809. fRange.b := $1F;
  2810. fShift.r := 11;
  2811. fShift.g := 5;
  2812. fShift.b := 0;
  2813. fglFormat := GL_RGB; //B5G6R5 is only possible as R5G6B5 -> use reverted dataformat
  2814. fglInternalFormat := GL_RGB8;
  2815. fglDataFormat := GL_UNSIGNED_SHORT_5_6_5;
  2816. end;
  2817. constructor TfdBGR5.Create;
  2818. begin
  2819. inherited Create;
  2820. fPixelSize := 2.0;
  2821. fFormat := tfBGR5;
  2822. fWithAlpha := tfBGR5A1;
  2823. fWithoutAlpha := tfBGR5;
  2824. fRGBInverted := tfRGB5;
  2825. fRange.r := $1F;
  2826. fRange.g := $1F;
  2827. fRange.b := $1F;
  2828. fRange.a := $00;
  2829. fShift.r := 10;
  2830. fShift.g := 5;
  2831. fShift.b := 0;
  2832. fShift.a := 0;
  2833. fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2834. fglInternalFormat := GL_RGB5;
  2835. fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
  2836. end;
  2837. constructor TfdBGR8.Create;
  2838. begin
  2839. inherited Create;
  2840. fFormat := tfBGR8;
  2841. fWithAlpha := tfBGRA8;
  2842. fWithoutAlpha := tfBGR8;
  2843. fRGBInverted := tfRGB8;
  2844. fglInternalFormat := GL_RGB8;
  2845. end;
  2846. constructor TfdBGR10.Create;
  2847. begin
  2848. inherited Create;
  2849. fFormat := tfBGR10;
  2850. fWithAlpha := tfBGR10A2;
  2851. fWithoutAlpha := tfBGR10;
  2852. fRGBInverted := tfRGB10;
  2853. fRange.r := $3FF;
  2854. fRange.g := $3FF;
  2855. fRange.b := $3FF;
  2856. fRange.a := $000;
  2857. fShift.r := 20;
  2858. fShift.g := 10;
  2859. fShift.b := 0;
  2860. fShift.a := 0;
  2861. fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
  2862. fglInternalFormat := GL_RGB10;
  2863. fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
  2864. end;
  2865. constructor TfdBGR12.Create;
  2866. begin
  2867. inherited Create;
  2868. fFormat := tfBGR12;
  2869. fWithAlpha := tfBGRA12;
  2870. fWithoutAlpha := tfBGR12;
  2871. fRGBInverted := tfRGB12;
  2872. fglInternalFormat := GL_RGB12;
  2873. end;
  2874. constructor TfdBGR16.Create;
  2875. begin
  2876. inherited Create;
  2877. fFormat := tfBGR16;
  2878. fWithAlpha := tfBGRA16;
  2879. fWithoutAlpha := tfBGR16;
  2880. fRGBInverted := tfRGB16;
  2881. fglInternalFormat := GL_RGB16;
  2882. end;
  2883. constructor TfdBGRA2.Create;
  2884. begin
  2885. inherited Create;
  2886. fFormat := tfBGRA2;
  2887. fWithAlpha := tfBGRA4;
  2888. fWithoutAlpha := tfBGR4;
  2889. fRGBInverted := tfRGBA2;
  2890. fglInternalFormat := GL_RGBA2;
  2891. end;
  2892. constructor TfdBGRA4.Create;
  2893. begin
  2894. inherited Create;
  2895. fFormat := tfBGRA4;
  2896. fWithAlpha := tfBGRA4;
  2897. fWithoutAlpha := tfBGR4;
  2898. fRGBInverted := tfRGBA4;
  2899. fRange.r := $F;
  2900. fRange.g := $F;
  2901. fRange.b := $F;
  2902. fRange.a := $F;
  2903. fShift.r := 8;
  2904. fShift.g := 4;
  2905. fShift.b := 0;
  2906. fShift.a := 12;
  2907. fglFormat := GL_BGRA;
  2908. fglInternalFormat := GL_RGBA4;
  2909. fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
  2910. end;
  2911. constructor TfdBGR5A1.Create;
  2912. begin
  2913. inherited Create;
  2914. fFormat := tfBGR5A1;
  2915. fWithAlpha := tfBGR5A1;
  2916. fWithoutAlpha := tfBGR5;
  2917. fRGBInverted := tfRGB5A1;
  2918. fRange.r := $1F;
  2919. fRange.g := $1F;
  2920. fRange.b := $1F;
  2921. fRange.a := $01;
  2922. fShift.r := 10;
  2923. fShift.g := 5;
  2924. fShift.b := 0;
  2925. fShift.a := 15;
  2926. fglFormat := GL_BGRA;
  2927. fglInternalFormat := GL_RGB5_A1;
  2928. fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
  2929. end;
  2930. constructor TfdBGRA8.Create;
  2931. begin
  2932. inherited Create;
  2933. fFormat := tfBGRA8;
  2934. fWithAlpha := tfBGRA8;
  2935. fWithoutAlpha := tfBGR8;
  2936. fRGBInverted := tfRGBA8;
  2937. fglInternalFormat := GL_RGBA8;
  2938. end;
  2939. constructor TfdBGR10A2.Create;
  2940. begin
  2941. inherited Create;
  2942. fFormat := tfBGR10A2;
  2943. fWithAlpha := tfBGR10A2;
  2944. fWithoutAlpha := tfBGR10;
  2945. fRGBInverted := tfRGB10A2;
  2946. fRange.r := $3FF;
  2947. fRange.g := $3FF;
  2948. fRange.b := $3FF;
  2949. fRange.a := $003;
  2950. fShift.r := 20;
  2951. fShift.g := 10;
  2952. fShift.b := 0;
  2953. fShift.a := 30;
  2954. fglFormat := GL_BGRA;
  2955. fglInternalFormat := GL_RGB10_A2;
  2956. fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
  2957. end;
  2958. constructor TfdBGRA12.Create;
  2959. begin
  2960. inherited Create;
  2961. fFormat := tfBGRA12;
  2962. fWithAlpha := tfBGRA12;
  2963. fWithoutAlpha := tfBGR12;
  2964. fRGBInverted := tfRGBA12;
  2965. fglInternalFormat := GL_RGBA12;
  2966. end;
  2967. constructor TfdBGRA16.Create;
  2968. begin
  2969. inherited Create;
  2970. fFormat := tfBGRA16;
  2971. fWithAlpha := tfBGRA16;
  2972. fWithoutAlpha := tfBGR16;
  2973. fRGBInverted := tfRGBA16;
  2974. fglInternalFormat := GL_RGBA16;
  2975. end;
  2976. constructor TfdDepth16.Create;
  2977. begin
  2978. inherited Create;
  2979. fFormat := tfDepth16;
  2980. fWithAlpha := tfEmpty;
  2981. fWithoutAlpha := tfDepth16;
  2982. fglInternalFormat := GL_DEPTH_COMPONENT16;
  2983. end;
  2984. constructor TfdDepth24.Create;
  2985. begin
  2986. inherited Create;
  2987. fFormat := tfDepth24;
  2988. fWithAlpha := tfEmpty;
  2989. fWithoutAlpha := tfDepth24;
  2990. fglInternalFormat := GL_DEPTH_COMPONENT24;
  2991. end;
  2992. constructor TfdDepth32.Create;
  2993. begin
  2994. inherited Create;
  2995. fFormat := tfDepth32;
  2996. fWithAlpha := tfEmpty;
  2997. fWithoutAlpha := tfDepth32;
  2998. fglInternalFormat := GL_DEPTH_COMPONENT32;
  2999. end;
  3000. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3001. //TfdS3tcDtx1RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3002. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3003. procedure TfdS3tcDtx1RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  3004. begin
  3005. raise EglBitmapException.Create('mapping for compressed formats is not supported');
  3006. end;
  3007. procedure TfdS3tcDtx1RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  3008. begin
  3009. raise EglBitmapException.Create('mapping for compressed formats is not supported');
  3010. end;
  3011. constructor TfdS3tcDtx1RGBA.Create;
  3012. begin
  3013. inherited Create;
  3014. fFormat := tfS3tcDtx1RGBA;
  3015. fWithAlpha := tfS3tcDtx1RGBA;
  3016. fUncompressed := tfRGB5A1;
  3017. fPixelSize := 0.5;
  3018. fIsCompressed := true;
  3019. fglFormat := GL_COMPRESSED_RGBA;
  3020. fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
  3021. fglDataFormat := GL_UNSIGNED_BYTE;
  3022. end;
  3023. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3024. //TfdS3tcDtx3RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3025. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3026. procedure TfdS3tcDtx3RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  3027. begin
  3028. raise EglBitmapException.Create('mapping for compressed formats is not supported');
  3029. end;
  3030. procedure TfdS3tcDtx3RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  3031. begin
  3032. raise EglBitmapException.Create('mapping for compressed formats is not supported');
  3033. end;
  3034. constructor TfdS3tcDtx3RGBA.Create;
  3035. begin
  3036. inherited Create;
  3037. fFormat := tfS3tcDtx3RGBA;
  3038. fWithAlpha := tfS3tcDtx3RGBA;
  3039. fUncompressed := tfRGBA8;
  3040. fPixelSize := 1.0;
  3041. fIsCompressed := true;
  3042. fglFormat := GL_COMPRESSED_RGBA;
  3043. fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
  3044. fglDataFormat := GL_UNSIGNED_BYTE;
  3045. end;
  3046. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3047. //TfdS3tcDtx5RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3048. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3049. procedure TfdS3tcDtx5RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  3050. begin
  3051. raise EglBitmapException.Create('mapping for compressed formats is not supported');
  3052. end;
  3053. procedure TfdS3tcDtx5RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  3054. begin
  3055. raise EglBitmapException.Create('mapping for compressed formats is not supported');
  3056. end;
  3057. constructor TfdS3tcDtx5RGBA.Create;
  3058. begin
  3059. inherited Create;
  3060. fFormat := tfS3tcDtx3RGBA;
  3061. fWithAlpha := tfS3tcDtx3RGBA;
  3062. fUncompressed := tfRGBA8;
  3063. fPixelSize := 1.0;
  3064. fIsCompressed := true;
  3065. fglFormat := GL_COMPRESSED_RGBA;
  3066. fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  3067. fglDataFormat := GL_UNSIGNED_BYTE;
  3068. end;
  3069. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3070. //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3071. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3072. class procedure TFormatDescriptor.Init;
  3073. begin
  3074. if not Assigned(FormatDescriptorCS) then
  3075. FormatDescriptorCS := TCriticalSection.Create;
  3076. end;
  3077. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3078. class function TFormatDescriptor.Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
  3079. begin
  3080. FormatDescriptorCS.Enter;
  3081. try
  3082. result := FormatDescriptors[aFormat];
  3083. if not Assigned(result) then begin
  3084. result := FORMAT_DESCRIPTOR_CLASSES[aFormat].Create;
  3085. FormatDescriptors[aFormat] := result;
  3086. end;
  3087. finally
  3088. FormatDescriptorCS.Leave;
  3089. end;
  3090. end;
  3091. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3092. class function TFormatDescriptor.GetWithAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
  3093. begin
  3094. result := Get(Get(aFormat).WithAlpha);
  3095. end;
  3096. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3097. class procedure TFormatDescriptor.Clear;
  3098. var
  3099. f: TglBitmapFormat;
  3100. begin
  3101. FormatDescriptorCS.Enter;
  3102. try
  3103. for f := low(FormatDescriptors) to high(FormatDescriptors) do
  3104. FreeAndNil(FormatDescriptors[f]);
  3105. finally
  3106. FormatDescriptorCS.Leave;
  3107. end;
  3108. end;
  3109. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3110. class procedure TFormatDescriptor.Finalize;
  3111. begin
  3112. Clear;
  3113. FreeAndNil(FormatDescriptorCS);
  3114. end;
  3115. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3116. //TBitfieldFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3117. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3118. procedure TbmpBitfieldFormat.SetRedMask(const aValue: QWord);
  3119. begin
  3120. Update(aValue, fRange.r, fShift.r);
  3121. end;
  3122. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3123. procedure TbmpBitfieldFormat.SetGreenMask(const aValue: QWord);
  3124. begin
  3125. Update(aValue, fRange.g, fShift.g);
  3126. end;
  3127. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3128. procedure TbmpBitfieldFormat.SetBlueMask(const aValue: QWord);
  3129. begin
  3130. Update(aValue, fRange.b, fShift.b);
  3131. end;
  3132. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3133. procedure TbmpBitfieldFormat.SetAlphaMask(const aValue: QWord);
  3134. begin
  3135. Update(aValue, fRange.a, fShift.a);
  3136. end;
  3137. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3138. procedure TbmpBitfieldFormat.Update(aMask: QWord; out aRange: Cardinal; out
  3139. aShift: Byte);
  3140. begin
  3141. aShift := 0;
  3142. aRange := 0;
  3143. if (aMask = 0) then
  3144. exit;
  3145. while (aMask > 0) and ((aMask and 1) = 0) do begin
  3146. inc(aShift);
  3147. aMask := aMask shr 1;
  3148. end;
  3149. aRange := 1;
  3150. while (aMask > 0) do begin
  3151. aRange := aRange shl 1;
  3152. aMask := aMask shr 1;
  3153. end;
  3154. dec(aRange);
  3155. fPixelSize := Round(GetTopMostBit(RedMask or GreenMask or BlueMask or AlphaMask) / 8);
  3156. end;
  3157. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3158. procedure TbmpBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  3159. var
  3160. data: QWord;
  3161. s: Integer;
  3162. begin
  3163. data :=
  3164. ((aPixel.Data.r and fRange.r) shl fShift.r) or
  3165. ((aPixel.Data.g and fRange.g) shl fShift.g) or
  3166. ((aPixel.Data.b and fRange.b) shl fShift.b) or
  3167. ((aPixel.Data.a and fRange.a) shl fShift.a);
  3168. s := Round(fPixelSize);
  3169. case s of
  3170. 1: aData^ := data;
  3171. 2: PWord(aData)^ := data;
  3172. 4: PCardinal(aData)^ := data;
  3173. 8: PQWord(aData)^ := data;
  3174. else
  3175. raise EglBitmapException.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
  3176. end;
  3177. inc(aData, s);
  3178. end;
  3179. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3180. procedure TbmpBitfieldFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  3181. var
  3182. data: QWord;
  3183. s, i: Integer;
  3184. begin
  3185. s := Round(fPixelSize);
  3186. case s of
  3187. 1: data := aData^;
  3188. 2: data := PWord(aData)^;
  3189. 4: data := PCardinal(aData)^;
  3190. 8: data := PQWord(aData)^;
  3191. else
  3192. raise EglBitmapException.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
  3193. end;
  3194. for i := 0 to 3 do
  3195. aPixel.Data.arr[i] := (data shr fShift.arr[i]) and fRange.arr[i];
  3196. inc(aData, s);
  3197. end;
  3198. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3199. //TColorTableFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3200. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3201. procedure TbmpColorTableFormat.CreateColorTable;
  3202. var
  3203. i: Integer;
  3204. begin
  3205. if not (Format in [tfLuminance4, tfLuminance8, tfR3G3B2]) then
  3206. raise EglBitmapException.Create(UNSUPPORTED_FORMAT);
  3207. if (Format = tfLuminance4) then
  3208. SetLength(fColorTable, 16)
  3209. else
  3210. SetLength(fColorTable, 256);
  3211. case Format of
  3212. tfLuminance4: begin
  3213. for i := 0 to High(fColorTable) do begin
  3214. fColorTable[i].r := 16 * i;
  3215. fColorTable[i].g := 16 * i;
  3216. fColorTable[i].b := 16 * i;
  3217. fColorTable[i].a := 0;
  3218. end;
  3219. end;
  3220. tfLuminance8: begin
  3221. for i := 0 to High(fColorTable) do begin
  3222. fColorTable[i].r := i;
  3223. fColorTable[i].g := i;
  3224. fColorTable[i].b := i;
  3225. fColorTable[i].a := 0;
  3226. end;
  3227. end;
  3228. tfR3G3B2: begin
  3229. for i := 0 to High(fColorTable) do begin
  3230. fColorTable[i].r := Round(((i shr Shift.r) and Range.r) / Range.r * 255);
  3231. fColorTable[i].g := Round(((i shr Shift.g) and Range.g) / Range.g * 255);
  3232. fColorTable[i].b := Round(((i shr Shift.b) and Range.b) / Range.b * 255);
  3233. fColorTable[i].a := 0;
  3234. end;
  3235. end;
  3236. end;
  3237. end;
  3238. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3239. procedure TbmpColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
  3240. var
  3241. d: Byte;
  3242. begin
  3243. if not (Format in [tfLuminance4, tfLuminance8, tfR3G3B2]) then
  3244. raise EglBitmapException.Create(UNSUPPORTED_FORMAT);
  3245. case Format of
  3246. tfLuminance4: begin
  3247. if (aMapData = nil) then
  3248. aData^ := 0;
  3249. d := LuminanceWeight(aPixel) and Range.r;
  3250. aData^ := aData^ or (d shl (4 - {%H-}PtrUInt(aMapData)));
  3251. inc(PByte(aMapData), 4);
  3252. if ({%H-}PtrUInt(aMapData) >= 8) then begin
  3253. inc(aData);
  3254. aMapData := nil;
  3255. end;
  3256. end;
  3257. tfLuminance8: begin
  3258. aData^ := LuminanceWeight(aPixel) and Range.r;
  3259. inc(aData);
  3260. end;
  3261. tfR3G3B2: begin
  3262. aData^ := Round(
  3263. ((aPixel.Data.r and Range.r) shl Shift.r) or
  3264. ((aPixel.Data.g and Range.g) shl Shift.g) or
  3265. ((aPixel.Data.b and Range.b) shl Shift.b));
  3266. inc(aData);
  3267. end;
  3268. end;
  3269. end;
  3270. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3271. procedure TbmpColorTableFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
  3272. var
  3273. idx: QWord;
  3274. s: Integer;
  3275. bits: Byte;
  3276. f: Single;
  3277. begin
  3278. s := Trunc(fPixelSize);
  3279. f := fPixelSize - s;
  3280. bits := Round(8 * f);
  3281. case s of
  3282. 0: idx := (aData^ shr (8 - bits - {%H-}PtrInt(aMapData))) and ((1 shl bits) - 1);
  3283. 1: idx := aData^;
  3284. 2: idx := PWord(aData)^;
  3285. 4: idx := PCardinal(aData)^;
  3286. 8: idx := PQWord(aData)^;
  3287. else
  3288. raise EglBitmapException.CreateFmt('invalid pixel size: %.3f', [fPixelSize]);
  3289. end;
  3290. if (idx >= Length(fColorTable)) then
  3291. raise EglBitmapException.CreateFmt('invalid color index: %d', [idx]);
  3292. with fColorTable[idx] do begin
  3293. aPixel.Data.r := r;
  3294. aPixel.Data.g := g;
  3295. aPixel.Data.b := b;
  3296. aPixel.Data.a := a;
  3297. end;
  3298. inc(PByte(aMapData), bits);
  3299. if ({%H-}PtrUInt(aMapData) >= 8) then begin
  3300. inc(aData, 1);
  3301. dec(PByte(aMapData), 8);
  3302. end;
  3303. inc(aData, s);
  3304. end;
  3305. destructor TbmpColorTableFormat.Destroy;
  3306. begin
  3307. SetLength(fColorTable, 0);
  3308. inherited Destroy;
  3309. end;
  3310. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3311. //TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3312. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3313. procedure glBitmapConvertPixel(var aPixel: TglBitmapPixelData; const aSourceFD, aDestFD: TFormatDescriptor);
  3314. var
  3315. i: Integer;
  3316. begin
  3317. for i := 0 to 3 do begin
  3318. if (aSourceFD.Range.arr[i] <> aDestFD.Range.arr[i]) then begin
  3319. if (aSourceFD.Range.arr[i] > 0) then
  3320. aPixel.Data.arr[i] := Round(aPixel.Data.arr[i] / aSourceFD.Range.arr[i] * aDestFD.Range.arr[i])
  3321. else
  3322. aPixel.Data.arr[i] := aDestFD.Range.arr[i];
  3323. end;
  3324. end;
  3325. end;
  3326. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3327. procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
  3328. begin
  3329. with aFuncRec do begin
  3330. if (Source.Range.r > 0) then
  3331. Dest.Data.r := Source.Data.r;
  3332. if (Source.Range.g > 0) then
  3333. Dest.Data.g := Source.Data.g;
  3334. if (Source.Range.b > 0) then
  3335. Dest.Data.b := Source.Data.b;
  3336. if (Source.Range.a > 0) then
  3337. Dest.Data.a := Source.Data.a;
  3338. end;
  3339. end;
  3340. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3341. procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
  3342. var
  3343. i: Integer;
  3344. begin
  3345. with aFuncRec do begin
  3346. for i := 0 to 3 do
  3347. if (Source.Range.arr[i] > 0) then
  3348. Dest.Data.arr[i] := Round(Dest.Range.arr[i] * Source.Data.arr[i] / Source.Range.arr[i]);
  3349. end;
  3350. end;
  3351. type
  3352. TShiftData = packed record
  3353. case Integer of
  3354. 0: (r, g, b, a: SmallInt);
  3355. 1: (arr: array[0..3] of SmallInt);
  3356. end;
  3357. PShiftData = ^TShiftData;
  3358. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3359. procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
  3360. var
  3361. i: Integer;
  3362. begin
  3363. with aFuncRec do
  3364. for i := 0 to 3 do
  3365. if (Source.Range.arr[i] > 0) then
  3366. Dest.Data.arr[i] := Source.Data.arr[i] shr PShiftData(Args)^.arr[i];
  3367. end;
  3368. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3369. procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
  3370. begin
  3371. with aFuncRec do begin
  3372. Dest.Data := Source.Data;
  3373. if ({%H-}PtrUInt(Args) and $1 > 0) then begin
  3374. Dest.Data.r := Dest.Data.r xor Dest.Range.r;
  3375. Dest.Data.g := Dest.Data.g xor Dest.Range.g;
  3376. Dest.Data.b := Dest.Data.b xor Dest.Range.b;
  3377. end;
  3378. if ({%H-}PtrUInt(Args) and $2 > 0) then begin
  3379. Dest.Data.a := Dest.Data.a xor Dest.Range.a;
  3380. end;
  3381. end;
  3382. end;
  3383. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3384. procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
  3385. var
  3386. i: Integer;
  3387. begin
  3388. with aFuncRec do begin
  3389. for i := 0 to 3 do
  3390. Dest.Data.arr[i] := PglBitmapPixelData(Args)^.Data.arr[i];
  3391. end;
  3392. end;
  3393. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3394. procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
  3395. var
  3396. Temp: Single;
  3397. begin
  3398. with FuncRec do begin
  3399. if (FuncRec.Args = nil) then begin //source has no alpha
  3400. Temp :=
  3401. Source.Data.r / Source.Range.r * ALPHA_WEIGHT_R +
  3402. Source.Data.g / Source.Range.g * ALPHA_WEIGHT_G +
  3403. Source.Data.b / Source.Range.b * ALPHA_WEIGHT_B;
  3404. Dest.Data.a := Round(Dest.Range.a * Temp);
  3405. end else
  3406. Dest.Data.a := Round(Source.Data.a / Source.Range.a * Dest.Range.a);
  3407. end;
  3408. end;
  3409. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3410. procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
  3411. type
  3412. PglBitmapPixelData = ^TglBitmapPixelData;
  3413. begin
  3414. with FuncRec do begin
  3415. Dest.Data.r := Source.Data.r;
  3416. Dest.Data.g := Source.Data.g;
  3417. Dest.Data.b := Source.Data.b;
  3418. with PglBitmapPixelData(Args)^ do
  3419. if ((Dest.Data.r <= Data.r) and (Dest.Data.r >= Range.r) and
  3420. (Dest.Data.g <= Data.g) and (Dest.Data.g >= Range.g) and
  3421. (Dest.Data.b <= Data.b) and (Dest.Data.b >= Range.b)) then
  3422. Dest.Data.a := 0
  3423. else
  3424. Dest.Data.a := Dest.Range.a;
  3425. end;
  3426. end;
  3427. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3428. procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
  3429. begin
  3430. with FuncRec do begin
  3431. Dest.Data.r := Source.Data.r;
  3432. Dest.Data.g := Source.Data.g;
  3433. Dest.Data.b := Source.Data.b;
  3434. Dest.Data.a := PCardinal(Args)^;
  3435. end;
  3436. end;
  3437. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3438. procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
  3439. type
  3440. PRGBPix = ^TRGBPix;
  3441. TRGBPix = array [0..2] of byte;
  3442. var
  3443. Temp: Byte;
  3444. begin
  3445. while aWidth > 0 do begin
  3446. Temp := PRGBPix(aData)^[0];
  3447. PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
  3448. PRGBPix(aData)^[2] := Temp;
  3449. if aHasAlpha then
  3450. Inc(aData, 4)
  3451. else
  3452. Inc(aData, 3);
  3453. dec(aWidth);
  3454. end;
  3455. end;
  3456. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3457. //TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3458. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3459. function TglBitmap.GetWidth: Integer;
  3460. begin
  3461. if (ffX in fDimension.Fields) then
  3462. result := fDimension.X
  3463. else
  3464. result := -1;
  3465. end;
  3466. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3467. function TglBitmap.GetHeight: Integer;
  3468. begin
  3469. if (ffY in fDimension.Fields) then
  3470. result := fDimension.Y
  3471. else
  3472. result := -1;
  3473. end;
  3474. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3475. function TglBitmap.GetFileWidth: Integer;
  3476. begin
  3477. result := Max(1, Width);
  3478. end;
  3479. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3480. function TglBitmap.GetFileHeight: Integer;
  3481. begin
  3482. result := Max(1, Height);
  3483. end;
  3484. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3485. procedure TglBitmap.SetCustomData(const aValue: Pointer);
  3486. begin
  3487. if fCustomData = aValue then
  3488. exit;
  3489. fCustomData := aValue;
  3490. end;
  3491. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3492. procedure TglBitmap.SetCustomName(const aValue: String);
  3493. begin
  3494. if fCustomName = aValue then
  3495. exit;
  3496. fCustomName := aValue;
  3497. end;
  3498. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3499. procedure TglBitmap.SetCustomNameW(const aValue: WideString);
  3500. begin
  3501. if fCustomNameW = aValue then
  3502. exit;
  3503. fCustomNameW := aValue;
  3504. end;
  3505. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3506. procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
  3507. begin
  3508. if fDeleteTextureOnFree = aValue then
  3509. exit;
  3510. fDeleteTextureOnFree := aValue;
  3511. end;
  3512. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3513. procedure TglBitmap.SetFormat(const aValue: TglBitmapFormat);
  3514. begin
  3515. if fFormat = aValue then
  3516. exit;
  3517. if TFormatDescriptor.Get(Format).PixelSize <> TFormatDescriptor.Get(aValue).PixelSize then
  3518. raise EglBitmapUnsupportedFormat.Create(Format);
  3519. SetDataPointer(Data, aValue, Width, Height);
  3520. end;
  3521. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3522. procedure TglBitmap.SetFreeDataAfterGenTexture(const aValue: Boolean);
  3523. begin
  3524. if fFreeDataAfterGenTexture = aValue then
  3525. exit;
  3526. fFreeDataAfterGenTexture := aValue;
  3527. end;
  3528. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3529. procedure TglBitmap.SetID(const aValue: Cardinal);
  3530. begin
  3531. if fID = aValue then
  3532. exit;
  3533. fID := aValue;
  3534. end;
  3535. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3536. procedure TglBitmap.SetMipMap(const aValue: TglBitmapMipMap);
  3537. begin
  3538. if fMipMap = aValue then
  3539. exit;
  3540. fMipMap := aValue;
  3541. end;
  3542. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3543. procedure TglBitmap.SetTarget(const aValue: Cardinal);
  3544. begin
  3545. if fTarget = aValue then
  3546. exit;
  3547. fTarget := aValue;
  3548. end;
  3549. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3550. procedure TglBitmap.SetAnisotropic(const aValue: Integer);
  3551. var
  3552. MaxAnisotropic: Integer;
  3553. begin
  3554. fAnisotropic := aValue;
  3555. if (ID > 0) then begin
  3556. if GL_EXT_texture_filter_anisotropic then begin
  3557. if fAnisotropic > 0 then begin
  3558. Bind(false);
  3559. glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
  3560. if aValue > MaxAnisotropic then
  3561. fAnisotropic := MaxAnisotropic;
  3562. glTexParameteri(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, fAnisotropic);
  3563. end;
  3564. end else begin
  3565. fAnisotropic := 0;
  3566. end;
  3567. end;
  3568. end;
  3569. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3570. procedure TglBitmap.CreateID;
  3571. begin
  3572. if (ID <> 0) then
  3573. glDeleteTextures(1, @fID);
  3574. glGenTextures(1, @fID);
  3575. Bind(false);
  3576. end;
  3577. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3578. procedure TglBitmap.SetupParameters(out aBuildWithGlu: Boolean);
  3579. begin
  3580. // Set Up Parameters
  3581. SetWrap(fWrapS, fWrapT, fWrapR);
  3582. SetFilter(fFilterMin, fFilterMag);
  3583. SetAnisotropic(fAnisotropic);
  3584. SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
  3585. // Mip Maps Generation Mode
  3586. aBuildWithGlu := false;
  3587. if (MipMap = mmMipmap) then begin
  3588. if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
  3589. glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
  3590. else
  3591. aBuildWithGlu := true;
  3592. end else if (MipMap = mmMipmapGlu) then
  3593. aBuildWithGlu := true;
  3594. end;
  3595. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3596. procedure TglBitmap.SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
  3597. const aWidth: Integer; const aHeight: Integer);
  3598. var
  3599. s: Single;
  3600. begin
  3601. if (Data <> aData) then begin
  3602. if (Assigned(Data)) then
  3603. FreeMem(Data);
  3604. fData := aData;
  3605. end;
  3606. FillChar(fDimension, SizeOf(fDimension), 0);
  3607. if not Assigned(fData) then begin
  3608. fFormat := tfEmpty;
  3609. fPixelSize := 0;
  3610. fRowSize := 0;
  3611. end else begin
  3612. if aWidth <> -1 then begin
  3613. fDimension.Fields := fDimension.Fields + [ffX];
  3614. fDimension.X := aWidth;
  3615. end;
  3616. if aHeight <> -1 then begin
  3617. fDimension.Fields := fDimension.Fields + [ffY];
  3618. fDimension.Y := aHeight;
  3619. end;
  3620. s := TFormatDescriptor.Get(aFormat).PixelSize;
  3621. fFormat := aFormat;
  3622. fPixelSize := Ceil(s);
  3623. fRowSize := Ceil(s * aWidth);
  3624. end;
  3625. end;
  3626. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3627. function TglBitmap.FlipHorz: Boolean;
  3628. begin
  3629. result := false;
  3630. end;
  3631. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3632. function TglBitmap.FlipVert: Boolean;
  3633. begin
  3634. result := false;
  3635. end;
  3636. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3637. //TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3638. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3639. procedure TglBitmap.AfterConstruction;
  3640. begin
  3641. inherited AfterConstruction;
  3642. fID := 0;
  3643. fTarget := 0;
  3644. fIsResident := false;
  3645. fFormat := glBitmapGetDefaultFormat;
  3646. fMipMap := glBitmapDefaultMipmap;
  3647. fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
  3648. fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
  3649. glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
  3650. glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
  3651. end;
  3652. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3653. procedure TglBitmap.BeforeDestruction;
  3654. begin
  3655. SetDataPointer(nil, tfEmpty);
  3656. if (fID > 0) and fDeleteTextureOnFree then
  3657. glDeleteTextures(1, @fID);
  3658. inherited BeforeDestruction;
  3659. end;
  3660. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3661. procedure TglBitmap.PrepareResType(var aResource: String; var aResType: PChar);
  3662. var
  3663. TempPos: Integer;
  3664. begin
  3665. if not Assigned(aResType) then begin
  3666. TempPos := Pos('.', aResource);
  3667. aResType := PChar(UpperCase(Copy(aResource, TempPos + 1, Length(aResource) - TempPos)));
  3668. aResource := UpperCase(Copy(aResource, 0, TempPos -1));
  3669. end;
  3670. end;
  3671. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3672. procedure TglBitmap.LoadFromFile(const aFilename: String);
  3673. var
  3674. fs: TFileStream;
  3675. begin
  3676. if not FileExists(aFilename) then
  3677. raise EglBitmapException.Create('file does not exist: ' + aFilename);
  3678. fFilename := aFilename;
  3679. fs := TFileStream.Create(fFilename, fmOpenRead);
  3680. try
  3681. fs.Position := 0;
  3682. LoadFromStream(fs);
  3683. finally
  3684. fs.Free;
  3685. end;
  3686. end;
  3687. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3688. procedure TglBitmap.LoadFromStream(const aStream: TStream);
  3689. begin
  3690. {$IFDEF GLB_SUPPORT_PNG_READ}
  3691. if not LoadPNG(aStream) then
  3692. {$ENDIF}
  3693. {$IFDEF GLB_SUPPORT_JPEG_READ}
  3694. if not LoadJPEG(aStream) then
  3695. {$ENDIF}
  3696. if not LoadDDS(aStream) then
  3697. if not LoadTGA(aStream) then
  3698. if not LoadBMP(aStream) then
  3699. raise EglBitmapException.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
  3700. end;
  3701. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3702. procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
  3703. const aFormat: TglBitmapFormat; const aArgs: Pointer);
  3704. var
  3705. tmpData: PByte;
  3706. size: Integer;
  3707. begin
  3708. size := TFormatDescriptor.Get(aFormat).GetSize(aSize);
  3709. GetMem(tmpData, size);
  3710. try
  3711. FillChar(tmpData^, size, #$FF);
  3712. SetDataPointer(tmpData, aFormat, aSize.X, aSize.Y);
  3713. except
  3714. FreeMem(tmpData);
  3715. raise;
  3716. end;
  3717. AddFunc(Self, aFunc, false, Format, aArgs);
  3718. end;
  3719. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3720. procedure TglBitmap.LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar);
  3721. var
  3722. rs: TResourceStream;
  3723. begin
  3724. PrepareResType(aResource, aResType);
  3725. rs := TResourceStream.Create(aInstance, aResource, aResType);
  3726. try
  3727. LoadFromStream(rs);
  3728. finally
  3729. rs.Free;
  3730. end;
  3731. end;
  3732. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3733. procedure TglBitmap.LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
  3734. var
  3735. rs: TResourceStream;
  3736. begin
  3737. rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
  3738. try
  3739. LoadFromStream(rs);
  3740. finally
  3741. rs.Free;
  3742. end;
  3743. end;
  3744. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3745. procedure TglBitmap.SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
  3746. var
  3747. fs: TFileStream;
  3748. begin
  3749. fs := TFileStream.Create(aFileName, fmCreate);
  3750. try
  3751. fs.Position := 0;
  3752. SaveToStream(fs, aFileType);
  3753. finally
  3754. fs.Free;
  3755. end;
  3756. end;
  3757. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3758. procedure TglBitmap.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
  3759. begin
  3760. case aFileType of
  3761. {$IFDEF GLB_SUPPORT_PNG_WRITE}
  3762. ftPNG: SavePNG(aStream);
  3763. {$ENDIF}
  3764. {$IFDEF GLB_SUPPORT_JPEG_WRITE}
  3765. ftJPEG: SaveJPEG(aStream);
  3766. {$ENDIF}
  3767. ftDDS: SaveDDS(aStream);
  3768. ftTGA: SaveTGA(aStream);
  3769. ftBMP: SaveBMP(aStream);
  3770. end;
  3771. end;
  3772. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3773. function TglBitmap.AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer): Boolean;
  3774. begin
  3775. result := AddFunc(Self, aFunc, aCreateTemp, Format, aArgs);
  3776. end;
  3777. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3778. function TglBitmap.AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
  3779. const aFormat: TglBitmapFormat; const aArgs: Pointer): Boolean;
  3780. var
  3781. DestData, TmpData, SourceData: pByte;
  3782. TempHeight, TempWidth: Integer;
  3783. SourceFD, DestFD: TFormatDescriptor;
  3784. SourceMD, DestMD: Pointer;
  3785. FuncRec: TglBitmapFunctionRec;
  3786. begin
  3787. Assert(Assigned(Data));
  3788. Assert(Assigned(aSource));
  3789. Assert(Assigned(aSource.Data));
  3790. result := false;
  3791. if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
  3792. SourceFD := TFormatDescriptor.Get(aSource.Format);
  3793. DestFD := TFormatDescriptor.Get(aFormat);
  3794. if (SourceFD.IsCompressed) then
  3795. raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', SourceFD.Format);
  3796. if (DestFD.IsCompressed) then
  3797. raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', DestFD.Format);
  3798. // inkompatible Formats so CreateTemp
  3799. if (SourceFD.PixelSize <> DestFD.PixelSize) then
  3800. aCreateTemp := true;
  3801. // Values
  3802. TempHeight := Max(1, aSource.Height);
  3803. TempWidth := Max(1, aSource.Width);
  3804. FuncRec.Sender := Self;
  3805. FuncRec.Args := aArgs;
  3806. TmpData := nil;
  3807. if aCreateTemp then begin
  3808. GetMem(TmpData, DestFD.GetSize(TempWidth, TempHeight));
  3809. DestData := TmpData;
  3810. end else
  3811. DestData := Data;
  3812. try
  3813. SourceFD.PreparePixel(FuncRec.Source);
  3814. DestFD.PreparePixel (FuncRec.Dest);
  3815. SourceMD := SourceFD.CreateMappingData;
  3816. DestMD := DestFD.CreateMappingData;
  3817. FuncRec.Size := aSource.Dimension;
  3818. FuncRec.Position.Fields := FuncRec.Size.Fields;
  3819. try
  3820. SourceData := aSource.Data;
  3821. FuncRec.Position.Y := 0;
  3822. while FuncRec.Position.Y < TempHeight do begin
  3823. FuncRec.Position.X := 0;
  3824. while FuncRec.Position.X < TempWidth do begin
  3825. SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
  3826. aFunc(FuncRec);
  3827. DestFD.Map(FuncRec.Dest, DestData, DestMD);
  3828. inc(FuncRec.Position.X);
  3829. end;
  3830. inc(FuncRec.Position.Y);
  3831. end;
  3832. // Updating Image or InternalFormat
  3833. if aCreateTemp then
  3834. SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height)
  3835. else if (aFormat <> fFormat) then
  3836. Format := aFormat;
  3837. result := true;
  3838. finally
  3839. SourceFD.FreeMappingData(SourceMD);
  3840. DestFD.FreeMappingData(DestMD);
  3841. end;
  3842. except
  3843. if aCreateTemp then
  3844. FreeMem(TmpData);
  3845. raise;
  3846. end;
  3847. end;
  3848. end;
  3849. {$IFDEF GLB_SDL}
  3850. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3851. function TglBitmap.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
  3852. var
  3853. Row, RowSize: Integer;
  3854. SourceData, TmpData: PByte;
  3855. TempDepth: Integer;
  3856. FormatDesc: TFormatDescriptor;
  3857. function GetRowPointer(Row: Integer): pByte;
  3858. begin
  3859. result := aSurface.pixels;
  3860. Inc(result, Row * RowSize);
  3861. end;
  3862. begin
  3863. result := false;
  3864. FormatDesc := TFormatDescriptor.Get(Format);
  3865. if FormatDesc.IsCompressed then
  3866. raise EglBitmapUnsupportedFormat.Create(Format);
  3867. if Assigned(Data) then begin
  3868. case Trunc(FormatDesc.PixelSize) of
  3869. 1: TempDepth := 8;
  3870. 2: TempDepth := 16;
  3871. 3: TempDepth := 24;
  3872. 4: TempDepth := 32;
  3873. else
  3874. raise EglBitmapUnsupportedFormat.Create(Format);
  3875. end;
  3876. aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
  3877. FormatDesc.RedMask, FormatDesc.GreenMask, FormatDesc.BlueMask, FormatDesc.AlphaMask);
  3878. SourceData := Data;
  3879. RowSize := FormatDesc.GetSize(FileWidth, 1);
  3880. for Row := 0 to FileHeight-1 do begin
  3881. TmpData := GetRowPointer(Row);
  3882. if Assigned(TmpData) then begin
  3883. Move(SourceData^, TmpData^, RowSize);
  3884. inc(SourceData, RowSize);
  3885. end;
  3886. end;
  3887. result := true;
  3888. end;
  3889. end;
  3890. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3891. function TglBitmap.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
  3892. var
  3893. pSource, pData, pTempData: PByte;
  3894. Row, RowSize, TempWidth, TempHeight: Integer;
  3895. IntFormat: TglBitmapFormat;
  3896. FormatDesc: TFormatDescriptor;
  3897. function GetRowPointer(Row: Integer): pByte;
  3898. begin
  3899. result := aSurface^.pixels;
  3900. Inc(result, Row * RowSize);
  3901. end;
  3902. begin
  3903. result := false;
  3904. if (Assigned(aSurface)) then begin
  3905. with aSurface^.format^ do begin
  3906. for IntFormat := High(TglBitmapFormat) to Low(TglBitmapFormat) do begin
  3907. FormatDesc := TFormatDescriptor.Get(IntFormat);
  3908. if (FormatDesc.MaskMatch(RMask, GMask, BMask, AMask)) then
  3909. break;
  3910. end;
  3911. if (IntFormat = tfEmpty) then
  3912. raise EglBitmapException.Create('AssignFromSurface - Invalid Pixelformat.');
  3913. end;
  3914. TempWidth := aSurface^.w;
  3915. TempHeight := aSurface^.h;
  3916. RowSize := FormatDesc.GetSize(TempWidth, 1);
  3917. GetMem(pData, TempHeight * RowSize);
  3918. try
  3919. pTempData := pData;
  3920. for Row := 0 to TempHeight -1 do begin
  3921. pSource := GetRowPointer(Row);
  3922. if (Assigned(pSource)) then begin
  3923. Move(pSource^, pTempData^, RowSize);
  3924. Inc(pTempData, RowSize);
  3925. end;
  3926. end;
  3927. SetDataPointer(pData, IntFormat, TempWidth, TempHeight);
  3928. result := true;
  3929. except
  3930. FreeMem(pData);
  3931. raise;
  3932. end;
  3933. end;
  3934. end;
  3935. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3936. function TglBitmap.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
  3937. var
  3938. Row, Col, AlphaInterleave: Integer;
  3939. pSource, pDest: PByte;
  3940. function GetRowPointer(Row: Integer): pByte;
  3941. begin
  3942. result := aSurface.pixels;
  3943. Inc(result, Row * Width);
  3944. end;
  3945. begin
  3946. result := false;
  3947. if Assigned(Data) then begin
  3948. if Format in [tfAlpha8, tfLuminance8Alpha8, tfBGRA8, tfRGBA8] then begin
  3949. aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
  3950. AlphaInterleave := 0;
  3951. case Format of
  3952. tfLuminance8Alpha8:
  3953. AlphaInterleave := 1;
  3954. tfBGRA8, tfRGBA8:
  3955. AlphaInterleave := 3;
  3956. end;
  3957. pSource := Data;
  3958. for Row := 0 to Height -1 do begin
  3959. pDest := GetRowPointer(Row);
  3960. if Assigned(pDest) then begin
  3961. for Col := 0 to Width -1 do begin
  3962. Inc(pSource, AlphaInterleave);
  3963. pDest^ := pSource^;
  3964. Inc(pDest);
  3965. Inc(pSource);
  3966. end;
  3967. end;
  3968. end;
  3969. result := true;
  3970. end;
  3971. end;
  3972. end;
  3973. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3974. function TglBitmap.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
  3975. var
  3976. bmp: TglBitmap2D;
  3977. begin
  3978. bmp := TglBitmap2D.Create;
  3979. try
  3980. bmp.AssignFromSurface(aSurface);
  3981. result := AddAlphaFromGlBitmap(bmp, aFunc, aArgs);
  3982. finally
  3983. bmp.Free;
  3984. end;
  3985. end;
  3986. {$ENDIF}
  3987. {$IFDEF GLB_DELPHI}
  3988. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3989. function CreateGrayPalette: HPALETTE;
  3990. var
  3991. Idx: Integer;
  3992. Pal: PLogPalette;
  3993. begin
  3994. GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
  3995. Pal.palVersion := $300;
  3996. Pal.palNumEntries := 256;
  3997. for Idx := 0 to Pal.palNumEntries - 1 do begin
  3998. Pal.palPalEntry[Idx].peRed := Idx;
  3999. Pal.palPalEntry[Idx].peGreen := Idx;
  4000. Pal.palPalEntry[Idx].peBlue := Idx;
  4001. Pal.palPalEntry[Idx].peFlags := 0;
  4002. end;
  4003. Result := CreatePalette(Pal^);
  4004. FreeMem(Pal);
  4005. end;
  4006. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4007. function TglBitmap.AssignToBitmap(const aBitmap: TBitmap): Boolean;
  4008. var
  4009. Row: Integer;
  4010. pSource, pData: PByte;
  4011. begin
  4012. result := false;
  4013. if Assigned(Data) then begin
  4014. if Assigned(aBitmap) then begin
  4015. aBitmap.Width := Width;
  4016. aBitmap.Height := Height;
  4017. case Format of
  4018. tfAlpha8, tfLuminance8: begin
  4019. aBitmap.PixelFormat := pf8bit;
  4020. aBitmap.Palette := CreateGrayPalette;
  4021. end;
  4022. tfRGB5A1:
  4023. aBitmap.PixelFormat := pf15bit;
  4024. tfR5G6B5:
  4025. aBitmap.PixelFormat := pf16bit;
  4026. tfRGB8, tfBGR8:
  4027. aBitmap.PixelFormat := pf24bit;
  4028. tfRGBA8, tfBGRA8:
  4029. aBitmap.PixelFormat := pf32bit;
  4030. else
  4031. raise EglBitmapException.Create('AssignToBitmap - Invalid Pixelformat.');
  4032. end;
  4033. pSource := Data;
  4034. for Row := 0 to FileHeight -1 do begin
  4035. pData := aBitmap.Scanline[Row];
  4036. Move(pSource^, pData^, fRowSize);
  4037. Inc(pSource, fRowSize);
  4038. if (Format in [tfRGB8, tfRGBA8]) then // swap RGB(A) to BGR(A)
  4039. SwapRGB(pData, FileWidth, Format = tfRGBA8);
  4040. end;
  4041. result := true;
  4042. end;
  4043. end;
  4044. end;
  4045. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4046. function TglBitmap.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
  4047. var
  4048. pSource, pData, pTempData: PByte;
  4049. Row, RowSize, TempWidth, TempHeight: Integer;
  4050. IntFormat: TglBitmapFormat;
  4051. begin
  4052. result := false;
  4053. if (Assigned(aBitmap)) then begin
  4054. case aBitmap.PixelFormat of
  4055. pf8bit:
  4056. IntFormat := tfLuminance8;
  4057. pf15bit:
  4058. IntFormat := tfRGB5A1;
  4059. pf16bit:
  4060. IntFormat := tfR5G6B5;
  4061. pf24bit:
  4062. IntFormat := tfBGR8;
  4063. pf32bit:
  4064. IntFormat := tfBGRA8;
  4065. else
  4066. raise EglBitmapException.Create('AssignFromBitmap - Invalid Pixelformat.');
  4067. end;
  4068. TempWidth := aBitmap.Width;
  4069. TempHeight := aBitmap.Height;
  4070. RowSize := TFormatDescriptor.Get(IntFormat).GetSize(TempWidth, 1);
  4071. GetMem(pData, TempHeight * RowSize);
  4072. try
  4073. pTempData := pData;
  4074. for Row := 0 to TempHeight -1 do begin
  4075. pSource := aBitmap.Scanline[Row];
  4076. if (Assigned(pSource)) then begin
  4077. Move(pSource^, pTempData^, RowSize);
  4078. Inc(pTempData, RowSize);
  4079. end;
  4080. end;
  4081. SetDataPointer(pData, IntFormat, TempWidth, TempHeight);
  4082. result := true;
  4083. except
  4084. FreeMem(pData);
  4085. raise;
  4086. end;
  4087. end;
  4088. end;
  4089. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4090. function TglBitmap.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
  4091. var
  4092. Row, Col, AlphaInterleave: Integer;
  4093. pSource, pDest: PByte;
  4094. begin
  4095. result := false;
  4096. if Assigned(Data) then begin
  4097. if (Format in [tfAlpha8, tfLuminance8Alpha8, tfRGBA8, tfBGRA8]) then begin
  4098. if Assigned(aBitmap) then begin
  4099. aBitmap.PixelFormat := pf8bit;
  4100. aBitmap.Palette := CreateGrayPalette;
  4101. aBitmap.Width := Width;
  4102. aBitmap.Height := Height;
  4103. case Format of
  4104. tfLuminance8Alpha8:
  4105. AlphaInterleave := 1;
  4106. tfRGBA8, tfBGRA8:
  4107. AlphaInterleave := 3;
  4108. else
  4109. AlphaInterleave := 0;
  4110. end;
  4111. // Copy Data
  4112. pSource := Data;
  4113. for Row := 0 to Height -1 do begin
  4114. pDest := aBitmap.Scanline[Row];
  4115. if Assigned(pDest) then begin
  4116. for Col := 0 to Width -1 do begin
  4117. Inc(pSource, AlphaInterleave);
  4118. pDest^ := pSource^;
  4119. Inc(pDest);
  4120. Inc(pSource);
  4121. end;
  4122. end;
  4123. end;
  4124. result := true;
  4125. end;
  4126. end;
  4127. end;
  4128. end;
  4129. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4130. function TglBitmap.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  4131. var
  4132. tex: TglBitmap2D;
  4133. begin
  4134. tex := TglBitmap2D.Create;
  4135. try
  4136. tex.AssignFromBitmap(ABitmap);
  4137. result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
  4138. finally
  4139. tex.Free;
  4140. end;
  4141. end;
  4142. {$ENDIF}
  4143. {$IFDEF GLB_LAZARUS}
  4144. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4145. function TglBitmap.AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
  4146. var
  4147. rid: TRawImageDescription;
  4148. FormatDesc: TFormatDescriptor;
  4149. begin
  4150. result := false;
  4151. if not Assigned(aImage) or (Format = tfEmpty) then
  4152. exit;
  4153. FormatDesc := TFormatDescriptor.Get(Format);
  4154. if FormatDesc.IsCompressed then
  4155. exit;
  4156. FillChar(rid{%H-}, SizeOf(rid), 0);
  4157. if (Format in [
  4158. tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16,
  4159. tfLuminance4, tfLuminance8, tfLuminance12, tfLuminance16,
  4160. tfLuminance4Alpha4, tfLuminance8Alpha8, tfLuminance12Alpha4, tfLuminance12Alpha12, tfLuminance16Alpha16]) then
  4161. rid.Format := ricfGray
  4162. else
  4163. rid.Format := ricfRGBA;
  4164. rid.Width := Width;
  4165. rid.Height := Height;
  4166. rid.Depth := CountSetBits(FormatDesc.Range.r or FormatDesc.Range.g or FormatDesc.Range.b or FormatDesc.Range.a);
  4167. rid.BitOrder := riboBitsInOrder;
  4168. rid.ByteOrder := riboLSBFirst;
  4169. rid.LineOrder := riloTopToBottom;
  4170. rid.LineEnd := rileTight;
  4171. rid.BitsPerPixel := Round(8 * FormatDesc.PixelSize);
  4172. rid.RedPrec := CountSetBits(FormatDesc.Range.r);
  4173. rid.GreenPrec := CountSetBits(FormatDesc.Range.g);
  4174. rid.BluePrec := CountSetBits(FormatDesc.Range.b);
  4175. rid.AlphaPrec := CountSetBits(FormatDesc.Range.a);
  4176. rid.RedShift := FormatDesc.Shift.r;
  4177. rid.GreenShift := FormatDesc.Shift.g;
  4178. rid.BlueShift := FormatDesc.Shift.b;
  4179. rid.AlphaShift := FormatDesc.Shift.a;
  4180. rid.MaskBitsPerPixel := 0;
  4181. rid.PaletteColorCount := 0;
  4182. aImage.DataDescription := rid;
  4183. aImage.CreateData;
  4184. Move(Data^, aImage.PixelData^, FormatDesc.GetSize(Dimension));
  4185. result := true;
  4186. end;
  4187. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4188. function TglBitmap.AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
  4189. var
  4190. f: TglBitmapFormat;
  4191. FormatDesc: TFormatDescriptor;
  4192. ImageData: PByte;
  4193. ImageSize: Integer;
  4194. begin
  4195. result := false;
  4196. if not Assigned(aImage) then
  4197. exit;
  4198. for f := High(f) downto Low(f) do begin
  4199. FormatDesc := TFormatDescriptor.Get(f);
  4200. with aImage.DataDescription do
  4201. if FormatDesc.MaskMatch(
  4202. (QWord(1 shl RedPrec )-1) shl RedShift,
  4203. (QWord(1 shl GreenPrec)-1) shl GreenShift,
  4204. (QWord(1 shl BluePrec )-1) shl BlueShift,
  4205. (QWord(1 shl AlphaPrec)-1) shl AlphaShift) then
  4206. break;
  4207. end;
  4208. if (f = tfEmpty) then
  4209. exit;
  4210. ImageSize := FormatDesc.GetSize(aImage.Width, aImage.Height);
  4211. ImageData := GetMem(ImageSize);
  4212. try
  4213. Move(aImage.PixelData^, ImageData^, (aImage.Width * aImage.Height * aImage.DataDescription.BitsPerPixel) shr 3);
  4214. SetDataPointer(ImageData, f, aImage.Width, aImage.Height);
  4215. except
  4216. FreeMem(ImageData);
  4217. raise;
  4218. end;
  4219. result := true;
  4220. end;
  4221. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4222. function TglBitmap.AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
  4223. var
  4224. rid: TRawImageDescription;
  4225. FormatDesc: TFormatDescriptor;
  4226. Pixel: TglBitmapPixelData;
  4227. x, y: Integer;
  4228. srcMD: Pointer;
  4229. src, dst: PByte;
  4230. begin
  4231. result := false;
  4232. if not Assigned(aImage) or (Format = tfEmpty) then
  4233. exit;
  4234. FormatDesc := TFormatDescriptor.Get(Format);
  4235. if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
  4236. exit;
  4237. FillChar(rid{%H-}, SizeOf(rid), 0);
  4238. rid.Format := ricfGray;
  4239. rid.Width := Width;
  4240. rid.Height := Height;
  4241. rid.Depth := CountSetBits(FormatDesc.Range.a);
  4242. rid.BitOrder := riboBitsInOrder;
  4243. rid.ByteOrder := riboLSBFirst;
  4244. rid.LineOrder := riloTopToBottom;
  4245. rid.LineEnd := rileTight;
  4246. rid.BitsPerPixel := 8 * Ceil(rid.Depth / 8);
  4247. rid.RedPrec := CountSetBits(FormatDesc.Range.a);
  4248. rid.GreenPrec := 0;
  4249. rid.BluePrec := 0;
  4250. rid.AlphaPrec := 0;
  4251. rid.RedShift := 0;
  4252. rid.GreenShift := 0;
  4253. rid.BlueShift := 0;
  4254. rid.AlphaShift := 0;
  4255. rid.MaskBitsPerPixel := 0;
  4256. rid.PaletteColorCount := 0;
  4257. aImage.DataDescription := rid;
  4258. aImage.CreateData;
  4259. srcMD := FormatDesc.CreateMappingData;
  4260. try
  4261. FormatDesc.PreparePixel(Pixel);
  4262. src := Data;
  4263. dst := aImage.PixelData;
  4264. for y := 0 to Height-1 do
  4265. for x := 0 to Width-1 do begin
  4266. FormatDesc.Unmap(src, Pixel, srcMD);
  4267. case rid.BitsPerPixel of
  4268. 8: begin
  4269. dst^ := Pixel.Data.a;
  4270. inc(dst);
  4271. end;
  4272. 16: begin
  4273. PWord(dst)^ := Pixel.Data.a;
  4274. inc(dst, 2);
  4275. end;
  4276. 24: begin
  4277. PByteArray(dst)^[0] := PByteArray(@Pixel.Data.a)^[0];
  4278. PByteArray(dst)^[1] := PByteArray(@Pixel.Data.a)^[1];
  4279. PByteArray(dst)^[2] := PByteArray(@Pixel.Data.a)^[2];
  4280. inc(dst, 3);
  4281. end;
  4282. 32: begin
  4283. PCardinal(dst)^ := Pixel.Data.a;
  4284. inc(dst, 4);
  4285. end;
  4286. else
  4287. raise EglBitmapUnsupportedFormat.Create(Format);
  4288. end;
  4289. end;
  4290. finally
  4291. FormatDesc.FreeMappingData(srcMD);
  4292. end;
  4293. result := true;
  4294. end;
  4295. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4296. function TglBitmap.AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  4297. var
  4298. tex: TglBitmap2D;
  4299. begin
  4300. tex := TglBitmap2D.Create;
  4301. try
  4302. tex.AssignFromLazIntfImage(aImage);
  4303. result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
  4304. finally
  4305. tex.Free;
  4306. end;
  4307. end;
  4308. {$ENDIF}
  4309. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4310. function TglBitmap.AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar;
  4311. const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  4312. var
  4313. rs: TResourceStream;
  4314. begin
  4315. PrepareResType(aResource, aResType);
  4316. rs := TResourceStream.Create(aInstance, aResource, aResType);
  4317. try
  4318. result := AddAlphaFromStream(rs, aFunc, aArgs);
  4319. finally
  4320. rs.Free;
  4321. end;
  4322. end;
  4323. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4324. function TglBitmap.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
  4325. const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  4326. var
  4327. rs: TResourceStream;
  4328. begin
  4329. rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
  4330. try
  4331. result := AddAlphaFromStream(rs, aFunc, aArgs);
  4332. finally
  4333. rs.Free;
  4334. end;
  4335. end;
  4336. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4337. function TglBitmap.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  4338. begin
  4339. if TFormatDescriptor.Get(Format).IsCompressed then
  4340. raise EglBitmapUnsupportedFormat.Create(Format);
  4341. result := AddFunc(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs);
  4342. end;
  4343. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4344. function TglBitmap.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  4345. var
  4346. FS: TFileStream;
  4347. begin
  4348. FS := TFileStream.Create(FileName, fmOpenRead);
  4349. try
  4350. result := AddAlphaFromStream(FS, aFunc, aArgs);
  4351. finally
  4352. FS.Free;
  4353. end;
  4354. end;
  4355. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4356. function TglBitmap.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  4357. var
  4358. tex: TglBitmap2D;
  4359. begin
  4360. tex := TglBitmap2D.Create(aStream);
  4361. try
  4362. result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
  4363. finally
  4364. tex.Free;
  4365. end;
  4366. end;
  4367. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4368. function TglBitmap.AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
  4369. var
  4370. DestData, DestData2, SourceData: pByte;
  4371. TempHeight, TempWidth: Integer;
  4372. SourceFD, DestFD: TFormatDescriptor;
  4373. SourceMD, DestMD, DestMD2: Pointer;
  4374. FuncRec: TglBitmapFunctionRec;
  4375. begin
  4376. result := false;
  4377. Assert(Assigned(Data));
  4378. Assert(Assigned(aBitmap));
  4379. Assert(Assigned(aBitmap.Data));
  4380. if ((aBitmap.Width = Width) and (aBitmap.Height = Height)) then begin
  4381. result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
  4382. SourceFD := TFormatDescriptor.Get(aBitmap.Format);
  4383. DestFD := TFormatDescriptor.Get(Format);
  4384. if not Assigned(aFunc) then begin
  4385. aFunc := glBitmapAlphaFunc;
  4386. FuncRec.Args := {%H-}Pointer(SourceFD.HasAlpha);
  4387. end else
  4388. FuncRec.Args := aArgs;
  4389. // Values
  4390. TempHeight := aBitmap.FileHeight;
  4391. TempWidth := aBitmap.FileWidth;
  4392. FuncRec.Sender := Self;
  4393. FuncRec.Size := Dimension;
  4394. FuncRec.Position.Fields := FuncRec.Size.Fields;
  4395. DestData := Data;
  4396. DestData2 := Data;
  4397. SourceData := aBitmap.Data;
  4398. // Mapping
  4399. SourceFD.PreparePixel(FuncRec.Source);
  4400. DestFD.PreparePixel (FuncRec.Dest);
  4401. SourceMD := SourceFD.CreateMappingData;
  4402. DestMD := DestFD.CreateMappingData;
  4403. DestMD2 := DestFD.CreateMappingData;
  4404. try
  4405. FuncRec.Position.Y := 0;
  4406. while FuncRec.Position.Y < TempHeight do begin
  4407. FuncRec.Position.X := 0;
  4408. while FuncRec.Position.X < TempWidth do begin
  4409. SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
  4410. DestFD.Unmap (DestData, FuncRec.Dest, DestMD);
  4411. aFunc(FuncRec);
  4412. DestFD.Map(FuncRec.Dest, DestData2, DestMD2);
  4413. inc(FuncRec.Position.X);
  4414. end;
  4415. inc(FuncRec.Position.Y);
  4416. end;
  4417. finally
  4418. SourceFD.FreeMappingData(SourceMD);
  4419. DestFD.FreeMappingData(DestMD);
  4420. DestFD.FreeMappingData(DestMD2);
  4421. end;
  4422. end;
  4423. end;
  4424. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4425. function TglBitmap.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
  4426. begin
  4427. result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
  4428. end;
  4429. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4430. function TglBitmap.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
  4431. var
  4432. PixelData: TglBitmapPixelData;
  4433. begin
  4434. TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
  4435. result := AddAlphaFromColorKeyFloat(
  4436. aRed / PixelData.Range.r,
  4437. aGreen / PixelData.Range.g,
  4438. aBlue / PixelData.Range.b,
  4439. aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b)));
  4440. end;
  4441. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4442. function TglBitmap.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
  4443. var
  4444. values: array[0..2] of Single;
  4445. tmp: Cardinal;
  4446. i: Integer;
  4447. PixelData: TglBitmapPixelData;
  4448. begin
  4449. TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
  4450. with PixelData do begin
  4451. values[0] := aRed;
  4452. values[1] := aGreen;
  4453. values[2] := aBlue;
  4454. for i := 0 to 2 do begin
  4455. tmp := Trunc(Range.arr[i] * aDeviation);
  4456. Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp));
  4457. Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp));
  4458. end;
  4459. Data.a := 0;
  4460. Range.a := 0;
  4461. end;
  4462. result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, @PixelData);
  4463. end;
  4464. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4465. function TglBitmap.AddAlphaFromValue(const aAlpha: Byte): Boolean;
  4466. begin
  4467. result := AddAlphaFromValueFloat(aAlpha / $FF);
  4468. end;
  4469. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4470. function TglBitmap.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
  4471. var
  4472. PixelData: TglBitmapPixelData;
  4473. begin
  4474. TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
  4475. result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
  4476. end;
  4477. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4478. function TglBitmap.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
  4479. var
  4480. PixelData: TglBitmapPixelData;
  4481. begin
  4482. TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
  4483. with PixelData do
  4484. Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
  4485. result := AddAlphaFromFunc(glBitmapValueAlphaFunc, @PixelData.Data.a);
  4486. end;
  4487. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4488. function TglBitmap.RemoveAlpha: Boolean;
  4489. var
  4490. FormatDesc: TFormatDescriptor;
  4491. begin
  4492. result := false;
  4493. FormatDesc := TFormatDescriptor.Get(Format);
  4494. if Assigned(Data) then begin
  4495. if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
  4496. raise EglBitmapUnsupportedFormat.Create(Format);
  4497. result := ConvertTo(FormatDesc.WithoutAlpha);
  4498. end;
  4499. end;
  4500. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4501. function TglBitmap.Clone: TglBitmap;
  4502. var
  4503. Temp: TglBitmap;
  4504. TempPtr: PByte;
  4505. Size: Integer;
  4506. begin
  4507. result := nil;
  4508. Temp := (ClassType.Create as TglBitmap);
  4509. try
  4510. // copy texture data if assigned
  4511. if Assigned(Data) then begin
  4512. Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
  4513. GetMem(TempPtr, Size);
  4514. try
  4515. Move(Data^, TempPtr^, Size);
  4516. Temp.SetDataPointer(TempPtr, Format, Width, Height);
  4517. except
  4518. FreeMem(TempPtr);
  4519. raise;
  4520. end;
  4521. end else
  4522. Temp.SetDataPointer(nil, Format, Width, Height);
  4523. // copy properties
  4524. Temp.fID := ID;
  4525. Temp.fTarget := Target;
  4526. Temp.fFormat := Format;
  4527. Temp.fMipMap := MipMap;
  4528. Temp.fAnisotropic := Anisotropic;
  4529. Temp.fBorderColor := fBorderColor;
  4530. Temp.fDeleteTextureOnFree := DeleteTextureOnFree;
  4531. Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
  4532. Temp.fFilterMin := fFilterMin;
  4533. Temp.fFilterMag := fFilterMag;
  4534. Temp.fWrapS := fWrapS;
  4535. Temp.fWrapT := fWrapT;
  4536. Temp.fWrapR := fWrapR;
  4537. Temp.fFilename := fFilename;
  4538. Temp.fCustomName := fCustomName;
  4539. Temp.fCustomNameW := fCustomNameW;
  4540. Temp.fCustomData := fCustomData;
  4541. result := Temp;
  4542. except
  4543. FreeAndNil(Temp);
  4544. raise;
  4545. end;
  4546. end;
  4547. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4548. function TglBitmap.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
  4549. var
  4550. SourceFD, DestFD: TFormatDescriptor;
  4551. SourcePD, DestPD: TglBitmapPixelData;
  4552. ShiftData: TShiftData;
  4553. function CanCopyDirect: Boolean;
  4554. begin
  4555. result :=
  4556. ((SourcePD.Range.r = DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
  4557. ((SourcePD.Range.g = DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
  4558. ((SourcePD.Range.b = DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
  4559. ((SourcePD.Range.a = DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
  4560. end;
  4561. function CanShift: Boolean;
  4562. begin
  4563. result :=
  4564. ((SourcePD.Range.r >= DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
  4565. ((SourcePD.Range.g >= DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
  4566. ((SourcePD.Range.b >= DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
  4567. ((SourcePD.Range.a >= DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
  4568. end;
  4569. function GetShift(aSource, aDest: Cardinal) : ShortInt;
  4570. begin
  4571. result := 0;
  4572. while (aSource > aDest) and (aSource > 0) do begin
  4573. inc(result);
  4574. aSource := aSource shr 1;
  4575. end;
  4576. end;
  4577. begin
  4578. if (aFormat <> fFormat) and (aFormat <> tfEmpty) then begin
  4579. SourceFD := TFormatDescriptor.Get(Format);
  4580. DestFD := TFormatDescriptor.Get(aFormat);
  4581. SourceFD.PreparePixel(SourcePD);
  4582. DestFD.PreparePixel (DestPD);
  4583. if CanCopyDirect then
  4584. result := AddFunc(Self, glBitmapConvertCopyFunc, false, aFormat)
  4585. else if CanShift then begin
  4586. ShiftData.r := GetShift(SourcePD.Range.r, DestPD.Range.r);
  4587. ShiftData.g := GetShift(SourcePD.Range.g, DestPD.Range.g);
  4588. ShiftData.b := GetShift(SourcePD.Range.b, DestPD.Range.b);
  4589. ShiftData.a := GetShift(SourcePD.Range.a, DestPD.Range.a);
  4590. result := AddFunc(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, @ShiftData);
  4591. end else
  4592. result := AddFunc(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
  4593. end else
  4594. result := true;
  4595. end;
  4596. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4597. procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
  4598. begin
  4599. if aUseRGB or aUseAlpha then
  4600. AddFunc(glBitmapInvertFunc, false, {%H-}Pointer(
  4601. ((PtrInt(aUseAlpha) and 1) shl 1) or
  4602. (PtrInt(aUseRGB) and 1) ));
  4603. end;
  4604. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4605. procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
  4606. begin
  4607. fBorderColor[0] := aRed;
  4608. fBorderColor[1] := aGreen;
  4609. fBorderColor[2] := aBlue;
  4610. fBorderColor[3] := aAlpha;
  4611. if (ID > 0) then begin
  4612. Bind(false);
  4613. glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
  4614. end;
  4615. end;
  4616. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4617. procedure TglBitmap.FreeData;
  4618. begin
  4619. SetDataPointer(nil, tfEmpty);
  4620. end;
  4621. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4622. procedure TglBitmap.FillWithColor(const aRed, aGreen, aBlue: Byte;
  4623. const aAlpha: Byte);
  4624. begin
  4625. FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
  4626. end;
  4627. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4628. procedure TglBitmap.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
  4629. var
  4630. PixelData: TglBitmapPixelData;
  4631. begin
  4632. TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
  4633. FillWithColorFloat(
  4634. aRed / PixelData.Range.r,
  4635. aGreen / PixelData.Range.g,
  4636. aBlue / PixelData.Range.b,
  4637. aAlpha / PixelData.Range.a);
  4638. end;
  4639. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4640. procedure TglBitmap.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
  4641. var
  4642. PixelData: TglBitmapPixelData;
  4643. begin
  4644. TFormatDescriptor.Get(Format).PreparePixel(PixelData);
  4645. with PixelData do begin
  4646. Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed)));
  4647. Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen)));
  4648. Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue)));
  4649. Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha)));
  4650. end;
  4651. AddFunc(glBitmapFillWithColorFunc, false, @PixelData);
  4652. end;
  4653. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4654. procedure TglBitmap.SetFilter(const aMin, aMag: Cardinal);
  4655. begin
  4656. //check MIN filter
  4657. case aMin of
  4658. GL_NEAREST:
  4659. fFilterMin := GL_NEAREST;
  4660. GL_LINEAR:
  4661. fFilterMin := GL_LINEAR;
  4662. GL_NEAREST_MIPMAP_NEAREST:
  4663. fFilterMin := GL_NEAREST_MIPMAP_NEAREST;
  4664. GL_LINEAR_MIPMAP_NEAREST:
  4665. fFilterMin := GL_LINEAR_MIPMAP_NEAREST;
  4666. GL_NEAREST_MIPMAP_LINEAR:
  4667. fFilterMin := GL_NEAREST_MIPMAP_LINEAR;
  4668. GL_LINEAR_MIPMAP_LINEAR:
  4669. fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
  4670. else
  4671. raise EglBitmapException.Create('SetFilter - Unknow MIN filter.');
  4672. end;
  4673. //check MAG filter
  4674. case aMag of
  4675. GL_NEAREST:
  4676. fFilterMag := GL_NEAREST;
  4677. GL_LINEAR:
  4678. fFilterMag := GL_LINEAR;
  4679. else
  4680. raise EglBitmapException.Create('SetFilter - Unknow MAG filter.');
  4681. end;
  4682. //apply filter
  4683. if (ID > 0) then begin
  4684. Bind(false);
  4685. glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
  4686. if (MipMap = mmNone) or (Target = GL_TEXTURE_RECTANGLE) then begin
  4687. case fFilterMin of
  4688. GL_NEAREST, GL_LINEAR:
  4689. glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
  4690. GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR:
  4691. glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  4692. GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR:
  4693. glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  4694. end;
  4695. end else
  4696. glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
  4697. end;
  4698. end;
  4699. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4700. procedure TglBitmap.SetWrap(const S: Cardinal; const T: Cardinal; const R: Cardinal);
  4701. procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
  4702. begin
  4703. case aValue of
  4704. GL_CLAMP:
  4705. aTarget := GL_CLAMP;
  4706. GL_REPEAT:
  4707. aTarget := GL_REPEAT;
  4708. GL_CLAMP_TO_EDGE: begin
  4709. if GL_VERSION_1_2 or GL_EXT_texture_edge_clamp then
  4710. aTarget := GL_CLAMP_TO_EDGE
  4711. else
  4712. aTarget := GL_CLAMP;
  4713. end;
  4714. GL_CLAMP_TO_BORDER: begin
  4715. if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
  4716. aTarget := GL_CLAMP_TO_BORDER
  4717. else
  4718. aTarget := GL_CLAMP;
  4719. end;
  4720. GL_MIRRORED_REPEAT: begin
  4721. if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
  4722. aTarget := GL_MIRRORED_REPEAT
  4723. else
  4724. raise EglBitmapException.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
  4725. end;
  4726. else
  4727. raise EglBitmapException.Create('SetWrap - Unknow Texturewrap (S).');
  4728. end;
  4729. end;
  4730. begin
  4731. CheckAndSetWrap(S, fWrapS);
  4732. CheckAndSetWrap(T, fWrapT);
  4733. CheckAndSetWrap(R, fWrapR);
  4734. if (ID > 0) then begin
  4735. Bind(false);
  4736. glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
  4737. glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
  4738. glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
  4739. end;
  4740. end;
  4741. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4742. procedure TglBitmap.Bind(const aEnableTextureUnit: Boolean);
  4743. begin
  4744. if aEnableTextureUnit then
  4745. glEnable(Target);
  4746. if (ID > 0) then
  4747. glBindTexture(Target, ID);
  4748. end;
  4749. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4750. procedure TglBitmap.Unbind(const aDisableTextureUnit: Boolean);
  4751. begin
  4752. if aDisableTextureUnit then
  4753. glDisable(Target);
  4754. glBindTexture(Target, 0);
  4755. end;
  4756. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4757. constructor TglBitmap.Create;
  4758. begin
  4759. {$IFDEF GLB_NATIVE_OGL}
  4760. glbReadOpenGLExtensions;
  4761. {$ENDIF}
  4762. if (ClassType = TglBitmap) then
  4763. raise EglBitmapException.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
  4764. inherited Create;
  4765. end;
  4766. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4767. constructor TglBitmap.Create(const aFileName: String);
  4768. begin
  4769. Create;
  4770. LoadFromFile(FileName);
  4771. end;
  4772. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4773. constructor TglBitmap.Create(const aStream: TStream);
  4774. begin
  4775. Create;
  4776. LoadFromStream(aStream);
  4777. end;
  4778. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4779. constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat);
  4780. var
  4781. Image: PByte;
  4782. ImageSize: Integer;
  4783. begin
  4784. Create;
  4785. ImageSize := TFormatDescriptor.Get(aFormat).GetSize(aSize);
  4786. GetMem(Image, ImageSize);
  4787. try
  4788. FillChar(Image^, ImageSize, #$FF);
  4789. SetDataPointer(Image, aFormat, aSize.X, aSize.Y);
  4790. except
  4791. FreeMem(Image);
  4792. raise;
  4793. end;
  4794. end;
  4795. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4796. constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat;
  4797. const aFunc: TglBitmapFunction; const aArgs: Pointer);
  4798. begin
  4799. Create;
  4800. LoadFromFunc(aSize, aFunc, aFormat, aArgs);
  4801. end;
  4802. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4803. constructor TglBitmap.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
  4804. begin
  4805. Create;
  4806. LoadFromResource(aInstance, aResource, aResType);
  4807. end;
  4808. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4809. constructor TglBitmap.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
  4810. begin
  4811. Create;
  4812. LoadFromResourceID(aInstance, aResourceID, aResType);
  4813. end;
  4814. {$IFDEF GLB_SUPPORT_PNG_READ}
  4815. {$IF DEFINED(GLB_SDL_IMAGE)}
  4816. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4817. //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4818. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4819. function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
  4820. var
  4821. Surface: PSDL_Surface;
  4822. RWops: PSDL_RWops;
  4823. begin
  4824. result := false;
  4825. RWops := glBitmapCreateRWops(aStream);
  4826. try
  4827. if IMG_isPNG(RWops) > 0 then begin
  4828. Surface := IMG_LoadPNG_RW(RWops);
  4829. try
  4830. AssignFromSurface(Surface);
  4831. result := true;
  4832. finally
  4833. SDL_FreeSurface(Surface);
  4834. end;
  4835. end;
  4836. finally
  4837. SDL_FreeRW(RWops);
  4838. end;
  4839. end;
  4840. {$ELSEIF DEFINED(GLB_LIB_PNG)}
  4841. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4842. procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
  4843. begin
  4844. TStream(png_get_io_ptr(png)).Read(buffer^, size);
  4845. end;
  4846. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4847. function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
  4848. var
  4849. StreamPos: Int64;
  4850. signature: array [0..7] of byte;
  4851. png: png_structp;
  4852. png_info: png_infop;
  4853. TempHeight, TempWidth: Integer;
  4854. Format: TglBitmapFormat;
  4855. png_data: pByte;
  4856. png_rows: array of pByte;
  4857. Row, LineSize: Integer;
  4858. begin
  4859. result := false;
  4860. if not init_libPNG then
  4861. raise Exception.Create('LoadPNG - unable to initialize libPNG.');
  4862. try
  4863. // signature
  4864. StreamPos := aStream.Position;
  4865. aStream.Read(signature{%H-}, 8);
  4866. aStream.Position := StreamPos;
  4867. if png_check_sig(@signature, 8) <> 0 then begin
  4868. // png read struct
  4869. png := png_create_read_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
  4870. if png = nil then
  4871. raise EglBitmapException.Create('LoadPng - couldn''t create read struct.');
  4872. // png info
  4873. png_info := png_create_info_struct(png);
  4874. if png_info = nil then begin
  4875. png_destroy_read_struct(@png, nil, nil);
  4876. raise EglBitmapException.Create('LoadPng - couldn''t create info struct.');
  4877. end;
  4878. // set read callback
  4879. png_set_read_fn(png, aStream, glBitmap_libPNG_read_func);
  4880. // read informations
  4881. png_read_info(png, png_info);
  4882. // size
  4883. TempHeight := png_get_image_height(png, png_info);
  4884. TempWidth := png_get_image_width(png, png_info);
  4885. // format
  4886. case png_get_color_type(png, png_info) of
  4887. PNG_COLOR_TYPE_GRAY:
  4888. Format := tfLuminance8;
  4889. PNG_COLOR_TYPE_GRAY_ALPHA:
  4890. Format := tfLuminance8Alpha8;
  4891. PNG_COLOR_TYPE_RGB:
  4892. Format := tfRGB8;
  4893. PNG_COLOR_TYPE_RGB_ALPHA:
  4894. Format := tfRGBA8;
  4895. else
  4896. raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
  4897. end;
  4898. // cut upper 8 bit from 16 bit formats
  4899. if png_get_bit_depth(png, png_info) > 8 then
  4900. png_set_strip_16(png);
  4901. // expand bitdepth smaller than 8
  4902. if png_get_bit_depth(png, png_info) < 8 then
  4903. png_set_expand(png);
  4904. // allocating mem for scanlines
  4905. LineSize := png_get_rowbytes(png, png_info);
  4906. GetMem(png_data, TempHeight * LineSize);
  4907. try
  4908. SetLength(png_rows, TempHeight);
  4909. for Row := Low(png_rows) to High(png_rows) do begin
  4910. png_rows[Row] := png_data;
  4911. Inc(png_rows[Row], Row * LineSize);
  4912. end;
  4913. // read complete image into scanlines
  4914. png_read_image(png, @png_rows[0]);
  4915. // read end
  4916. png_read_end(png, png_info);
  4917. // destroy read struct
  4918. png_destroy_read_struct(@png, @png_info, nil);
  4919. SetLength(png_rows, 0);
  4920. // set new data
  4921. SetDataPointer(png_data, Format, TempWidth, TempHeight);
  4922. result := true;
  4923. except
  4924. FreeMem(png_data);
  4925. raise;
  4926. end;
  4927. end;
  4928. finally
  4929. quit_libPNG;
  4930. end;
  4931. end;
  4932. {$ELSEIF DEFINED(GLB_PNGIMAGE)}
  4933. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4934. function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
  4935. var
  4936. StreamPos: Int64;
  4937. Png: TPNGObject;
  4938. Header: String[8];
  4939. Row, Col, PixSize, LineSize: Integer;
  4940. NewImage, pSource, pDest, pAlpha: pByte;
  4941. PngFormat: TglBitmapFormat;
  4942. FormatDesc: TFormatDescriptor;
  4943. const
  4944. PngHeader: String[8] = #137#80#78#71#13#10#26#10;
  4945. begin
  4946. result := false;
  4947. StreamPos := aStream.Position;
  4948. aStream.Read(Header[0], SizeOf(Header));
  4949. aStream.Position := StreamPos;
  4950. {Test if the header matches}
  4951. if Header = PngHeader then begin
  4952. Png := TPNGObject.Create;
  4953. try
  4954. Png.LoadFromStream(aStream);
  4955. case Png.Header.ColorType of
  4956. COLOR_GRAYSCALE:
  4957. PngFormat := tfLuminance8;
  4958. COLOR_GRAYSCALEALPHA:
  4959. PngFormat := tfLuminance8Alpha8;
  4960. COLOR_RGB:
  4961. PngFormat := tfBGR8;
  4962. COLOR_RGBALPHA:
  4963. PngFormat := tfBGRA8;
  4964. else
  4965. raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
  4966. end;
  4967. FormatDesc := TFormatDescriptor.Get(PngFormat);
  4968. PixSize := Round(FormatDesc.PixelSize);
  4969. LineSize := FormatDesc.GetSize(Png.Header.Width, 1);
  4970. GetMem(NewImage, LineSize * Integer(Png.Header.Height));
  4971. try
  4972. pDest := NewImage;
  4973. case Png.Header.ColorType of
  4974. COLOR_RGB, COLOR_GRAYSCALE:
  4975. begin
  4976. for Row := 0 to Png.Height -1 do begin
  4977. Move (Png.Scanline[Row]^, pDest^, LineSize);
  4978. Inc(pDest, LineSize);
  4979. end;
  4980. end;
  4981. COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA:
  4982. begin
  4983. PixSize := PixSize -1;
  4984. for Row := 0 to Png.Height -1 do begin
  4985. pSource := Png.Scanline[Row];
  4986. pAlpha := pByte(Png.AlphaScanline[Row]);
  4987. for Col := 0 to Png.Width -1 do begin
  4988. Move (pSource^, pDest^, PixSize);
  4989. Inc(pSource, PixSize);
  4990. Inc(pDest, PixSize);
  4991. pDest^ := pAlpha^;
  4992. inc(pAlpha);
  4993. Inc(pDest);
  4994. end;
  4995. end;
  4996. end;
  4997. else
  4998. raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
  4999. end;
  5000. SetDataPointer(NewImage, PngFormat, Png.Header.Width, Png.Header.Height);
  5001. result := true;
  5002. except
  5003. FreeMem(NewImage);
  5004. raise;
  5005. end;
  5006. finally
  5007. Png.Free;
  5008. end;
  5009. end;
  5010. end;
  5011. {$IFEND}
  5012. {$ENDIF}
  5013. {$IFDEF GLB_SUPPORT_PNG_WRITE}
  5014. {$IFDEF GLB_LIB_PNG}
  5015. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5016. procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
  5017. begin
  5018. TStream(png_get_io_ptr(png)).Write(buffer^, size);
  5019. end;
  5020. {$ENDIF}
  5021. {$IF DEFINED(GLB_LIB_PNG)}
  5022. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5023. procedure TglBitmap.SavePNG(const aStream: TStream);
  5024. var
  5025. png: png_structp;
  5026. png_info: png_infop;
  5027. png_rows: array of pByte;
  5028. LineSize: Integer;
  5029. ColorType: Integer;
  5030. Row: Integer;
  5031. FormatDesc: TFormatDescriptor;
  5032. begin
  5033. if not (ftPNG in FormatGetSupportedFiles(Format)) then
  5034. raise EglBitmapUnsupportedFormat.Create(Format);
  5035. if not init_libPNG then
  5036. raise Exception.Create('unable to initialize libPNG.');
  5037. try
  5038. case Format of
  5039. tfAlpha8, tfLuminance8:
  5040. ColorType := PNG_COLOR_TYPE_GRAY;
  5041. tfLuminance8Alpha8:
  5042. ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
  5043. tfBGR8, tfRGB8:
  5044. ColorType := PNG_COLOR_TYPE_RGB;
  5045. tfBGRA8, tfRGBA8:
  5046. ColorType := PNG_COLOR_TYPE_RGBA;
  5047. else
  5048. raise EglBitmapUnsupportedFormat.Create(Format);
  5049. end;
  5050. FormatDesc := TFormatDescriptor.Get(Format);
  5051. LineSize := FormatDesc.GetSize(Width, 1);
  5052. // creating array for scanline
  5053. SetLength(png_rows, Height);
  5054. try
  5055. for Row := 0 to Height - 1 do begin
  5056. png_rows[Row] := Data;
  5057. Inc(png_rows[Row], Row * LineSize)
  5058. end;
  5059. // write struct
  5060. png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
  5061. if png = nil then
  5062. raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
  5063. // create png info
  5064. png_info := png_create_info_struct(png);
  5065. if png_info = nil then begin
  5066. png_destroy_write_struct(@png, nil);
  5067. raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
  5068. end;
  5069. // set read callback
  5070. png_set_write_fn(png, aStream, glBitmap_libPNG_write_func, nil);
  5071. // set compression
  5072. png_set_compression_level(png, 6);
  5073. if Format in [tfBGR8, tfBGRA8] then
  5074. png_set_bgr(png);
  5075. png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
  5076. png_write_info(png, png_info);
  5077. png_write_image(png, @png_rows[0]);
  5078. png_write_end(png, png_info);
  5079. png_destroy_write_struct(@png, @png_info);
  5080. finally
  5081. SetLength(png_rows, 0);
  5082. end;
  5083. finally
  5084. quit_libPNG;
  5085. end;
  5086. end;
  5087. {$ELSEIF DEFINED(GLB_PNGIMAGE)}
  5088. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5089. procedure TglBitmap.SavePNG(const aStream: TStream);
  5090. var
  5091. Png: TPNGObject;
  5092. pSource, pDest: pByte;
  5093. X, Y, PixSize: Integer;
  5094. ColorType: Cardinal;
  5095. Alpha: Boolean;
  5096. pTemp: pByte;
  5097. Temp: Byte;
  5098. begin
  5099. if not (ftPNG in FormatGetSupportedFiles (Format)) then
  5100. raise EglBitmapUnsupportedFormat.Create(Format);
  5101. case Format of
  5102. tfAlpha8, tfLuminance8: begin
  5103. ColorType := COLOR_GRAYSCALE;
  5104. PixSize := 1;
  5105. Alpha := false;
  5106. end;
  5107. tfLuminance8Alpha8: begin
  5108. ColorType := COLOR_GRAYSCALEALPHA;
  5109. PixSize := 1;
  5110. Alpha := true;
  5111. end;
  5112. tfBGR8, tfRGB8: begin
  5113. ColorType := COLOR_RGB;
  5114. PixSize := 3;
  5115. Alpha := false;
  5116. end;
  5117. tfBGRA8, tfRGBA8: begin
  5118. ColorType := COLOR_RGBALPHA;
  5119. PixSize := 3;
  5120. Alpha := true
  5121. end;
  5122. else
  5123. raise EglBitmapUnsupportedFormat.Create(Format);
  5124. end;
  5125. Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
  5126. try
  5127. // Copy ImageData
  5128. pSource := Data;
  5129. for Y := 0 to Height -1 do begin
  5130. pDest := png.ScanLine[Y];
  5131. for X := 0 to Width -1 do begin
  5132. Move(pSource^, pDest^, PixSize);
  5133. Inc(pDest, PixSize);
  5134. Inc(pSource, PixSize);
  5135. if Alpha then begin
  5136. png.AlphaScanline[Y]^[X] := pSource^;
  5137. Inc(pSource);
  5138. end;
  5139. end;
  5140. // convert RGB line to BGR
  5141. if Format in [tfRGB8, tfRGBA8] then begin
  5142. pTemp := png.ScanLine[Y];
  5143. for X := 0 to Width -1 do begin
  5144. Temp := pByteArray(pTemp)^[0];
  5145. pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
  5146. pByteArray(pTemp)^[2] := Temp;
  5147. Inc(pTemp, 3);
  5148. end;
  5149. end;
  5150. end;
  5151. // Save to Stream
  5152. Png.CompressionLevel := 6;
  5153. Png.SaveToStream(aStream);
  5154. finally
  5155. FreeAndNil(Png);
  5156. end;
  5157. end;
  5158. {$IFEND}
  5159. {$ENDIF}
  5160. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5161. //JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5162. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5163. {$IFDEF GLB_LIB_JPEG}
  5164. type
  5165. glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
  5166. glBitmap_libJPEG_source_mgr = record
  5167. pub: jpeg_source_mgr;
  5168. SrcStream: TStream;
  5169. SrcBuffer: array [1..4096] of byte;
  5170. end;
  5171. glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
  5172. glBitmap_libJPEG_dest_mgr = record
  5173. pub: jpeg_destination_mgr;
  5174. DestStream: TStream;
  5175. DestBuffer: array [1..4096] of byte;
  5176. end;
  5177. procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
  5178. begin
  5179. //DUMMY
  5180. end;
  5181. procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
  5182. begin
  5183. //DUMMY
  5184. end;
  5185. procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
  5186. begin
  5187. //DUMMY
  5188. end;
  5189. procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
  5190. begin
  5191. //DUMMY
  5192. end;
  5193. procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
  5194. begin
  5195. //DUMMY
  5196. end;
  5197. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5198. function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
  5199. var
  5200. src: glBitmap_libJPEG_source_mgr_ptr;
  5201. bytes: integer;
  5202. begin
  5203. src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
  5204. bytes := src^.SrcStream.Read(src^.SrcBuffer[1], 4096);
  5205. if (bytes <= 0) then begin
  5206. src^.SrcBuffer[1] := $FF;
  5207. src^.SrcBuffer[2] := JPEG_EOI;
  5208. bytes := 2;
  5209. end;
  5210. src^.pub.next_input_byte := @(src^.SrcBuffer[1]);
  5211. src^.pub.bytes_in_buffer := bytes;
  5212. result := true;
  5213. end;
  5214. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5215. procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
  5216. var
  5217. src: glBitmap_libJPEG_source_mgr_ptr;
  5218. begin
  5219. src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
  5220. if num_bytes > 0 then begin
  5221. // wanted byte isn't in buffer so set stream position and read buffer
  5222. if num_bytes > src^.pub.bytes_in_buffer then begin
  5223. src^.SrcStream.Position := src^.SrcStream.Position + num_bytes - src^.pub.bytes_in_buffer;
  5224. src^.pub.fill_input_buffer(cinfo);
  5225. end else begin
  5226. // wanted byte is in buffer so only skip
  5227. inc(src^.pub.next_input_byte, num_bytes);
  5228. dec(src^.pub.bytes_in_buffer, num_bytes);
  5229. end;
  5230. end;
  5231. end;
  5232. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5233. function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
  5234. var
  5235. dest: glBitmap_libJPEG_dest_mgr_ptr;
  5236. begin
  5237. dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
  5238. if dest^.pub.free_in_buffer < Cardinal(Length(dest^.DestBuffer)) then begin
  5239. // write complete buffer
  5240. dest^.DestStream.Write(dest^.DestBuffer[1], SizeOf(dest^.DestBuffer));
  5241. // reset buffer
  5242. dest^.pub.next_output_byte := @dest^.DestBuffer[1];
  5243. dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
  5244. end;
  5245. result := true;
  5246. end;
  5247. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5248. procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
  5249. var
  5250. Idx: Integer;
  5251. dest: glBitmap_libJPEG_dest_mgr_ptr;
  5252. begin
  5253. dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
  5254. for Idx := Low(dest^.DestBuffer) to High(dest^.DestBuffer) do begin
  5255. // check for endblock
  5256. if (Idx < High(dest^.DestBuffer)) and (dest^.DestBuffer[Idx] = $FF) and (dest^.DestBuffer[Idx +1] = JPEG_EOI) then begin
  5257. // write endblock
  5258. dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
  5259. // leave
  5260. break;
  5261. end else
  5262. dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
  5263. end;
  5264. end;
  5265. {$ENDIF}
  5266. {$IFDEF GLB_SUPPORT_JPEG_READ}
  5267. {$IF DEFINED(GLB_SDL_IMAGE)}
  5268. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5269. function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
  5270. var
  5271. Surface: PSDL_Surface;
  5272. RWops: PSDL_RWops;
  5273. begin
  5274. result := false;
  5275. RWops := glBitmapCreateRWops(aStream);
  5276. try
  5277. if IMG_isJPG(RWops) > 0 then begin
  5278. Surface := IMG_LoadJPG_RW(RWops);
  5279. try
  5280. AssignFromSurface(Surface);
  5281. result := true;
  5282. finally
  5283. SDL_FreeSurface(Surface);
  5284. end;
  5285. end;
  5286. finally
  5287. SDL_FreeRW(RWops);
  5288. end;
  5289. end;
  5290. {$ELSEIF DEFINED(GLB_LIB_JPEG)}
  5291. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5292. function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
  5293. var
  5294. StreamPos: Int64;
  5295. Temp: array[0..1]of Byte;
  5296. jpeg: jpeg_decompress_struct;
  5297. jpeg_err: jpeg_error_mgr;
  5298. IntFormat: TglBitmapFormat;
  5299. pImage: pByte;
  5300. TempHeight, TempWidth: Integer;
  5301. pTemp: pByte;
  5302. Row: Integer;
  5303. FormatDesc: TFormatDescriptor;
  5304. begin
  5305. result := false;
  5306. if not init_libJPEG then
  5307. raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
  5308. try
  5309. // reading first two bytes to test file and set cursor back to begin
  5310. StreamPos := aStream.Position;
  5311. aStream.Read({%H-}Temp[0], 2);
  5312. aStream.Position := StreamPos;
  5313. // if Bitmap then read file.
  5314. if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
  5315. FillChar(jpeg{%H-}, SizeOf(jpeg_decompress_struct), $00);
  5316. FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
  5317. // error managment
  5318. jpeg.err := jpeg_std_error(@jpeg_err);
  5319. jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
  5320. jpeg_err.output_message := glBitmap_libJPEG_output_message;
  5321. // decompression struct
  5322. jpeg_create_decompress(@jpeg);
  5323. // allocation space for streaming methods
  5324. jpeg.src := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_source_mgr));
  5325. // seeting up custom functions
  5326. with glBitmap_libJPEG_source_mgr_ptr(jpeg.src)^ do begin
  5327. pub.init_source := glBitmap_libJPEG_init_source;
  5328. pub.fill_input_buffer := glBitmap_libJPEG_fill_input_buffer;
  5329. pub.skip_input_data := glBitmap_libJPEG_skip_input_data;
  5330. pub.resync_to_restart := jpeg_resync_to_restart; // use default method
  5331. pub.term_source := glBitmap_libJPEG_term_source;
  5332. pub.bytes_in_buffer := 0; // forces fill_input_buffer on first read
  5333. pub.next_input_byte := nil; // until buffer loaded
  5334. SrcStream := aStream;
  5335. end;
  5336. // set global decoding state
  5337. jpeg.global_state := DSTATE_START;
  5338. // read header of jpeg
  5339. jpeg_read_header(@jpeg, false);
  5340. // setting output parameter
  5341. case jpeg.jpeg_color_space of
  5342. JCS_GRAYSCALE:
  5343. begin
  5344. jpeg.out_color_space := JCS_GRAYSCALE;
  5345. IntFormat := tfLuminance8;
  5346. end;
  5347. else
  5348. jpeg.out_color_space := JCS_RGB;
  5349. IntFormat := tfRGB8;
  5350. end;
  5351. // reading image
  5352. jpeg_start_decompress(@jpeg);
  5353. TempHeight := jpeg.output_height;
  5354. TempWidth := jpeg.output_width;
  5355. FormatDesc := TFormatDescriptor.Get(IntFormat);
  5356. // creating new image
  5357. GetMem(pImage, FormatDesc.GetSize(TempWidth, TempHeight));
  5358. try
  5359. pTemp := pImage;
  5360. for Row := 0 to TempHeight -1 do begin
  5361. jpeg_read_scanlines(@jpeg, @pTemp, 1);
  5362. Inc(pTemp, FormatDesc.GetSize(TempWidth, 1));
  5363. end;
  5364. // finish decompression
  5365. jpeg_finish_decompress(@jpeg);
  5366. // destroy decompression
  5367. jpeg_destroy_decompress(@jpeg);
  5368. SetDataPointer(pImage, IntFormat, TempWidth, TempHeight);
  5369. result := true;
  5370. except
  5371. FreeMem(pImage);
  5372. raise;
  5373. end;
  5374. end;
  5375. finally
  5376. quit_libJPEG;
  5377. end;
  5378. end;
  5379. {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
  5380. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5381. function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
  5382. var
  5383. bmp: TBitmap;
  5384. jpg: TJPEGImage;
  5385. StreamPos: Int64;
  5386. Temp: array[0..1]of Byte;
  5387. begin
  5388. result := false;
  5389. // reading first two bytes to test file and set cursor back to begin
  5390. StreamPos := aStream.Position;
  5391. aStream.Read(Temp[0], 2);
  5392. aStream.Position := StreamPos;
  5393. // if Bitmap then read file.
  5394. if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
  5395. bmp := TBitmap.Create;
  5396. try
  5397. jpg := TJPEGImage.Create;
  5398. try
  5399. jpg.LoadFromStream(aStream);
  5400. bmp.Assign(jpg);
  5401. result := AssignFromBitmap(bmp);
  5402. finally
  5403. jpg.Free;
  5404. end;
  5405. finally
  5406. bmp.Free;
  5407. end;
  5408. end;
  5409. end;
  5410. {$IFEND}
  5411. {$ENDIF}
  5412. {$IFDEF GLB_SUPPORT_JPEG_WRITE}
  5413. {$IF DEFINED(GLB_LIB_JPEG)}
  5414. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5415. procedure TglBitmap.SaveJPEG(const aStream: TStream);
  5416. var
  5417. jpeg: jpeg_compress_struct;
  5418. jpeg_err: jpeg_error_mgr;
  5419. Row: Integer;
  5420. pTemp, pTemp2: pByte;
  5421. procedure CopyRow(pDest, pSource: pByte);
  5422. var
  5423. X: Integer;
  5424. begin
  5425. for X := 0 to Width - 1 do begin
  5426. pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
  5427. pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
  5428. pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
  5429. Inc(pDest, 3);
  5430. Inc(pSource, 3);
  5431. end;
  5432. end;
  5433. begin
  5434. if not (ftJPEG in FormatGetSupportedFiles(Format)) then
  5435. raise EglBitmapUnsupportedFormat.Create(Format);
  5436. if not init_libJPEG then
  5437. raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
  5438. try
  5439. FillChar(jpeg{%H-}, SizeOf(jpeg_compress_struct), $00);
  5440. FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
  5441. // error managment
  5442. jpeg.err := jpeg_std_error(@jpeg_err);
  5443. jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
  5444. jpeg_err.output_message := glBitmap_libJPEG_output_message;
  5445. // compression struct
  5446. jpeg_create_compress(@jpeg);
  5447. // allocation space for streaming methods
  5448. jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
  5449. // seeting up custom functions
  5450. with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
  5451. pub.init_destination := glBitmap_libJPEG_init_destination;
  5452. pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
  5453. pub.term_destination := glBitmap_libJPEG_term_destination;
  5454. pub.next_output_byte := @DestBuffer[1];
  5455. pub.free_in_buffer := Length(DestBuffer);
  5456. DestStream := aStream;
  5457. end;
  5458. // very important state
  5459. jpeg.global_state := CSTATE_START;
  5460. jpeg.image_width := Width;
  5461. jpeg.image_height := Height;
  5462. case Format of
  5463. tfAlpha8, tfLuminance8: begin
  5464. jpeg.input_components := 1;
  5465. jpeg.in_color_space := JCS_GRAYSCALE;
  5466. end;
  5467. tfRGB8, tfBGR8: begin
  5468. jpeg.input_components := 3;
  5469. jpeg.in_color_space := JCS_RGB;
  5470. end;
  5471. end;
  5472. jpeg_set_defaults(@jpeg);
  5473. jpeg_set_quality(@jpeg, 95, true);
  5474. jpeg_start_compress(@jpeg, true);
  5475. pTemp := Data;
  5476. if Format = tfBGR8 then
  5477. GetMem(pTemp2, fRowSize)
  5478. else
  5479. pTemp2 := pTemp;
  5480. try
  5481. for Row := 0 to jpeg.image_height -1 do begin
  5482. // prepare row
  5483. if Format = tfBGR8 then
  5484. CopyRow(pTemp2, pTemp)
  5485. else
  5486. pTemp2 := pTemp;
  5487. // write row
  5488. jpeg_write_scanlines(@jpeg, @pTemp2, 1);
  5489. inc(pTemp, fRowSize);
  5490. end;
  5491. finally
  5492. // free memory
  5493. if Format = tfBGR8 then
  5494. FreeMem(pTemp2);
  5495. end;
  5496. jpeg_finish_compress(@jpeg);
  5497. jpeg_destroy_compress(@jpeg);
  5498. finally
  5499. quit_libJPEG;
  5500. end;
  5501. end;
  5502. {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
  5503. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5504. procedure TglBitmap.SaveJPEG(const aStream: TStream);
  5505. var
  5506. Bmp: TBitmap;
  5507. Jpg: TJPEGImage;
  5508. begin
  5509. if not (ftJPEG in FormatGetSupportedFiles(Format)) then
  5510. raise EglBitmapUnsupportedFormat.Create(Format);
  5511. Bmp := TBitmap.Create;
  5512. try
  5513. Jpg := TJPEGImage.Create;
  5514. try
  5515. AssignToBitmap(Bmp);
  5516. if (Format in [tfAlpha8, tfLuminance8]) then begin
  5517. Jpg.Grayscale := true;
  5518. Jpg.PixelFormat := jf8Bit;
  5519. end;
  5520. Jpg.Assign(Bmp);
  5521. Jpg.SaveToStream(aStream);
  5522. finally
  5523. FreeAndNil(Jpg);
  5524. end;
  5525. finally
  5526. FreeAndNil(Bmp);
  5527. end;
  5528. end;
  5529. {$IFEND}
  5530. {$ENDIF}
  5531. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5532. //BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5533. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5534. const
  5535. BMP_MAGIC = $4D42;
  5536. BMP_COMP_RGB = 0;
  5537. BMP_COMP_RLE8 = 1;
  5538. BMP_COMP_RLE4 = 2;
  5539. BMP_COMP_BITFIELDS = 3;
  5540. type
  5541. TBMPHeader = packed record
  5542. bfType: Word;
  5543. bfSize: Cardinal;
  5544. bfReserved1: Word;
  5545. bfReserved2: Word;
  5546. bfOffBits: Cardinal;
  5547. end;
  5548. TBMPInfo = packed record
  5549. biSize: Cardinal;
  5550. biWidth: Longint;
  5551. biHeight: Longint;
  5552. biPlanes: Word;
  5553. biBitCount: Word;
  5554. biCompression: Cardinal;
  5555. biSizeImage: Cardinal;
  5556. biXPelsPerMeter: Longint;
  5557. biYPelsPerMeter: Longint;
  5558. biClrUsed: Cardinal;
  5559. biClrImportant: Cardinal;
  5560. end;
  5561. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5562. function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
  5563. //////////////////////////////////////////////////////////////////////////////////////////////////
  5564. function ReadInfo(out aInfo: TBMPInfo; out aMask: TglBitmapColorRec): TglBitmapFormat;
  5565. begin
  5566. result := tfEmpty;
  5567. aStream.Read(aInfo{%H-}, SizeOf(aInfo));
  5568. FillChar(aMask{%H-}, SizeOf(aMask), 0);
  5569. //Read Compression
  5570. case aInfo.biCompression of
  5571. BMP_COMP_RLE4,
  5572. BMP_COMP_RLE8: begin
  5573. raise EglBitmapException.Create('RLE compression is not supported');
  5574. end;
  5575. BMP_COMP_BITFIELDS: begin
  5576. if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
  5577. aStream.Read(aMask.r, SizeOf(aMask.r));
  5578. aStream.Read(aMask.g, SizeOf(aMask.g));
  5579. aStream.Read(aMask.b, SizeOf(aMask.b));
  5580. aStream.Read(aMask.a, SizeOf(aMask.a));
  5581. end else
  5582. raise EglBitmapException.Create('Bitfields are only supported for 16bit and 32bit formats');
  5583. end;
  5584. end;
  5585. //get suitable format
  5586. case aInfo.biBitCount of
  5587. 8: result := tfLuminance8;
  5588. 16: result := tfBGR5;
  5589. 24: result := tfBGR8;
  5590. 32: result := tfBGRA8;
  5591. end;
  5592. end;
  5593. function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TbmpColorTableFormat;
  5594. var
  5595. i, c: Integer;
  5596. ColorTable: TbmpColorTable;
  5597. begin
  5598. result := nil;
  5599. if (aInfo.biBitCount >= 16) then
  5600. exit;
  5601. aFormat := tfLuminance8;
  5602. c := aInfo.biClrUsed;
  5603. if (c = 0) then
  5604. c := 1 shl aInfo.biBitCount;
  5605. SetLength(ColorTable, c);
  5606. for i := 0 to c-1 do begin
  5607. aStream.Read(ColorTable[i], SizeOf(TbmpColorTableEnty));
  5608. if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then
  5609. aFormat := tfRGB8;
  5610. end;
  5611. result := TbmpColorTableFormat.Create;
  5612. result.PixelSize := aInfo.biBitCount / 8;
  5613. result.ColorTable := ColorTable;
  5614. result.Range := glBitmapColorRec($FF, $FF, $FF, $00);
  5615. end;
  5616. //////////////////////////////////////////////////////////////////////////////////////////////////
  5617. function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapColorRec;
  5618. const aInfo: TBMPInfo): TbmpBitfieldFormat;
  5619. var
  5620. TmpFormat: TglBitmapFormat;
  5621. FormatDesc: TFormatDescriptor;
  5622. begin
  5623. result := nil;
  5624. if (aMask.r <> 0) or (aMask.g <> 0) or (aMask.b <> 0) or (aMask.a <> 0) then begin
  5625. for TmpFormat := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
  5626. FormatDesc := TFormatDescriptor.Get(TmpFormat);
  5627. if FormatDesc.MaskMatch(aMask.r, aMask.g, aMask.b, aMask.a) then begin
  5628. aFormat := FormatDesc.Format;
  5629. exit;
  5630. end;
  5631. end;
  5632. if (aMask.a = 0) and TFormatDescriptor.Get(aFormat).HasAlpha then
  5633. aFormat := TFormatDescriptor.Get(aFormat).WithoutAlpha;
  5634. if (aMask.a <> 0) and not TFormatDescriptor.Get(aFormat).HasAlpha then
  5635. aFormat := TFormatDescriptor.Get(aFormat).WithAlpha;
  5636. result := TbmpBitfieldFormat.Create;
  5637. result.PixelSize := aInfo.biBitCount / 8;
  5638. result.RedMask := aMask.r;
  5639. result.GreenMask := aMask.g;
  5640. result.BlueMask := aMask.b;
  5641. result.AlphaMask := aMask.a;
  5642. end;
  5643. end;
  5644. var
  5645. //simple types
  5646. StartPos: Int64;
  5647. ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
  5648. PaddingBuff: Cardinal;
  5649. LineBuf, ImageData, TmpData: PByte;
  5650. SourceMD, DestMD: Pointer;
  5651. BmpFormat: TglBitmapFormat;
  5652. //records
  5653. Mask: TglBitmapColorRec;
  5654. Header: TBMPHeader;
  5655. Info: TBMPInfo;
  5656. //classes
  5657. SpecialFormat: TFormatDescriptor;
  5658. FormatDesc: TFormatDescriptor;
  5659. //////////////////////////////////////////////////////////////////////////////////////////////////
  5660. procedure SpecialFormatReadLine(aData: PByte; aLineBuf: PByte);
  5661. var
  5662. i: Integer;
  5663. Pixel: TglBitmapPixelData;
  5664. begin
  5665. aStream.Read(aLineBuf^, rbLineSize);
  5666. SpecialFormat.PreparePixel(Pixel);
  5667. for i := 0 to Info.biWidth-1 do begin
  5668. SpecialFormat.Unmap(aLineBuf, Pixel, SourceMD);
  5669. glBitmapConvertPixel(Pixel, SpecialFormat, FormatDesc);
  5670. FormatDesc.Map(Pixel, aData, DestMD);
  5671. end;
  5672. end;
  5673. begin
  5674. result := false;
  5675. BmpFormat := tfEmpty;
  5676. SpecialFormat := nil;
  5677. LineBuf := nil;
  5678. SourceMD := nil;
  5679. DestMD := nil;
  5680. // Header
  5681. StartPos := aStream.Position;
  5682. aStream.Read(Header{%H-}, SizeOf(Header));
  5683. if Header.bfType = BMP_MAGIC then begin
  5684. try try
  5685. BmpFormat := ReadInfo(Info, Mask);
  5686. SpecialFormat := ReadColorTable(BmpFormat, Info);
  5687. if not Assigned(SpecialFormat) then
  5688. SpecialFormat := CheckBitfields(BmpFormat, Mask, Info);
  5689. aStream.Position := StartPos + Header.bfOffBits;
  5690. if (BmpFormat <> tfEmpty) then begin
  5691. FormatDesc := TFormatDescriptor.Get(BmpFormat);
  5692. rbLineSize := Round(Info.biWidth * Info.biBitCount / 8); //ReadBuffer LineSize
  5693. wbLineSize := Trunc(Info.biWidth * FormatDesc.PixelSize);
  5694. Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
  5695. //get Memory
  5696. DestMD := FormatDesc.CreateMappingData;
  5697. ImageSize := FormatDesc.GetSize(Info.biWidth, abs(Info.biHeight));
  5698. GetMem(ImageData, ImageSize);
  5699. if Assigned(SpecialFormat) then begin
  5700. GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
  5701. SourceMD := SpecialFormat.CreateMappingData;
  5702. end;
  5703. //read Data
  5704. try try
  5705. FillChar(ImageData^, ImageSize, $FF);
  5706. TmpData := ImageData;
  5707. if (Info.biHeight > 0) then
  5708. Inc(TmpData, wbLineSize * (Info.biHeight-1));
  5709. for i := 0 to Abs(Info.biHeight)-1 do begin
  5710. if Assigned(SpecialFormat) then
  5711. SpecialFormatReadLine(TmpData, LineBuf) //if is special format read and convert data
  5712. else
  5713. aStream.Read(TmpData^, wbLineSize); //else only read data
  5714. if (Info.biHeight > 0) then
  5715. dec(TmpData, wbLineSize)
  5716. else
  5717. inc(TmpData, wbLineSize);
  5718. aStream.Read(PaddingBuff{%H-}, Padding);
  5719. end;
  5720. SetDataPointer(ImageData, BmpFormat, Info.biWidth, abs(Info.biHeight));
  5721. result := true;
  5722. finally
  5723. if Assigned(LineBuf) then
  5724. FreeMem(LineBuf);
  5725. if Assigned(SourceMD) then
  5726. SpecialFormat.FreeMappingData(SourceMD);
  5727. FormatDesc.FreeMappingData(DestMD);
  5728. end;
  5729. except
  5730. FreeMem(ImageData);
  5731. raise;
  5732. end;
  5733. end else
  5734. raise EglBitmapException.Create('LoadBMP - No suitable format found');
  5735. except
  5736. aStream.Position := StartPos;
  5737. raise;
  5738. end;
  5739. finally
  5740. FreeAndNil(SpecialFormat);
  5741. end;
  5742. end
  5743. else aStream.Position := StartPos;
  5744. end;
  5745. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5746. procedure TglBitmap.SaveBMP(const aStream: TStream);
  5747. var
  5748. Header: TBMPHeader;
  5749. Info: TBMPInfo;
  5750. Converter: TbmpColorTableFormat;
  5751. FormatDesc: TFormatDescriptor;
  5752. SourceFD, DestFD: Pointer;
  5753. pData, srcData, dstData, ConvertBuffer: pByte;
  5754. Pixel: TglBitmapPixelData;
  5755. ImageSize, wbLineSize, rbLineSize, Padding, LineIdx, PixelIdx: Integer;
  5756. RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
  5757. PaddingBuff: Cardinal;
  5758. function GetLineWidth : Integer;
  5759. begin
  5760. result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
  5761. end;
  5762. begin
  5763. if not (ftBMP in FormatGetSupportedFiles(Format)) then
  5764. raise EglBitmapUnsupportedFormat.Create(Format);
  5765. Converter := nil;
  5766. FormatDesc := TFormatDescriptor.Get(Format);
  5767. ImageSize := FormatDesc.GetSize(Dimension);
  5768. FillChar(Header{%H-}, SizeOf(Header), 0);
  5769. Header.bfType := BMP_MAGIC;
  5770. Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
  5771. Header.bfReserved1 := 0;
  5772. Header.bfReserved2 := 0;
  5773. Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
  5774. FillChar(Info{%H-}, SizeOf(Info), 0);
  5775. Info.biSize := SizeOf(Info);
  5776. Info.biWidth := Width;
  5777. Info.biHeight := Height;
  5778. Info.biPlanes := 1;
  5779. Info.biCompression := BMP_COMP_RGB;
  5780. Info.biSizeImage := ImageSize;
  5781. try
  5782. case Format of
  5783. tfLuminance4: begin
  5784. Info.biBitCount := 4;
  5785. Header.bfSize := Header.bfSize + 16 * SizeOf(Cardinal);
  5786. Header.bfOffBits := Header.bfOffBits + 16 * SizeOf(Cardinal); //16 ColorTable entries
  5787. Converter := TbmpColorTableFormat.Create;
  5788. Converter.PixelSize := 0.5;
  5789. Converter.Format := Format;
  5790. Converter.Range := glBitmapColorRec($F, $F, $F, $0);
  5791. Converter.CreateColorTable;
  5792. end;
  5793. tfR3G3B2, tfLuminance8: begin
  5794. Info.biBitCount := 8;
  5795. Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
  5796. Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal); //256 ColorTable entries
  5797. Converter := TbmpColorTableFormat.Create;
  5798. Converter.PixelSize := 1;
  5799. Converter.Format := Format;
  5800. if (Format = tfR3G3B2) then begin
  5801. Converter.Range := glBitmapColorRec($7, $7, $3, $0);
  5802. Converter.Shift := glBitmapShiftRec(0, 3, 6, 0);
  5803. end else
  5804. Converter.Range := glBitmapColorRec($FF, $FF, $FF, $0);
  5805. Converter.CreateColorTable;
  5806. end;
  5807. tfRGB4, tfRGB5, tfR5G6B5, tfRGB5A1, tfRGBA4,
  5808. tfBGR4, tfBGR5, tfB5G6R5, tfBGR5A1, tfBGRA4: begin
  5809. Info.biBitCount := 16;
  5810. Info.biCompression := BMP_COMP_BITFIELDS;
  5811. end;
  5812. tfBGR8, tfRGB8: begin
  5813. Info.biBitCount := 24;
  5814. end;
  5815. tfRGB10, tfRGB10A2, tfRGBA8,
  5816. tfBGR10, tfBGR10A2, tfBGRA8: begin
  5817. Info.biBitCount := 32;
  5818. Info.biCompression := BMP_COMP_BITFIELDS;
  5819. end;
  5820. else
  5821. raise EglBitmapUnsupportedFormat.Create(Format);
  5822. end;
  5823. Info.biXPelsPerMeter := 2835;
  5824. Info.biYPelsPerMeter := 2835;
  5825. // prepare bitmasks
  5826. if Info.biCompression = BMP_COMP_BITFIELDS then begin
  5827. Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
  5828. Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
  5829. RedMask := FormatDesc.RedMask;
  5830. GreenMask := FormatDesc.GreenMask;
  5831. BlueMask := FormatDesc.BlueMask;
  5832. AlphaMask := FormatDesc.AlphaMask;
  5833. end;
  5834. // headers
  5835. aStream.Write(Header, SizeOf(Header));
  5836. aStream.Write(Info, SizeOf(Info));
  5837. // colortable
  5838. if Assigned(Converter) then
  5839. aStream.Write(Converter.ColorTable[0].b,
  5840. SizeOf(TbmpColorTableEnty) * Length(Converter.ColorTable));
  5841. // bitmasks
  5842. if Info.biCompression = BMP_COMP_BITFIELDS then begin
  5843. aStream.Write(RedMask, SizeOf(Cardinal));
  5844. aStream.Write(GreenMask, SizeOf(Cardinal));
  5845. aStream.Write(BlueMask, SizeOf(Cardinal));
  5846. aStream.Write(AlphaMask, SizeOf(Cardinal));
  5847. end;
  5848. // image data
  5849. rbLineSize := Round(Info.biWidth * FormatDesc.PixelSize);
  5850. wbLineSize := Round(Info.biWidth * Info.biBitCount / 8);
  5851. Padding := GetLineWidth - wbLineSize;
  5852. PaddingBuff := 0;
  5853. pData := Data;
  5854. inc(pData, (Height-1) * rbLineSize);
  5855. // prepare row buffer. But only for RGB because RGBA supports color masks
  5856. // so it's possible to change color within the image.
  5857. if Assigned(Converter) then begin
  5858. FormatDesc.PreparePixel(Pixel);
  5859. GetMem(ConvertBuffer, wbLineSize);
  5860. SourceFD := FormatDesc.CreateMappingData;
  5861. DestFD := Converter.CreateMappingData;
  5862. end else
  5863. ConvertBuffer := nil;
  5864. try
  5865. for LineIdx := 0 to Height - 1 do begin
  5866. // preparing row
  5867. if Assigned(Converter) then begin
  5868. srcData := pData;
  5869. dstData := ConvertBuffer;
  5870. for PixelIdx := 0 to Info.biWidth-1 do begin
  5871. FormatDesc.Unmap(srcData, Pixel, SourceFD);
  5872. glBitmapConvertPixel(Pixel, FormatDesc, Converter);
  5873. Converter.Map(Pixel, dstData, DestFD);
  5874. end;
  5875. aStream.Write(ConvertBuffer^, wbLineSize);
  5876. end else begin
  5877. aStream.Write(pData^, rbLineSize);
  5878. end;
  5879. dec(pData, rbLineSize);
  5880. if (Padding > 0) then
  5881. aStream.Write(PaddingBuff, Padding);
  5882. end;
  5883. finally
  5884. // destroy row buffer
  5885. if Assigned(ConvertBuffer) then begin
  5886. FormatDesc.FreeMappingData(SourceFD);
  5887. Converter.FreeMappingData(DestFD);
  5888. FreeMem(ConvertBuffer);
  5889. end;
  5890. end;
  5891. finally
  5892. if Assigned(Converter) then
  5893. Converter.Free;
  5894. end;
  5895. end;
  5896. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5897. //TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5898. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5899. type
  5900. TTGAHeader = packed record
  5901. ImageID: Byte;
  5902. ColorMapType: Byte;
  5903. ImageType: Byte;
  5904. //ColorMapSpec: Array[0..4] of Byte;
  5905. ColorMapStart: Word;
  5906. ColorMapLength: Word;
  5907. ColorMapEntrySize: Byte;
  5908. OrigX: Word;
  5909. OrigY: Word;
  5910. Width: Word;
  5911. Height: Word;
  5912. Bpp: Byte;
  5913. ImageDesc: Byte;
  5914. end;
  5915. const
  5916. TGA_UNCOMPRESSED_RGB = 2;
  5917. TGA_UNCOMPRESSED_GRAY = 3;
  5918. TGA_COMPRESSED_RGB = 10;
  5919. TGA_COMPRESSED_GRAY = 11;
  5920. TGA_NONE_COLOR_TABLE = 0;
  5921. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5922. function TglBitmap.LoadTGA(const aStream: TStream): Boolean;
  5923. var
  5924. Header: TTGAHeader;
  5925. ImageData: System.PByte;
  5926. StartPosition: Int64;
  5927. PixelSize, LineSize: Integer;
  5928. tgaFormat: TglBitmapFormat;
  5929. FormatDesc: TFormatDescriptor;
  5930. Counter: packed record
  5931. X, Y: packed record
  5932. low, high, dir: Integer;
  5933. end;
  5934. end;
  5935. const
  5936. CACHE_SIZE = $4000;
  5937. ////////////////////////////////////////////////////////////////////////////////////////
  5938. procedure ReadUncompressed;
  5939. var
  5940. i, j: Integer;
  5941. buf, tmp1, tmp2: System.PByte;
  5942. begin
  5943. buf := nil;
  5944. if (Counter.X.dir < 0) then
  5945. GetMem(buf, LineSize);
  5946. try
  5947. while (Counter.Y.low <> Counter.Y.high + counter.Y.dir) do begin
  5948. tmp1 := ImageData;
  5949. inc(tmp1, (Counter.Y.low * LineSize)); //pointer to LineStart
  5950. if (Counter.X.dir < 0) then begin //flip X
  5951. aStream.Read(buf^, LineSize);
  5952. tmp2 := buf;
  5953. inc(tmp2, LineSize - PixelSize); //pointer to last pixel in line
  5954. for i := 0 to Header.Width-1 do begin //for all pixels in line
  5955. for j := 0 to PixelSize-1 do begin //for all bytes in pixel
  5956. tmp1^ := tmp2^;
  5957. inc(tmp1);
  5958. inc(tmp2);
  5959. end;
  5960. dec(tmp2, 2*PixelSize); //move 2 backwards, because j-loop moved 1 forward
  5961. end;
  5962. end else
  5963. aStream.Read(tmp1^, LineSize);
  5964. inc(Counter.Y.low, Counter.Y.dir); //move to next line index
  5965. end;
  5966. finally
  5967. if Assigned(buf) then
  5968. FreeMem(buf);
  5969. end;
  5970. end;
  5971. ////////////////////////////////////////////////////////////////////////////////////////
  5972. procedure ReadCompressed;
  5973. /////////////////////////////////////////////////////////////////
  5974. var
  5975. TmpData: System.PByte;
  5976. LinePixelsRead: Integer;
  5977. procedure CheckLine;
  5978. begin
  5979. if (LinePixelsRead >= Header.Width) then begin
  5980. LinePixelsRead := 0;
  5981. inc(Counter.Y.low, Counter.Y.dir); //next line index
  5982. TmpData := ImageData;
  5983. inc(TmpData, Counter.Y.low * LineSize); //set line
  5984. if (Counter.X.dir < 0) then //if x flipped then
  5985. inc(TmpData, LineSize - PixelSize); //set last pixel
  5986. end;
  5987. end;
  5988. /////////////////////////////////////////////////////////////////
  5989. var
  5990. Cache: PByte;
  5991. CacheSize, CachePos: Integer;
  5992. procedure CachedRead(out Buffer; Count: Integer);
  5993. var
  5994. BytesRead: Integer;
  5995. begin
  5996. if (CachePos + Count > CacheSize) then begin
  5997. //if buffer overflow save non read bytes
  5998. BytesRead := 0;
  5999. if (CacheSize - CachePos > 0) then begin
  6000. BytesRead := CacheSize - CachePos;
  6001. Move(PByteArray(Cache)^[CachePos], Buffer{%H-}, BytesRead);
  6002. inc(CachePos, BytesRead);
  6003. end;
  6004. //load cache from file
  6005. CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
  6006. aStream.Read(Cache^, CacheSize);
  6007. CachePos := 0;
  6008. //read rest of requested bytes
  6009. if (Count - BytesRead > 0) then begin
  6010. Move(PByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
  6011. inc(CachePos, Count - BytesRead);
  6012. end;
  6013. end else begin
  6014. //if no buffer overflow just read the data
  6015. Move(PByteArray(Cache)^[CachePos], Buffer, Count);
  6016. inc(CachePos, Count);
  6017. end;
  6018. end;
  6019. procedure PixelToBuffer(const aData: PByte; var aBuffer: PByte);
  6020. begin
  6021. case PixelSize of
  6022. 1: begin
  6023. aBuffer^ := aData^;
  6024. inc(aBuffer, Counter.X.dir);
  6025. end;
  6026. 2: begin
  6027. PWord(aBuffer)^ := PWord(aData)^;
  6028. inc(aBuffer, 2 * Counter.X.dir);
  6029. end;
  6030. 3: begin
  6031. PByteArray(aBuffer)^[0] := PByteArray(aData)^[0];
  6032. PByteArray(aBuffer)^[1] := PByteArray(aData)^[1];
  6033. PByteArray(aBuffer)^[2] := PByteArray(aData)^[2];
  6034. inc(aBuffer, 3 * Counter.X.dir);
  6035. end;
  6036. 4: begin
  6037. PCardinal(aBuffer)^ := PCardinal(aData)^;
  6038. inc(aBuffer, 4 * Counter.X.dir);
  6039. end;
  6040. end;
  6041. end;
  6042. var
  6043. TotalPixelsToRead, TotalPixelsRead: Integer;
  6044. Temp: Byte;
  6045. buf: array [0..3] of Byte; //1 pixel is max 32bit long
  6046. PixelRepeat: Boolean;
  6047. PixelsToRead, PixelCount: Integer;
  6048. begin
  6049. CacheSize := 0;
  6050. CachePos := 0;
  6051. TotalPixelsToRead := Header.Width * Header.Height;
  6052. TotalPixelsRead := 0;
  6053. LinePixelsRead := 0;
  6054. GetMem(Cache, CACHE_SIZE);
  6055. try
  6056. TmpData := ImageData;
  6057. inc(TmpData, Counter.Y.low * LineSize); //set line
  6058. if (Counter.X.dir < 0) then //if x flipped then
  6059. inc(TmpData, LineSize - PixelSize); //set last pixel
  6060. repeat
  6061. //read CommandByte
  6062. CachedRead(Temp, 1);
  6063. PixelRepeat := (Temp and $80) > 0;
  6064. PixelsToRead := (Temp and $7F) + 1;
  6065. inc(TotalPixelsRead, PixelsToRead);
  6066. if PixelRepeat then
  6067. CachedRead(buf[0], PixelSize);
  6068. while (PixelsToRead > 0) do begin
  6069. CheckLine;
  6070. PixelCount := Min(Header.Width - LinePixelsRead, PixelsToRead); //max read to EOL or EOF
  6071. while (PixelCount > 0) do begin
  6072. if not PixelRepeat then
  6073. CachedRead(buf[0], PixelSize);
  6074. PixelToBuffer(@buf[0], TmpData);
  6075. inc(LinePixelsRead);
  6076. dec(PixelsToRead);
  6077. dec(PixelCount);
  6078. end;
  6079. end;
  6080. until (TotalPixelsRead >= TotalPixelsToRead);
  6081. finally
  6082. FreeMem(Cache);
  6083. end;
  6084. end;
  6085. function IsGrayFormat: Boolean;
  6086. begin
  6087. result := Header.ImageType in [TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_GRAY];
  6088. end;
  6089. begin
  6090. result := false;
  6091. // reading header to test file and set cursor back to begin
  6092. StartPosition := aStream.Position;
  6093. aStream.Read(Header{%H-}, SizeOf(Header));
  6094. // no colormapped files
  6095. if (Header.ColorMapType = TGA_NONE_COLOR_TABLE) and (Header.ImageType in [
  6096. TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY]) then
  6097. begin
  6098. try
  6099. if Header.ImageID <> 0 then // skip image ID
  6100. aStream.Position := aStream.Position + Header.ImageID;
  6101. tgaFormat := tfEmpty;
  6102. case Header.Bpp of
  6103. 8: if IsGrayFormat then case (Header.ImageDesc and $F) of
  6104. 0: tgaFormat := tfLuminance8;
  6105. 8: tgaFormat := tfAlpha8;
  6106. end;
  6107. 16: if IsGrayFormat then case (Header.ImageDesc and $F) of
  6108. 0: tgaFormat := tfLuminance16;
  6109. 8: tgaFormat := tfLuminance8Alpha8;
  6110. end else case (Header.ImageDesc and $F) of
  6111. 0: tgaFormat := tfBGR5;
  6112. 1: tgaFormat := tfBGR5A1;
  6113. 4: tgaFormat := tfBGRA4;
  6114. end;
  6115. 24: if not IsGrayFormat then case (Header.ImageDesc and $F) of
  6116. 0: tgaFormat := tfBGR8;
  6117. end;
  6118. 32: if not IsGrayFormat then case (Header.ImageDesc and $F) of
  6119. 2: tgaFormat := tfBGR10A2;
  6120. 8: tgaFormat := tfBGRA8;
  6121. end;
  6122. end;
  6123. if (tgaFormat = tfEmpty) then
  6124. raise EglBitmapException.Create('LoadTga - unsupported format');
  6125. FormatDesc := TFormatDescriptor.Get(tgaFormat);
  6126. PixelSize := FormatDesc.GetSize(1, 1);
  6127. LineSize := FormatDesc.GetSize(Header.Width, 1);
  6128. GetMem(ImageData, LineSize * Header.Height);
  6129. try
  6130. //column direction
  6131. if ((Header.ImageDesc and (1 shl 4)) > 0) then begin
  6132. Counter.X.low := Header.Height-1;;
  6133. Counter.X.high := 0;
  6134. Counter.X.dir := -1;
  6135. end else begin
  6136. Counter.X.low := 0;
  6137. Counter.X.high := Header.Height-1;
  6138. Counter.X.dir := 1;
  6139. end;
  6140. // Row direction
  6141. if ((Header.ImageDesc and (1 shl 5)) > 0) then begin
  6142. Counter.Y.low := 0;
  6143. Counter.Y.high := Header.Height-1;
  6144. Counter.Y.dir := 1;
  6145. end else begin
  6146. Counter.Y.low := Header.Height-1;;
  6147. Counter.Y.high := 0;
  6148. Counter.Y.dir := -1;
  6149. end;
  6150. // Read Image
  6151. case Header.ImageType of
  6152. TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY:
  6153. ReadUncompressed;
  6154. TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY:
  6155. ReadCompressed;
  6156. end;
  6157. SetDataPointer(ImageData, tgaFormat, Header.Width, Header.Height);
  6158. result := true;
  6159. except
  6160. FreeMem(ImageData);
  6161. raise;
  6162. end;
  6163. finally
  6164. aStream.Position := StartPosition;
  6165. end;
  6166. end
  6167. else aStream.Position := StartPosition;
  6168. end;
  6169. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6170. procedure TglBitmap.SaveTGA(const aStream: TStream);
  6171. var
  6172. Header: TTGAHeader;
  6173. LineSize, Size, x, y: Integer;
  6174. Pixel: TglBitmapPixelData;
  6175. LineBuf, SourceData, DestData: PByte;
  6176. SourceMD, DestMD: Pointer;
  6177. FormatDesc: TFormatDescriptor;
  6178. Converter: TFormatDescriptor;
  6179. begin
  6180. if not (ftTGA in FormatGetSupportedFiles(Format)) then
  6181. raise EglBitmapUnsupportedFormat.Create(Format);
  6182. //prepare header
  6183. FillChar(Header{%H-}, SizeOf(Header), 0);
  6184. //set ImageType
  6185. if (Format in [tfLuminance8, tfLuminance6Alpha2, tfLuminance4Alpha4, tfAlpha8,
  6186. tfLuminance16, tfLuminance12Alpha4, tfLuminance8Alpha8]) then
  6187. Header.ImageType := TGA_UNCOMPRESSED_GRAY
  6188. else
  6189. Header.ImageType := TGA_UNCOMPRESSED_RGB;
  6190. //set BitsPerPixel
  6191. if (Format in [tfLuminance8, tfLuminance6Alpha2, tfLuminance4Alpha4, tfAlpha8]) then
  6192. Header.Bpp := 8
  6193. else if (Format in [tfLuminance16, tfLuminance12Alpha4, tfLuminance8Alpha8,
  6194. tfRGB5, tfBGR5, tfRGB5A1, tfBGR5A1, tfRGBA4, tfBGRA4]) then
  6195. Header.Bpp := 16
  6196. else if (Format in [tfBGR8, tfRGB8]) then
  6197. Header.Bpp := 24
  6198. else
  6199. Header.Bpp := 32;
  6200. //set AlphaBitCount
  6201. case Format of
  6202. tfRGB5A1, tfBGR5A1:
  6203. Header.ImageDesc := 1 and $F;
  6204. tfRGB10A2, tfBGR10A2:
  6205. Header.ImageDesc := 2 and $F;
  6206. tfRGBA4, tfBGRA4:
  6207. Header.ImageDesc := 4 and $F;
  6208. tfAlpha8, tfLuminance8Alpha8, tfRGBA8, tfBGRA8:
  6209. Header.ImageDesc := 8 and $F;
  6210. end;
  6211. Header.Width := Width;
  6212. Header.Height := Height;
  6213. Header.ImageDesc := Header.ImageDesc or $20; //flip y
  6214. aStream.Write(Header, SizeOf(Header));
  6215. // convert RGB(A) to BGR(A)
  6216. Converter := nil;
  6217. FormatDesc := TFormatDescriptor.Get(Format);
  6218. Size := FormatDesc.GetSize(Dimension);
  6219. if Format in [tfRGB5, tfRGB5A1, tfRGBA4, tfRGB8, tfRGB10A2, tfRGBA8] then begin
  6220. if (FormatDesc.RGBInverted = tfEmpty) then
  6221. raise EglBitmapException.Create('inverted RGB format is empty');
  6222. Converter := TFormatDescriptor.Get(FormatDesc.RGBInverted);
  6223. if not glBitmapColorRecCmp(Converter.Range, FormatDesc.Range) or
  6224. (Converter.PixelSize <> FormatDesc.PixelSize) then
  6225. raise EglBitmapException.Create('invalid inverted RGB format');
  6226. end;
  6227. if Assigned(Converter) then begin
  6228. LineSize := FormatDesc.GetSize(Width, 1);
  6229. GetMem(LineBuf, LineSize);
  6230. SourceMD := FormatDesc.CreateMappingData;
  6231. DestMD := Converter.CreateMappingData;
  6232. try
  6233. SourceData := Data;
  6234. for y := 0 to Height-1 do begin
  6235. DestData := LineBuf;
  6236. for x := 0 to Width-1 do begin
  6237. FormatDesc.Unmap(SourceData, Pixel, SourceMD);
  6238. Converter.Map(Pixel, DestData, DestMD);
  6239. end;
  6240. aStream.Write(LineBuf^, LineSize);
  6241. end;
  6242. finally
  6243. FreeMem(LineBuf);
  6244. FormatDesc.FreeMappingData(SourceMD);
  6245. FormatDesc.FreeMappingData(DestMD);
  6246. end;
  6247. end else
  6248. aStream.Write(Data^, Size);
  6249. end;
  6250. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6251. //DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6252. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6253. const
  6254. DDS_MAGIC: Cardinal = $20534444;
  6255. // DDS_header.dwFlags
  6256. DDSD_CAPS = $00000001;
  6257. DDSD_HEIGHT = $00000002;
  6258. DDSD_WIDTH = $00000004;
  6259. DDSD_PIXELFORMAT = $00001000;
  6260. // DDS_header.sPixelFormat.dwFlags
  6261. DDPF_ALPHAPIXELS = $00000001;
  6262. DDPF_ALPHA = $00000002;
  6263. DDPF_FOURCC = $00000004;
  6264. DDPF_RGB = $00000040;
  6265. DDPF_LUMINANCE = $00020000;
  6266. // DDS_header.sCaps.dwCaps1
  6267. DDSCAPS_TEXTURE = $00001000;
  6268. // DDS_header.sCaps.dwCaps2
  6269. DDSCAPS2_CUBEMAP = $00000200;
  6270. D3DFMT_DXT1 = $31545844;
  6271. D3DFMT_DXT3 = $33545844;
  6272. D3DFMT_DXT5 = $35545844;
  6273. type
  6274. TDDSPixelFormat = packed record
  6275. dwSize: Cardinal;
  6276. dwFlags: Cardinal;
  6277. dwFourCC: Cardinal;
  6278. dwRGBBitCount: Cardinal;
  6279. dwRBitMask: Cardinal;
  6280. dwGBitMask: Cardinal;
  6281. dwBBitMask: Cardinal;
  6282. dwABitMask: Cardinal;
  6283. end;
  6284. TDDSCaps = packed record
  6285. dwCaps1: Cardinal;
  6286. dwCaps2: Cardinal;
  6287. dwDDSX: Cardinal;
  6288. dwReserved: Cardinal;
  6289. end;
  6290. TDDSHeader = packed record
  6291. dwSize: Cardinal;
  6292. dwFlags: Cardinal;
  6293. dwHeight: Cardinal;
  6294. dwWidth: Cardinal;
  6295. dwPitchOrLinearSize: Cardinal;
  6296. dwDepth: Cardinal;
  6297. dwMipMapCount: Cardinal;
  6298. dwReserved: array[0..10] of Cardinal;
  6299. PixelFormat: TDDSPixelFormat;
  6300. Caps: TDDSCaps;
  6301. dwReserved2: Cardinal;
  6302. end;
  6303. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6304. function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
  6305. var
  6306. Header: TDDSHeader;
  6307. Converter: TbmpBitfieldFormat;
  6308. function GetDDSFormat: TglBitmapFormat;
  6309. var
  6310. fd: TFormatDescriptor;
  6311. i: Integer;
  6312. Range: TglBitmapColorRec;
  6313. match: Boolean;
  6314. begin
  6315. result := tfEmpty;
  6316. with Header.PixelFormat do begin
  6317. // Compresses
  6318. if ((dwFlags and DDPF_FOURCC) > 0) then begin
  6319. case Header.PixelFormat.dwFourCC of
  6320. D3DFMT_DXT1: result := tfS3tcDtx1RGBA;
  6321. D3DFMT_DXT3: result := tfS3tcDtx3RGBA;
  6322. D3DFMT_DXT5: result := tfS3tcDtx5RGBA;
  6323. end;
  6324. end else if ((Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0) then begin
  6325. //find matching format
  6326. for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
  6327. fd := TFormatDescriptor.Get(result);
  6328. if fd.MaskMatch(dwRBitMask, dwGBitMask, dwBBitMask, dwABitMask) and
  6329. (8 * fd.PixelSize = dwRGBBitCount) then
  6330. exit;
  6331. end;
  6332. //find format with same Range
  6333. Range.r := dwRBitMask;
  6334. Range.g := dwGBitMask;
  6335. Range.b := dwBBitMask;
  6336. Range.a := dwABitMask;
  6337. for i := 0 to 3 do begin
  6338. while ((Range.arr[i] and 1) = 0) and (Range.arr[i] > 0) do
  6339. Range.arr[i] := Range.arr[i] shr 1;
  6340. end;
  6341. for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
  6342. fd := TFormatDescriptor.Get(result);
  6343. match := true;
  6344. for i := 0 to 3 do
  6345. if (fd.Range.arr[i] <> Range.arr[i]) then begin
  6346. match := false;
  6347. break;
  6348. end;
  6349. if match then
  6350. break;
  6351. end;
  6352. //no format with same range found -> use default
  6353. if (result = tfEmpty) then begin
  6354. if (dwABitMask > 0) then
  6355. result := tfBGRA8
  6356. else
  6357. result := tfBGR8;
  6358. end;
  6359. Converter := TbmpBitfieldFormat.Create;
  6360. Converter.RedMask := dwRBitMask;
  6361. Converter.GreenMask := dwGBitMask;
  6362. Converter.BlueMask := dwBBitMask;
  6363. Converter.AlphaMask := dwABitMask;
  6364. Converter.PixelSize := dwRGBBitCount / 8;
  6365. end;
  6366. end;
  6367. end;
  6368. var
  6369. StreamPos: Int64;
  6370. x, y, LineSize, RowSize, Magic: Cardinal;
  6371. NewImage, TmpData, RowData, SrcData: System.PByte;
  6372. SourceMD, DestMD: Pointer;
  6373. Pixel: TglBitmapPixelData;
  6374. ddsFormat: TglBitmapFormat;
  6375. FormatDesc: TFormatDescriptor;
  6376. begin
  6377. result := false;
  6378. Converter := nil;
  6379. StreamPos := aStream.Position;
  6380. // Magic
  6381. aStream.Read(Magic{%H-}, sizeof(Magic));
  6382. if (Magic <> DDS_MAGIC) then begin
  6383. aStream.Position := StreamPos;
  6384. exit;
  6385. end;
  6386. //Header
  6387. aStream.Read(Header{%H-}, sizeof(Header));
  6388. if (Header.dwSize <> SizeOf(Header)) or
  6389. ((Header.dwFlags and (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) <>
  6390. (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) then
  6391. begin
  6392. aStream.Position := StreamPos;
  6393. exit;
  6394. end;
  6395. if ((Header.Caps.dwCaps1 and DDSCAPS2_CUBEMAP) > 0) then
  6396. raise EglBitmapException.Create('LoadDDS - CubeMaps are not supported');
  6397. ddsFormat := GetDDSFormat;
  6398. try
  6399. if (ddsFormat = tfEmpty) then
  6400. raise EglBitmapException.Create('LoadDDS - unsupported Pixelformat found.');
  6401. FormatDesc := TFormatDescriptor.Get(ddsFormat);
  6402. LineSize := Trunc(Header.dwWidth * FormatDesc.PixelSize);
  6403. GetMem(NewImage, Header.dwHeight * LineSize);
  6404. try
  6405. TmpData := NewImage;
  6406. //Converter needed
  6407. if Assigned(Converter) then begin
  6408. RowSize := Round(Header.dwWidth * Header.PixelFormat.dwRGBBitCount / 8);
  6409. GetMem(RowData, RowSize);
  6410. SourceMD := Converter.CreateMappingData;
  6411. DestMD := FormatDesc.CreateMappingData;
  6412. try
  6413. for y := 0 to Header.dwHeight-1 do begin
  6414. TmpData := NewImage;
  6415. inc(TmpData, y * LineSize);
  6416. SrcData := RowData;
  6417. aStream.Read(SrcData^, RowSize);
  6418. for x := 0 to Header.dwWidth-1 do begin
  6419. Converter.Unmap(SrcData, Pixel, SourceMD);
  6420. glBitmapConvertPixel(Pixel, Converter, FormatDesc);
  6421. FormatDesc.Map(Pixel, TmpData, DestMD);
  6422. end;
  6423. end;
  6424. finally
  6425. Converter.FreeMappingData(SourceMD);
  6426. FormatDesc.FreeMappingData(DestMD);
  6427. FreeMem(RowData);
  6428. end;
  6429. end else
  6430. // Compressed
  6431. if ((Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0) then begin
  6432. RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
  6433. for Y := 0 to Header.dwHeight-1 do begin
  6434. aStream.Read(TmpData^, RowSize);
  6435. Inc(TmpData, LineSize);
  6436. end;
  6437. end else
  6438. // Uncompressed
  6439. if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0 then begin
  6440. RowSize := (Header.PixelFormat.dwRGBBitCount * Header.dwWidth) shr 3;
  6441. for Y := 0 to Header.dwHeight-1 do begin
  6442. aStream.Read(TmpData^, RowSize);
  6443. Inc(TmpData, LineSize);
  6444. end;
  6445. end else
  6446. raise EglBitmapException.Create('LoadDDS - unsupported Pixelformat found.');
  6447. SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight);
  6448. result := true;
  6449. except
  6450. FreeMem(NewImage);
  6451. raise;
  6452. end;
  6453. finally
  6454. FreeAndNil(Converter);
  6455. end;
  6456. end;
  6457. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6458. procedure TglBitmap.SaveDDS(const aStream: TStream);
  6459. var
  6460. Header: TDDSHeader;
  6461. FormatDesc: TFormatDescriptor;
  6462. begin
  6463. if not (ftDDS in FormatGetSupportedFiles(Format)) then
  6464. raise EglBitmapUnsupportedFormat.Create(Format);
  6465. FormatDesc := TFormatDescriptor.Get(Format);
  6466. // Generell
  6467. FillChar(Header{%H-}, SizeOf(Header), 0);
  6468. Header.dwSize := SizeOf(Header);
  6469. Header.dwFlags := DDSD_WIDTH or DDSD_HEIGHT or DDSD_CAPS or DDSD_PIXELFORMAT;
  6470. Header.dwWidth := Max(1, Width);
  6471. Header.dwHeight := Max(1, Height);
  6472. // Caps
  6473. Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
  6474. // Pixelformat
  6475. Header.PixelFormat.dwSize := sizeof(Header);
  6476. if (FormatDesc.IsCompressed) then begin
  6477. Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_FOURCC;
  6478. case Format of
  6479. tfS3tcDtx1RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT1;
  6480. tfS3tcDtx3RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT3;
  6481. tfS3tcDtx5RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT5;
  6482. end;
  6483. end else if (Format in [tfAlpha8, tfAlpha16]) then begin
  6484. Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHA;
  6485. Header.PixelFormat.dwRGBBitCount := Round(FormatDesc.PixelSize * 8);
  6486. Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
  6487. end else if (FormatDesc.RedMask = FormatDesc.GreenMask) and (FormatDesc.GreenMask = FormatDesc.BlueMask) then begin
  6488. Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_LUMINANCE;
  6489. Header.PixelFormat.dwRGBBitCount := Round(FormatDesc.PixelSize * 8);
  6490. Header.PixelFormat.dwRBitMask := FormatDesc.RedMask;
  6491. Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
  6492. end else begin
  6493. Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_RGB;
  6494. Header.PixelFormat.dwRGBBitCount := Round(FormatDesc.PixelSize * 8);
  6495. Header.PixelFormat.dwRBitMask := FormatDesc.RedMask;
  6496. Header.PixelFormat.dwGBitMask := FormatDesc.GreenMask;
  6497. Header.PixelFormat.dwBBitMask := FormatDesc.BlueMask;
  6498. Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
  6499. end;
  6500. if (FormatDesc.HasAlpha) then
  6501. Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
  6502. aStream.Write(DDS_MAGIC, sizeof(DDS_MAGIC));
  6503. aStream.Write(Header, SizeOf(Header));
  6504. aStream.Write(Data^, FormatDesc.GetSize(Dimension));
  6505. end;
  6506. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6507. //TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6508. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6509. function TglBitmap2D.GetScanline(const aIndex: Integer): Pointer;
  6510. begin
  6511. if (aIndex >= Low(fLines)) and (aIndex <= High(fLines)) then
  6512. result := fLines[aIndex]
  6513. else
  6514. result := nil;
  6515. end;
  6516. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6517. procedure TglBitmap2D.SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
  6518. const aWidth: Integer; const aHeight: Integer);
  6519. var
  6520. Idx, LineWidth: Integer;
  6521. begin
  6522. inherited SetDataPointer(aData, aFormat, aWidth, aHeight);
  6523. if not TFormatDescriptor.Get(aFormat).IsCompressed then begin
  6524. // Assigning Data
  6525. if Assigned(Data) then begin
  6526. SetLength(fLines, GetHeight);
  6527. LineWidth := Trunc(GetWidth * TFormatDescriptor.Get(Format).PixelSize);
  6528. for Idx := 0 to GetHeight-1 do begin
  6529. fLines[Idx] := Data;
  6530. Inc(fLines[Idx], Idx * LineWidth);
  6531. end;
  6532. end
  6533. else SetLength(fLines, 0);
  6534. end else begin
  6535. SetLength(fLines, 0);
  6536. end;
  6537. end;
  6538. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6539. procedure TglBitmap2D.UploadData(const aTarget: Cardinal; const aBuildWithGlu: Boolean);
  6540. var
  6541. FormatDesc: TFormatDescriptor;
  6542. begin
  6543. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  6544. FormatDesc := TFormatDescriptor.Get(Format);
  6545. if FormatDesc.IsCompressed then begin
  6546. glCompressedTexImage2D(Target, 0, FormatDesc.glInternalFormat, Width, Height, 0, FormatDesc.GetSize(fDimension), Data)
  6547. end else if aBuildWithGlu then begin
  6548. gluBuild2DMipmaps(aTarget, FormatDesc.Components, Width, Height,
  6549. FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
  6550. end else begin
  6551. glTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0,
  6552. FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
  6553. end;
  6554. // Freigeben
  6555. if (FreeDataAfterGenTexture) then
  6556. FreeData;
  6557. end;
  6558. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6559. procedure TglBitmap2D.AfterConstruction;
  6560. begin
  6561. inherited;
  6562. Target := GL_TEXTURE_2D;
  6563. end;
  6564. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6565. procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
  6566. var
  6567. Temp: pByte;
  6568. Size, w, h: Integer;
  6569. FormatDesc: TFormatDescriptor;
  6570. begin
  6571. FormatDesc := TFormatDescriptor.Get(Format);
  6572. if FormatDesc.IsCompressed then
  6573. raise EglBitmapUnsupportedFormat.Create(Format);
  6574. w := aRight - aLeft;
  6575. h := aBottom - aTop;
  6576. Size := FormatDesc.GetSize(w, h);
  6577. GetMem(Temp, Size);
  6578. try
  6579. glPixelStorei(GL_PACK_ALIGNMENT, 1);
  6580. glReadPixels(aLeft, aTop, w, h, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
  6581. SetDataPointer(Temp, Format, w, h);
  6582. FlipVert;
  6583. except
  6584. FreeMem(Temp);
  6585. raise;
  6586. end;
  6587. end;
  6588. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6589. procedure TglBitmap2D.GetDataFromTexture;
  6590. var
  6591. Temp: PByte;
  6592. TempWidth, TempHeight: Integer;
  6593. TempIntFormat: Cardinal;
  6594. IntFormat, f: TglBitmapFormat;
  6595. FormatDesc: TFormatDescriptor;
  6596. begin
  6597. Bind;
  6598. // Request Data
  6599. glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
  6600. glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
  6601. glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
  6602. IntFormat := tfEmpty;
  6603. for f := Low(TglBitmapFormat) to High(TglBitmapFormat) do begin
  6604. FormatDesc := TFormatDescriptor.Get(f);
  6605. if (FormatDesc.glInternalFormat = TempIntFormat) then begin
  6606. IntFormat := FormatDesc.Format;
  6607. break;
  6608. end;
  6609. end;
  6610. // Getting data from OpenGL
  6611. FormatDesc := TFormatDescriptor.Get(IntFormat);
  6612. GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
  6613. try
  6614. if FormatDesc.IsCompressed then
  6615. glGetCompressedTexImage(Target, 0, Temp)
  6616. else
  6617. glGetTexImage(Target, 0, FormatDesc.glInternalFormat, FormatDesc.glDataFormat, Temp);
  6618. SetDataPointer(Temp, IntFormat, TempWidth, TempHeight);
  6619. except
  6620. FreeMem(Temp);
  6621. raise;
  6622. end;
  6623. end;
  6624. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6625. procedure TglBitmap2D.GenTexture(const aTestTextureSize: Boolean);
  6626. var
  6627. BuildWithGlu, PotTex, TexRec: Boolean;
  6628. TexSize: Integer;
  6629. begin
  6630. if Assigned(Data) then begin
  6631. // Check Texture Size
  6632. if (aTestTextureSize) then begin
  6633. glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
  6634. if ((Height > TexSize) or (Width > TexSize)) then
  6635. raise EglBitmapSizeToLargeException.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
  6636. PotTex := IsPowerOfTwo(Height) and IsPowerOfTwo(Width);
  6637. TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE);
  6638. if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
  6639. raise EglBitmapNonPowerOfTwoException.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
  6640. end;
  6641. CreateId;
  6642. SetupParameters(BuildWithGlu);
  6643. UploadData(Target, BuildWithGlu);
  6644. glAreTexturesResident(1, @fID, @fIsResident);
  6645. end;
  6646. end;
  6647. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6648. function TglBitmap2D.FlipHorz: Boolean;
  6649. var
  6650. Col, Row: Integer;
  6651. TempDestData, DestData, SourceData: PByte;
  6652. ImgSize: Integer;
  6653. begin
  6654. result := inherited FlipHorz;
  6655. if Assigned(Data) then begin
  6656. SourceData := Data;
  6657. ImgSize := Height * fRowSize;
  6658. GetMem(DestData, ImgSize);
  6659. try
  6660. TempDestData := DestData;
  6661. Dec(TempDestData, fRowSize + fPixelSize);
  6662. for Row := 0 to Height -1 do begin
  6663. Inc(TempDestData, fRowSize * 2);
  6664. for Col := 0 to Width -1 do begin
  6665. Move(SourceData^, TempDestData^, fPixelSize);
  6666. Inc(SourceData, fPixelSize);
  6667. Dec(TempDestData, fPixelSize);
  6668. end;
  6669. end;
  6670. SetDataPointer(DestData, Format);
  6671. result := true;
  6672. except
  6673. FreeMem(DestData);
  6674. raise;
  6675. end;
  6676. end;
  6677. end;
  6678. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6679. function TglBitmap2D.FlipVert: Boolean;
  6680. var
  6681. Row: Integer;
  6682. TempDestData, DestData, SourceData: PByte;
  6683. begin
  6684. result := inherited FlipVert;
  6685. if Assigned(Data) then begin
  6686. SourceData := Data;
  6687. GetMem(DestData, Height * fRowSize);
  6688. try
  6689. TempDestData := DestData;
  6690. Inc(TempDestData, Width * (Height -1) * fPixelSize);
  6691. for Row := 0 to Height -1 do begin
  6692. Move(SourceData^, TempDestData^, fRowSize);
  6693. Dec(TempDestData, fRowSize);
  6694. Inc(SourceData, fRowSize);
  6695. end;
  6696. SetDataPointer(DestData, Format);
  6697. result := true;
  6698. except
  6699. FreeMem(DestData);
  6700. raise;
  6701. end;
  6702. end;
  6703. end;
  6704. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6705. //TglBitmap2D - ToNormalMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6706. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6707. type
  6708. TMatrixItem = record
  6709. X, Y: Integer;
  6710. W: Single;
  6711. end;
  6712. PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
  6713. TglBitmapToNormalMapRec = Record
  6714. Scale: Single;
  6715. Heights: array of Single;
  6716. MatrixU : array of TMatrixItem;
  6717. MatrixV : array of TMatrixItem;
  6718. end;
  6719. const
  6720. ONE_OVER_255 = 1 / 255;
  6721. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6722. procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
  6723. var
  6724. Val: Single;
  6725. begin
  6726. with FuncRec do begin
  6727. Val :=
  6728. Source.Data.r * LUMINANCE_WEIGHT_R +
  6729. Source.Data.g * LUMINANCE_WEIGHT_G +
  6730. Source.Data.b * LUMINANCE_WEIGHT_B;
  6731. PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255;
  6732. end;
  6733. end;
  6734. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6735. procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
  6736. begin
  6737. with FuncRec do
  6738. PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
  6739. end;
  6740. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6741. procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
  6742. type
  6743. TVec = Array[0..2] of Single;
  6744. var
  6745. Idx: Integer;
  6746. du, dv: Double;
  6747. Len: Single;
  6748. Vec: TVec;
  6749. function GetHeight(X, Y: Integer): Single;
  6750. begin
  6751. with FuncRec do begin
  6752. X := Max(0, Min(Size.X -1, X));
  6753. Y := Max(0, Min(Size.Y -1, Y));
  6754. result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
  6755. end;
  6756. end;
  6757. begin
  6758. with FuncRec do begin
  6759. with PglBitmapToNormalMapRec(Args)^ do begin
  6760. du := 0;
  6761. for Idx := Low(MatrixU) to High(MatrixU) do
  6762. du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
  6763. dv := 0;
  6764. for Idx := Low(MatrixU) to High(MatrixU) do
  6765. dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
  6766. Vec[0] := -du * Scale;
  6767. Vec[1] := -dv * Scale;
  6768. Vec[2] := 1;
  6769. end;
  6770. // Normalize
  6771. Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
  6772. if Len <> 0 then begin
  6773. Vec[0] := Vec[0] * Len;
  6774. Vec[1] := Vec[1] * Len;
  6775. Vec[2] := Vec[2] * Len;
  6776. end;
  6777. // Farbe zuweisem
  6778. Dest.Data.r := Trunc((Vec[0] + 1) * 127.5);
  6779. Dest.Data.g := Trunc((Vec[1] + 1) * 127.5);
  6780. Dest.Data.b := Trunc((Vec[2] + 1) * 127.5);
  6781. end;
  6782. end;
  6783. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6784. procedure TglBitmap2D.ToNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
  6785. var
  6786. Rec: TglBitmapToNormalMapRec;
  6787. procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
  6788. begin
  6789. if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
  6790. Matrix[Index].X := X;
  6791. Matrix[Index].Y := Y;
  6792. Matrix[Index].W := W;
  6793. end;
  6794. end;
  6795. begin
  6796. if TFormatDescriptor.Get(Format).IsCompressed then
  6797. raise EglBitmapUnsupportedFormat.Create(Format);
  6798. if aScale > 100 then
  6799. Rec.Scale := 100
  6800. else if aScale < -100 then
  6801. Rec.Scale := -100
  6802. else
  6803. Rec.Scale := aScale;
  6804. SetLength(Rec.Heights, Width * Height);
  6805. try
  6806. case aFunc of
  6807. nm4Samples: begin
  6808. SetLength(Rec.MatrixU, 2);
  6809. SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
  6810. SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
  6811. SetLength(Rec.MatrixV, 2);
  6812. SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
  6813. SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
  6814. end;
  6815. nmSobel: begin
  6816. SetLength(Rec.MatrixU, 6);
  6817. SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
  6818. SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
  6819. SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
  6820. SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
  6821. SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
  6822. SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
  6823. SetLength(Rec.MatrixV, 6);
  6824. SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
  6825. SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
  6826. SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
  6827. SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
  6828. SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
  6829. SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
  6830. end;
  6831. nm3x3: begin
  6832. SetLength(Rec.MatrixU, 6);
  6833. SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
  6834. SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
  6835. SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
  6836. SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
  6837. SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
  6838. SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
  6839. SetLength(Rec.MatrixV, 6);
  6840. SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
  6841. SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
  6842. SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
  6843. SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
  6844. SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
  6845. SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
  6846. end;
  6847. nm5x5: begin
  6848. SetLength(Rec.MatrixU, 20);
  6849. SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
  6850. SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
  6851. SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
  6852. SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
  6853. SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
  6854. SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
  6855. SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
  6856. SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
  6857. SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
  6858. SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
  6859. SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
  6860. SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
  6861. SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
  6862. SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
  6863. SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
  6864. SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
  6865. SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
  6866. SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
  6867. SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
  6868. SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
  6869. SetLength(Rec.MatrixV, 20);
  6870. SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
  6871. SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
  6872. SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
  6873. SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
  6874. SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
  6875. SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
  6876. SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
  6877. SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
  6878. SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
  6879. SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
  6880. SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
  6881. SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
  6882. SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
  6883. SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
  6884. SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
  6885. SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
  6886. SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
  6887. SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
  6888. SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
  6889. SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
  6890. end;
  6891. end;
  6892. // Daten Sammeln
  6893. if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
  6894. AddFunc(glBitmapToNormalMapPrepareAlphaFunc, false, @Rec)
  6895. else
  6896. AddFunc(glBitmapToNormalMapPrepareFunc, false, @Rec);
  6897. AddFunc(glBitmapToNormalMapFunc, false, @Rec);
  6898. finally
  6899. SetLength(Rec.Heights, 0);
  6900. end;
  6901. end;
  6902. (*
  6903. procedure TglBitmap1D.SetDataPointer(Data: pByte; Format: TglBitmapInternalFormat; Width, Height: Integer);
  6904. var
  6905. pTemp: pByte;
  6906. Size: Integer;
  6907. begin
  6908. if Height > 1 then begin
  6909. // extract first line of the data
  6910. Size := FormatGetImageSize(glBitmapPosition(Width), Format);
  6911. GetMem(pTemp, Size);
  6912. Move(Data^, pTemp^, Size);
  6913. FreeMem(Data);
  6914. end else
  6915. pTemp := Data;
  6916. // set data pointer
  6917. inherited SetDataPointer(pTemp, Format, Width);
  6918. if FormatIsUncompressed(Format) then begin
  6919. fUnmapFunc := FormatGetUnMapFunc(Format);
  6920. fGetPixelFunc := GetPixel1DUnmap;
  6921. end;
  6922. end;
  6923. procedure TglBitmap1D.GetPixel1DUnmap(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
  6924. var
  6925. pTemp: pByte;
  6926. begin
  6927. pTemp := Data;
  6928. Inc(pTemp, Pos.X * fPixelSize);
  6929. fUnmapFunc(pTemp, Pixel);
  6930. end;
  6931. function TglBitmap1D.FlipHorz: Boolean;
  6932. var
  6933. Col: Integer;
  6934. pTempDest, pDest, pSource: pByte;
  6935. begin
  6936. result := inherited FlipHorz;
  6937. if Assigned(Data) and FormatIsUncompressed(InternalFormat) then begin
  6938. pSource := Data;
  6939. GetMem(pDest, fRowSize);
  6940. try
  6941. pTempDest := pDest;
  6942. Inc(pTempDest, fRowSize);
  6943. for Col := 0 to Width -1 do begin
  6944. Move(pSource^, pTempDest^, fPixelSize);
  6945. Inc(pSource, fPixelSize);
  6946. Dec(pTempDest, fPixelSize);
  6947. end;
  6948. SetDataPointer(pDest, InternalFormat);
  6949. result := true;
  6950. finally
  6951. FreeMem(pDest);
  6952. end;
  6953. end;
  6954. end;
  6955. procedure TglBitmap1D.UploadData (Target, Format, InternalFormat, Typ: Cardinal; BuildWithGlu: Boolean);
  6956. begin
  6957. // Upload data
  6958. if Self.InternalFormat in [ifDXT1, ifDXT3, ifDXT5] then
  6959. glCompressedTexImage1D(Target, 0, InternalFormat, Width, 0, Trunc(Width * FormatGetSize(Self.InternalFormat)), Data)
  6960. else
  6961. // Upload data
  6962. if BuildWithGlu then
  6963. gluBuild1DMipmaps(Target, InternalFormat, Width, Format, Typ, Data)
  6964. else
  6965. glTexImage1D(Target, 0, InternalFormat, Width, 0, Format, Typ, Data);
  6966. // Freigeben
  6967. if (FreeDataAfterGenTexture) then
  6968. FreeData;
  6969. end;
  6970. procedure TglBitmap1D.GenTexture(TestTextureSize: Boolean);
  6971. var
  6972. BuildWithGlu, TexRec: Boolean;
  6973. glFormat, glInternalFormat, glType: Cardinal;
  6974. TexSize: Integer;
  6975. begin
  6976. if Assigned(Data) then begin
  6977. // Check Texture Size
  6978. if (TestTextureSize) then begin
  6979. glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
  6980. if (Width > TexSize) then
  6981. raise EglBitmapSizeToLargeException.Create('TglBitmap1D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
  6982. TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
  6983. (Target = GL_TEXTURE_RECTANGLE_ARB);
  6984. if not (IsPowerOfTwo (Width) or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
  6985. raise EglBitmapNonPowerOfTwoException.Create('TglBitmap1D.GenTexture - Rendercontex dosn''t support non power of two texture.');
  6986. end;
  6987. CreateId;
  6988. SetupParameters(BuildWithGlu);
  6989. SelectFormat(InternalFormat, glFormat, glInternalFormat, glType);
  6990. UploadData(Target, glFormat, glInternalFormat, glType, BuildWithGlu);
  6991. // Infos sammeln
  6992. glAreTexturesResident(1, @fID, @fIsResident);
  6993. end;
  6994. end;
  6995. procedure TglBitmap1D.AfterConstruction;
  6996. begin
  6997. inherited;
  6998. Target := GL_TEXTURE_1D;
  6999. end;
  7000. { TglBitmapCubeMap }
  7001. procedure TglBitmapCubeMap.AfterConstruction;
  7002. begin
  7003. inherited;
  7004. if not (GL_VERSION_1_3 or GL_ARB_texture_cube_map or GL_EXT_texture_cube_map) then
  7005. raise EglBitmapException.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
  7006. SetWrap; // set all to GL_CLAMP_TO_EDGE
  7007. Target := GL_TEXTURE_CUBE_MAP;
  7008. fGenMode := GL_REFLECTION_MAP;
  7009. end;
  7010. procedure TglBitmapCubeMap.Bind(EnableTexCoordsGen, EnableTextureUnit: Boolean);
  7011. begin
  7012. inherited Bind (EnableTextureUnit);
  7013. if EnableTexCoordsGen then begin
  7014. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, fGenMode);
  7015. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, fGenMode);
  7016. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, fGenMode);
  7017. glEnable(GL_TEXTURE_GEN_S);
  7018. glEnable(GL_TEXTURE_GEN_T);
  7019. glEnable(GL_TEXTURE_GEN_R);
  7020. end;
  7021. end;
  7022. procedure TglBitmapCubeMap.GenerateCubeMap(CubeTarget: Cardinal; TestTextureSize: Boolean);
  7023. var
  7024. glFormat, glInternalFormat, glType: Cardinal;
  7025. BuildWithGlu: Boolean;
  7026. TexSize: Integer;
  7027. begin
  7028. // Check Texture Size
  7029. if (TestTextureSize) then begin
  7030. glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @TexSize);
  7031. if ((Height > TexSize) or (Width > TexSize)) then
  7032. raise EglBitmapSizeToLargeException.Create('TglBitmapCubeMap.GenTexture - The size for the Cubemap is to large. It''s may be not conform with the Hardware.');
  7033. if not ((IsPowerOfTwo (Height) and IsPowerOfTwo (Width)) or GL_VERSION_2_0 or GL_ARB_texture_non_power_of_two) then
  7034. raise EglBitmapNonPowerOfTwoException.Create('TglBitmapCubeMap.GenTexture - Cubemaps dosn''t support non power of two texture.');
  7035. end;
  7036. // create Texture
  7037. if ID = 0 then begin
  7038. CreateID;
  7039. SetupParameters(BuildWithGlu);
  7040. end;
  7041. SelectFormat(InternalFormat, glFormat, glInternalFormat, glType);
  7042. UploadData (CubeTarget, glFormat, glInternalFormat, glType, BuildWithGlu);
  7043. end;
  7044. procedure TglBitmapCubeMap.GenTexture(TestTextureSize: Boolean);
  7045. begin
  7046. Assert(false, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
  7047. end;
  7048. procedure TglBitmapCubeMap.Unbind(DisableTexCoordsGen,
  7049. DisableTextureUnit: Boolean);
  7050. begin
  7051. inherited Unbind (DisableTextureUnit);
  7052. if DisableTexCoordsGen then begin
  7053. glDisable(GL_TEXTURE_GEN_S);
  7054. glDisable(GL_TEXTURE_GEN_T);
  7055. glDisable(GL_TEXTURE_GEN_R);
  7056. end;
  7057. end;
  7058. { TglBitmapNormalMap }
  7059. type
  7060. TVec = Array[0..2] of Single;
  7061. TglBitmapNormalMapGetVectorFunc = procedure (var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
  7062. PglBitmapNormalMapRec = ^TglBitmapNormalMapRec;
  7063. TglBitmapNormalMapRec = record
  7064. HalfSize : Integer;
  7065. Func: TglBitmapNormalMapGetVectorFunc;
  7066. end;
  7067. procedure glBitmapNormalMapPosX(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
  7068. begin
  7069. Vec[0] := HalfSize;
  7070. Vec[1] := - (Position.Y + 0.5 - HalfSize);
  7071. Vec[2] := - (Position.X + 0.5 - HalfSize);
  7072. end;
  7073. procedure glBitmapNormalMapNegX(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
  7074. begin
  7075. Vec[0] := - HalfSize;
  7076. Vec[1] := - (Position.Y + 0.5 - HalfSize);
  7077. Vec[2] := Position.X + 0.5 - HalfSize;
  7078. end;
  7079. procedure glBitmapNormalMapPosY(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
  7080. begin
  7081. Vec[0] := Position.X + 0.5 - HalfSize;
  7082. Vec[1] := HalfSize;
  7083. Vec[2] := Position.Y + 0.5 - HalfSize;
  7084. end;
  7085. procedure glBitmapNormalMapNegY(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
  7086. begin
  7087. Vec[0] := Position.X + 0.5 - HalfSize;
  7088. Vec[1] := - HalfSize;
  7089. Vec[2] := - (Position.Y + 0.5 - HalfSize);
  7090. end;
  7091. procedure glBitmapNormalMapPosZ(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
  7092. begin
  7093. Vec[0] := Position.X + 0.5 - HalfSize;
  7094. Vec[1] := - (Position.Y + 0.5 - HalfSize);
  7095. Vec[2] := HalfSize;
  7096. end;
  7097. procedure glBitmapNormalMapNegZ(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
  7098. begin
  7099. Vec[0] := - (Position.X + 0.5 - HalfSize);
  7100. Vec[1] := - (Position.Y + 0.5 - HalfSize);
  7101. Vec[2] := - HalfSize;
  7102. end;
  7103. procedure glBitmapNormalMapFunc(var FuncRec: TglBitmapFunctionRec);
  7104. var
  7105. Vec : TVec;
  7106. Len: Single;
  7107. begin
  7108. with FuncRec do begin
  7109. with PglBitmapNormalMapRec (CustomData)^ do begin
  7110. Func(Vec, Position, HalfSize);
  7111. // Normalize
  7112. Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
  7113. if Len <> 0 then begin
  7114. Vec[0] := Vec[0] * Len;
  7115. Vec[1] := Vec[1] * Len;
  7116. Vec[2] := Vec[2] * Len;
  7117. end;
  7118. // Scale Vector and AddVectro
  7119. Vec[0] := Vec[0] * 0.5 + 0.5;
  7120. Vec[1] := Vec[1] * 0.5 + 0.5;
  7121. Vec[2] := Vec[2] * 0.5 + 0.5;
  7122. end;
  7123. // Set Color
  7124. Dest.Red := Round(Vec[0] * 255);
  7125. Dest.Green := Round(Vec[1] * 255);
  7126. Dest.Blue := Round(Vec[2] * 255);
  7127. end;
  7128. end;
  7129. procedure TglBitmapNormalMap.AfterConstruction;
  7130. begin
  7131. inherited;
  7132. fGenMode := GL_NORMAL_MAP;
  7133. end;
  7134. procedure TglBitmapNormalMap.GenerateNormalMap(Size: Integer;
  7135. TestTextureSize: Boolean);
  7136. var
  7137. Rec: TglBitmapNormalMapRec;
  7138. SizeRec: TglBitmapPixelPosition;
  7139. begin
  7140. Rec.HalfSize := Size div 2;
  7141. FreeDataAfterGenTexture := false;
  7142. SizeRec.Fields := [ffX, ffY];
  7143. SizeRec.X := Size;
  7144. SizeRec.Y := Size;
  7145. // Positive X
  7146. Rec.Func := glBitmapNormalMapPosX;
  7147. LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
  7148. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X, TestTextureSize);
  7149. // Negative X
  7150. Rec.Func := glBitmapNormalMapNegX;
  7151. LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
  7152. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, TestTextureSize);
  7153. // Positive Y
  7154. Rec.Func := glBitmapNormalMapPosY;
  7155. LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
  7156. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, TestTextureSize);
  7157. // Negative Y
  7158. Rec.Func := glBitmapNormalMapNegY;
  7159. LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
  7160. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, TestTextureSize);
  7161. // Positive Z
  7162. Rec.Func := glBitmapNormalMapPosZ;
  7163. LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
  7164. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, TestTextureSize);
  7165. // Negative Z
  7166. Rec.Func := glBitmapNormalMapNegZ;
  7167. LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
  7168. GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, TestTextureSize);
  7169. end;
  7170. *)
  7171. initialization
  7172. glBitmapSetDefaultFormat(tfEmpty);
  7173. glBitmapSetDefaultMipmap(mmMipmap);
  7174. glBitmapSetDefaultFilter(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
  7175. glBitmapSetDefaultWrap (GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
  7176. glBitmapSetDefaultFreeDataAfterGenTexture(true);
  7177. glBitmapSetDefaultDeleteTextureOnFree (true);
  7178. TFormatDescriptor.Init;
  7179. {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
  7180. OpenGLInitialized := false;
  7181. InitOpenGLCS := TCriticalSection.Create;
  7182. {$ENDIF}
  7183. finalization
  7184. TFormatDescriptor.Finalize;
  7185. {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
  7186. FreeAndNil(InitOpenGLCS);
  7187. {$ENDIF}
  7188. end.