fTransparencyAdv.pas 9.4 KB

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