GLMultisampleImage.pas 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. //
  2. // This unit is part of the GLScene Engine, http://glscene.org
  3. //
  4. {
  5. This unit provides support for two new types of "multisample
  6. textures" - two-dimensional and two-dimensional array - as well as
  7. mechanisms to fetch a specific sample from such a texture in a shader,
  8. and to attach such textures to FBOs for rendering.
  9. }
  10. unit GLMultisampleImage;
  11. interface
  12. {$I GLScene.inc}
  13. uses
  14. System.Classes,
  15. OpenGLTokens,
  16. GLContext,
  17. GLTexture,
  18. GLGraphics,
  19. GLTextureFormat;
  20. type
  21. TGLMultisampleImage = class(TGLTextureImage)
  22. private
  23. FBitmap: TGLBitmap32;
  24. FSamplesCount: Integer;
  25. FWidth, FHeight, FDepth: Integer;
  26. FFixedSamplesLocation: Boolean;
  27. procedure SetWidth(val: Integer);
  28. procedure SetHeight(val: Integer);
  29. procedure SetDepth(val: Integer);
  30. procedure SetSamplesCount(val: Integer);
  31. procedure SetFixedSamplesLocation(val: Boolean);
  32. protected
  33. function GetWidth: Integer; override;
  34. function GetHeight: Integer; override;
  35. function GetDepth: Integer; override;
  36. function GetTextureTarget: TGLTextureTarget; override;
  37. public
  38. constructor Create(AOwner: TPersistent); override;
  39. destructor Destroy; override;
  40. procedure Assign(Source: TPersistent); override;
  41. class function IsSelfLoading: Boolean; override;
  42. procedure LoadTexture(AInternalFormat: TGLInternalFormat); override;
  43. function GetBitmap32: TGLBitmap32; override;
  44. procedure ReleaseBitmap32; override;
  45. procedure SaveToFile(const fileName: string); override;
  46. procedure LoadFromFile(const fileName: string); override;
  47. class function FriendlyName: string; override;
  48. class function FriendlyDescription: string; override;
  49. property NativeTextureTarget;
  50. published
  51. {Width of the blank image (for memory allocation). }
  52. property Width: Integer read GetWidth write SetWidth default 256;
  53. {Width of the blank image (for memory allocation). }
  54. property Height: Integer read GetHeight write SetHeight default 256;
  55. property Depth: Integer read GetDepth write SetDepth default 0;
  56. property SamplesCount: Integer read FSamplesCount write SetSamplesCount
  57. default 0;
  58. property FixedSamplesLocation: Boolean read FFixedSamplesLocation write
  59. SetFixedSamplesLocation;
  60. end;
  61. implementation
  62. // ------------------
  63. // ------------------ TGLMultisampleImage ------------------
  64. // ------------------
  65. constructor TGLMultisampleImage.Create(AOwner: TPersistent);
  66. begin
  67. inherited;
  68. FWidth := 256;
  69. FHeight := 256;
  70. FDepth := 0;
  71. FSamplesCount := 0;
  72. end;
  73. destructor TGLMultisampleImage.Destroy;
  74. begin
  75. ReleaseBitmap32;
  76. inherited Destroy;
  77. end;
  78. procedure TGLMultisampleImage.Assign(Source: TPersistent);
  79. begin
  80. if Assigned(Source) then
  81. begin
  82. if (Source is TGLMultisampleImage) then
  83. begin
  84. FWidth := TGLMultisampleImage(Source).FWidth;
  85. FHeight := TGLMultisampleImage(Source).FHeight;
  86. FDepth := TGLMultisampleImage(Source).FDepth;
  87. FSamplesCount := TGLMultisampleImage(Source).FSamplesCount;
  88. Invalidate;
  89. end
  90. else
  91. inherited;
  92. end
  93. else
  94. inherited;
  95. end;
  96. procedure TGLMultisampleImage.SetWidth(val: Integer);
  97. begin
  98. if val <> FWidth then
  99. begin
  100. FWidth := val;
  101. if FWidth < 1 then
  102. FWidth := 1;
  103. Invalidate;
  104. end;
  105. end;
  106. function TGLMultisampleImage.GetWidth: Integer;
  107. begin
  108. Result := FWidth;
  109. end;
  110. procedure TGLMultisampleImage.SetHeight(val: Integer);
  111. begin
  112. if val <> FHeight then
  113. begin
  114. FHeight := val;
  115. if FHeight < 1 then
  116. FHeight := 1;
  117. Invalidate;
  118. end;
  119. end;
  120. function TGLMultisampleImage.GetHeight: Integer;
  121. begin
  122. Result := FHeight;
  123. end;
  124. function TGLMultisampleImage.GetDepth: Integer;
  125. begin
  126. Result := FDepth;
  127. end;
  128. procedure TGLMultisampleImage.SetDepth(val: Integer);
  129. begin
  130. if val <> FDepth then
  131. begin
  132. FDepth := val;
  133. if FDepth < 0 then
  134. FDepth := 0;
  135. Invalidate;
  136. end;
  137. end;
  138. procedure TGLMultisampleImage.SetSamplesCount(val: Integer);
  139. begin
  140. if val < 0 then
  141. val := 0;
  142. if val <> FSamplesCount then
  143. begin
  144. FSamplesCount := val;
  145. Invalidate;
  146. end;
  147. end;
  148. procedure TGLMultisampleImage.SetFixedSamplesLocation(val: Boolean);
  149. begin
  150. if val <> FFixedSamplesLocation then
  151. begin
  152. FFixedSamplesLocation := val;
  153. Invalidate;
  154. end;
  155. end;
  156. function TGLMultisampleImage.GetBitmap32: TGLBitmap32;
  157. begin
  158. if not Assigned(FBitmap) then
  159. begin
  160. FBitmap := TGLBitmap32.Create;
  161. FBitmap.Blank := true;
  162. FBitmap.Width := FWidth;
  163. FBitmap.Height := FHeight;
  164. end;
  165. Result := FBitmap;
  166. end;
  167. procedure TGLMultisampleImage.ReleaseBitmap32;
  168. begin
  169. FBitmap.Free;
  170. FBitmap := nil;
  171. end;
  172. procedure TGLMultisampleImage.SaveToFile(const fileName: string);
  173. begin
  174. end;
  175. procedure TGLMultisampleImage.LoadFromFile(const fileName: string);
  176. begin
  177. end;
  178. class function TGLMultisampleImage.FriendlyName: string;
  179. begin
  180. Result := 'Multisample Image';
  181. end;
  182. class function TGLMultisampleImage.FriendlyDescription: string;
  183. begin
  184. Result := 'Image for rendering to texture with antialiasing';
  185. end;
  186. function TGLMultisampleImage.GetTextureTarget: TGLTextureTarget;
  187. begin
  188. if fDepth > 0 then
  189. Result := ttTexture2DMultisampleArray
  190. else
  191. Result := ttTexture2DMultisample;
  192. end;
  193. class function TGLMultisampleImage.IsSelfLoading: Boolean;
  194. begin
  195. Result := True;
  196. end;
  197. procedure TGLMultisampleImage.LoadTexture(AInternalFormat: TGLInternalFormat);
  198. var
  199. target: TGLTextureTarget;
  200. maxSamples, maxSize: TGLint;
  201. begin
  202. // Check smaples count range
  203. gl.GetIntegerv(GL_MAX_SAMPLES, @maxSamples);
  204. if FSamplesCount > maxSamples then
  205. FSamplesCount := maxSamples;
  206. if IsDepthFormat(AInternalFormat) then
  207. begin
  208. gl.GetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, @maxSamples);
  209. if FSamplesCount > maxSamples then
  210. FSamplesCount := maxSamples;
  211. end
  212. else
  213. begin
  214. gl.GetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, @maxSamples);
  215. if FSamplesCount > maxSamples then
  216. FSamplesCount := maxSamples;
  217. end;
  218. // Check texture size
  219. gl.GetIntegerv(GL_MAX_TEXTURE_SIZE, @maxSize);
  220. if FWidth > maxSize then
  221. FWidth := maxSize;
  222. if FHeight > maxSize then
  223. FHeight := maxSize;
  224. target := NativeTextureTarget;
  225. case target of
  226. ttTexture2DMultisample:
  227. gl.TexImage2DMultisample(
  228. DecodeTextureTarget(target),
  229. SamplesCount,
  230. InternalFormatToOpenGLFormat(AInternalFormat),
  231. Width,
  232. Height,
  233. FFixedSamplesLocation);
  234. ttTexture2DMultisampleArray:
  235. gl.TexImage3DMultisample(
  236. DecodeTextureTarget(target),
  237. SamplesCount,
  238. InternalFormatToOpenGLFormat(AInternalFormat),
  239. Width,
  240. Height,
  241. Depth,
  242. FFixedSamplesLocation);
  243. end;
  244. end;
  245. //--------------------------------------------
  246. initialization
  247. //--------------------------------------------
  248. RegisterGLTextureImageClass(TGLMultisampleImage);
  249. end.