GLS.MultiSampleImage.pas 6.8 KB

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