2
0

GLS.MultiSampleImage.pas 6.8 KB

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