fTransparAdvD.pas 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. unit fTransparAdvD;
  2. interface
  3. uses
  4. Winapi.OpenGL,
  5. System.SysUtils,
  6. System.Variants,
  7. System.Classes,
  8. Vcl.Graphics,
  9. Vcl.Controls,
  10. Vcl.Forms,
  11. Vcl.Dialogs,
  12. Vcl.Imaging.Jpeg,
  13. GLS.TextureFormat,
  14. GLScene.VectorGeometry,
  15. GLScene.VectorTypes,
  16. GLS.Context,
  17. GLS.State,
  18. GLS.Color,
  19. GLS.Scene,
  20. GLS.Objects,
  21. GLS.Coordinates,
  22. GLS.FileJPEG,
  23. GLS.SimpleNavigation,
  24. GLS.Material,
  25. GLS.Cadencer,
  26. GLS.BaseClasses,
  27. GLS.SceneViewer,
  28. GLSL.Shader,
  29. GLSL.CustomShader,
  30. GLS.Texture,
  31. GLS.FBORenderer,
  32. GLS.RenderContextInfo,
  33. GLS.GeomObjects,
  34. GLS.Mesh,
  35. GLS.HUDObjects,
  36. GLS.BitmapFont,
  37. GLS.WindowsFont,
  38. GLS.Keyboard,
  39. GLS.CompositeImage,
  40. GLScene.Utils;
  41. type
  42. TFormTransparAdv = class(TForm)
  43. GLSceneViewer1: TGLSceneViewer;
  44. GLScene1: TGLScene;
  45. GLCadencer1: TGLCadencer;
  46. GLMaterialLibrary1: TGLMaterialLibrary;
  47. GLCamera1: TGLCamera;
  48. GLSLShader1: TGLSLShader;
  49. CustomRederer: TGLDirectOpenGL;
  50. LayeredFrameBuffer: TGLFBORenderer;
  51. GLLightSource1: TGLLightSource;
  52. GLDisk1: TGLDisk;
  53. ObjectContainer: TGLDummyCube;
  54. GLMesh1: TGLMesh;
  55. GLMesh2: TGLMesh;
  56. GLMesh3: TGLMesh;
  57. GLMesh4: TGLMesh;
  58. GLMesh5: TGLMesh;
  59. GLSimpleNavigation1: TGLSimpleNavigation;
  60. GLCylinder1: TGLCylinder;
  61. Surround: TGLDummyCube;
  62. ScreenQuad: TGLHUDSprite;
  63. GLHUDText1: TGLHUDText;
  64. GLWindowsBitmapFont1: TGLWindowsBitmapFont;
  65. ClearFrameBuffer: TGLDirectOpenGL;
  66. procedure ClearFrameBufferRender(Sender: TObject;
  67. var rci: TGLRenderContextInfo);
  68. procedure FormCreate(Sender: TObject);
  69. procedure GLCadencer1Progress(Sender: TObject;
  70. const deltaTime, newTime: Double);
  71. procedure GLSLShader1Apply(Shader: TGLCustomGLSLShader);
  72. procedure CustomRedererRender(Sender: TObject; var rci: TGLRenderContextInfo);
  73. procedure GLSceneViewer1AfterRender(Sender: TObject);
  74. procedure FormResize(Sender: TObject);
  75. private
  76. FOITEnabled: Boolean;
  77. procedure CreateShapes;
  78. public
  79. end;
  80. var
  81. FormTransparAdv: TFormTransparAdv;
  82. implementation
  83. {$R *.dfm}
  84. procedure TFormTransparAdv.FormCreate(Sender: TObject);
  85. var
  86. img: TGLBlankImage;
  87. NativeDir: string;
  88. begin
  89. var Path: TFileName := GetCurrentAssetPath();
  90. SetCurrentDir(Path + '\texture');
  91. // loadable only for Persistent Images
  92. GLMaterialLibrary1.TextureByName('Surround').Image.LoadFromFile('wheatfld.jpg');
  93. GLMaterialLibrary1.TextureByName('Surround').Disabled := False;
  94. SetCurrentDir(Path + '\shader');
  95. GLSLShader1.LoadShaderPrograms('OIT_vtx.glsl','OIT_frag.glsl');
  96. GLSLShader1.Enabled := true;
  97. // Setup texture arrays
  98. img := TGLBlankImage(GLMaterialLibrary1.TextureByName('ColorLayers').Image);
  99. img.TextureArray := True;
  100. img.Depth := 6;
  101. img := TGLBlankImage(GLMaterialLibrary1.TextureByName('DepthLayers').Image);
  102. img.TextureArray := True;
  103. img.Depth := 6;
  104. // Create transparent shapes
  105. CreateShapes;
  106. GLHUDText1.Text := 'Press 1-7 to apply different blending functions'+#10#13+
  107. '8 to apply order independed transparency based on rendering to texture array';
  108. end;
  109. procedure TFormTransparAdv.ClearFrameBufferRender(Sender: TObject;
  110. var rci: TGLRenderContextInfo);
  111. begin
  112. gl.Clear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  113. end;
  114. //---------------------------------------------------------------------------
  115. procedure TFormTransparAdv.CreateShapes;
  116. const
  117. vLtBlue: TGLColorVector = (X: 0.00; Y: 0.00; Z: 1.00; W:0.90);
  118. vLtPink: TGLColorVector = (X: 0.40; Y:0.00; Z:0.20; W:0.50);
  119. vLtYellow: TGLColorVector = (X: 0.98; Y:0.96; Z:0.14; W:0.30);
  120. vLtMagenta: TGLColorVector = (X: 0.83; Y:0.04; Z:0.83; W:0.70);
  121. vLtGreen: TGLColorVector = (X: 0.05; Y:0.98; Z:0.14; W:0.30);
  122. var
  123. vd: array [0 .. 3] of TGLVertexData;
  124. begin
  125. vd[0].coord := Vector3fMake(-0.2, -0.4, 0.0);
  126. vd[1].coord := Vector3fMake(-0.2, 0.4, 0.0);
  127. vd[2].coord := Vector3fMake(0.2, -0.4, 0.0);
  128. vd[3].coord := Vector3fMake(0.2, 0.4, 0.0);
  129. // Color
  130. vd[0].color := vLtYellow;
  131. vd[1].color := vLtYellow;
  132. vd[2].color := vLtYellow;
  133. vd[3].color := vLtYellow;
  134. with GLMesh1 do
  135. begin
  136. Vertices.Clear;
  137. Vertices.AddVertex3(vd[0], vd[1], vd[2]);
  138. Vertices.AddVertex(vd[3]);
  139. CalcNormals(fwCounterClockWise);
  140. end;
  141. vd[0].coord := Vector3fMake(-0.24, -0.35, 0.0);
  142. vd[1].coord := Vector3fMake(-0.24, 0.45, 0.0);
  143. vd[2].coord := Vector3fMake(0.24, -0.45, 0.0);
  144. vd[3].coord := Vector3fMake(0.24, 0.35, 0.0);
  145. // Color
  146. vd[0].color := vLtBlue;
  147. vd[1].color := vLtBlue;
  148. vd[2].color := vLtBlue;
  149. vd[3].color := vLtBlue;
  150. with GLMesh2 do
  151. begin
  152. Vertices.Clear;
  153. Vertices.AddVertex3(vd[0], vd[1], vd[2]);
  154. Vertices.AddVertex(vd[3]);
  155. CalcNormals(fwCounterClockWise);
  156. end;
  157. vd[0].coord := Vector3fMake(-0.20, -0.35, 0.0);
  158. vd[1].coord := Vector3fMake(-0.20, 0.25, 0.0);
  159. vd[2].coord := Vector3fMake(0.20, -0.25, 0.0);
  160. vd[3].coord := Vector3fMake(0.20, 0.35, 0.0);
  161. // Color
  162. vd[0].color := vLtPink;
  163. vd[1].color := vLtPink;
  164. vd[2].color := vLtPink;
  165. vd[3].color := vLtPink;
  166. with GLMesh3 do
  167. begin
  168. Vertices.Clear;
  169. Vertices.AddVertex3(vd[0], vd[1], vd[2]);
  170. Vertices.AddVertex(vd[3]);
  171. CalcNormals(fwCounterClockWise);
  172. end;
  173. vd[0].coord := Vector3fMake(0.0, -0.45, 0.0);
  174. vd[1].coord := Vector3fMake(-0.3, 0.0, 0.0);
  175. vd[2].coord := Vector3fMake(0.3, 0.0, 0.0);
  176. vd[3].coord := Vector3fMake(0.0, 0.45, 0.0);
  177. // Color
  178. vd[0].color := vLtGreen;
  179. vd[1].color := vLtGreen;
  180. vd[2].color := vLtGreen;
  181. vd[3].color := vLtGreen;
  182. with GLMesh4 do
  183. begin
  184. Vertices.Clear;
  185. Vertices.AddVertex3(vd[0], vd[1], vd[2]);
  186. Vertices.AddVertex(vd[3]);
  187. CalcNormals(fwCounterClockWise);
  188. end;
  189. vd[0].coord := Vector3fMake(-0.3, -0.4, 0.0);
  190. vd[1].coord := Vector3fMake(-0.0, 0.5, 0.0);
  191. vd[2].coord := Vector3fMake(0.3, -0.4, 0.0);
  192. // Color
  193. vd[0].color := vLtMagenta;
  194. vd[1].color := vLtMagenta;
  195. vd[2].color := vLtMagenta;
  196. with GLMesh5 do
  197. begin
  198. Vertices.Clear;
  199. Vertices.AddVertex3(vd[0], vd[1], vd[2]);
  200. CalcNormals(fwCounterClockWise);
  201. end;
  202. end;
  203. //--------------------------------------------------------------------------
  204. procedure TFormTransparAdv.GLCadencer1Progress(Sender: TObject;
  205. const deltaTime, newTime: Double);
  206. procedure TurnOffOIT;
  207. begin
  208. ObjectContainer.Visible := True;
  209. ClearFrameBuffer.Visible := True;
  210. CustomRederer.Visible := False;
  211. LayeredFrameBuffer.Active := False;
  212. ScreenQuad.Visible := False;
  213. end;
  214. begin
  215. with GLMaterialLibrary1.Materials[0].Material.BlendingParams do
  216. begin
  217. if IsKeyDown('1') then
  218. begin
  219. SeparateBlendFunc := False;
  220. BlendFuncSFactor := bfSrcAlpha;
  221. BlendFuncDFactor := bfOneMinusSrcAlpha;
  222. TurnOffOIT;
  223. end
  224. else if IsKeyDown('2') then
  225. begin
  226. SeparateBlendFunc := False;
  227. BlendFuncSFactor := bfSrcAlpha;
  228. BlendFuncDFactor := bfOneMinusDstAlpha;
  229. TurnOffOIT;
  230. end
  231. else if IsKeyDown('3') then
  232. begin
  233. SeparateBlendFunc := False;
  234. BlendFuncSFactor := bfOne;
  235. BlendFuncDFactor := bfOneMinusSrcAlpha;
  236. TurnOffOIT;
  237. end
  238. else if IsKeyDown('4') then
  239. begin
  240. SeparateBlendFunc := False;
  241. BlendFuncSFactor := bfSrcAlpha;
  242. BlendFuncDFactor := bfOne;
  243. TurnOffOIT;
  244. end
  245. else if IsKeyDown('5') then
  246. begin
  247. SeparateBlendFunc := False;
  248. BlendFuncSFactor := bfSrcAlpha;
  249. BlendFuncDFactor := bfDstColor;
  250. TurnOffOIT;
  251. end
  252. else if IsKeyDown('6') then
  253. begin
  254. SeparateBlendFunc := True;
  255. BlendFuncSFactor := bfSrcAlpha;
  256. BlendFuncDFactor := bfDstAlpha;
  257. AlphaBlendFuncSFactor := bfSrcAlpha;
  258. AlphaBlendFuncDFactor := bfOneMinusSrcAlpha;
  259. TurnOffOIT;
  260. end
  261. else if IsKeyDown('7') then
  262. begin
  263. SeparateBlendFunc := True;
  264. BlendFuncSFactor := bfSrcColor;
  265. BlendFuncDFactor := bfDstColor;
  266. AlphaBlendFuncSFactor := bfSrcAlpha;
  267. AlphaBlendFuncDFactor := bfOneMinusSrcAlpha;
  268. TurnOffOIT;
  269. end
  270. else if IsKeyDown('8') and FOITEnabled then
  271. begin
  272. ObjectContainer.Visible := False;
  273. ClearFrameBuffer.Visible := False;
  274. CustomRederer.Visible := True;
  275. LayeredFrameBuffer.Active := True;
  276. ScreenQuad.Visible := True;
  277. end;
  278. GLSceneViewer1.Invalidate;
  279. end;
  280. end;
  281. procedure TFormTransparAdv.CustomRedererRender(Sender: TObject;
  282. var rci: TGLRenderContextInfo);
  283. begin
  284. rci.ignoreBlendingRequests := True;
  285. rci.GLStates.Disable(stBlend);
  286. LayeredFrameBuffer.Layer := 0;
  287. gl.Clear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  288. Surround.Render(rci);
  289. GlDisk1.Render(rci);
  290. rci.GLStates.ColorClearValue := clrTransparent;
  291. LayeredFrameBuffer.Layer := 1;
  292. gl.Clear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  293. GLMesh1.Render(rci);
  294. LayeredFrameBuffer.Layer := 2;
  295. gl.Clear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  296. GLMesh2.Render(rci);
  297. LayeredFrameBuffer.Layer := 3;
  298. gl.Clear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  299. GLMesh3.Render(rci);
  300. LayeredFrameBuffer.Layer := 4;
  301. gl.Clear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  302. GLMesh4.Render(rci);
  303. LayeredFrameBuffer.Layer := 5;
  304. gl.Clear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  305. GLMesh5.Render(rci);
  306. rci.ignoreBlendingRequests := True;
  307. end;
  308. procedure TFormTransparAdv.GLSceneViewer1AfterRender(Sender: TObject);
  309. begin
  310. with GLSceneViewer1.Buffer.RenderingContext.GL do
  311. FOITEnabled := VERSION_3_0 or EXT_texture_array;
  312. GLSceneViewer1.AfterRender := nil;
  313. end;
  314. procedure TFormTransparAdv.GLSLShader1Apply(Shader: TGLCustomGLSLShader);
  315. begin
  316. with Shader, GLMaterialLibrary1 do
  317. begin
  318. Param['ColorLayers'].AsTexture[0] := TextureByName('ColorLayers');
  319. Param['DepthLayers'].AsTexture[1] := TextureByName('DepthLayers');
  320. end;
  321. CurrentGLContext.GLStates.Disable(stBlend);
  322. end;
  323. procedure TFormTransparAdv.FormResize(Sender: TObject);
  324. begin
  325. LayeredFrameBuffer.Width := GLSceneViewer1.Width;
  326. LayeredFrameBuffer.Height := GLSceneViewer1.Height;
  327. end;
  328. end.