fTransparAdvD.pas 9.8 KB

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