fTransparencyAdv.pas 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  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. SetGLSceneMediaDir();
  89. GLMaterialLibrary1.TextureByName('Surround').Image.LoadFromFile('WheatFld.JPG');
  90. GLSLShader1.LoadShaderPrograms('Shaders\OIT_vtx.glsl','Shaders\OIT_frag.glsl');
  91. GLSLShader1.Enabled := true;
  92. // Setup texture arrays
  93. img := TGLBlankImage(GLMaterialLibrary1.TextureByName('ColorLayers').Image);
  94. img.TextureArray := True;
  95. img.Depth := 6;
  96. img := TGLBlankImage(GLMaterialLibrary1.TextureByName('DepthLayers').Image);
  97. img.TextureArray := True;
  98. img.Depth := 6;
  99. // Create transparent shapes
  100. CreateShapes;
  101. GLHUDText1.Text := 'Press 1-7 to apply different blending functions'+#10#13+
  102. '8 to apply order independed transparency based on rendering to texture array';
  103. end;
  104. procedure TForm1.ClearFrameBufferRender(Sender: TObject;
  105. var rci: TGLRenderContextInfo);
  106. begin
  107. gl.Clear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  108. end;
  109. procedure TForm1.CreateShapes;
  110. const
  111. vLtBlue: TColorVector = (X: 0.00; Y: 0.00; Z: 1.00; W:0.90);
  112. vLtPink: TColorVector = (X: 0.40; Y:0.00; Z:0.20; W:0.50);
  113. vLtYellow: TColorVector = (X: 0.98; Y:0.96; Z:0.14; W:0.30);
  114. vLtMagenta: TColorVector = (X: 0.83; Y:0.04; Z:0.83; W:0.70);
  115. vLtGreen: TColorVector = (X: 0.05; Y:0.98; Z:0.14; W:0.30);
  116. var
  117. vd: array [0 .. 3] of TGLVertexData;
  118. begin
  119. vd[0].coord := Vector3fMake(-0.2, -0.4, 0.0);
  120. vd[1].coord := Vector3fMake(-0.2, 0.4, 0.0);
  121. vd[2].coord := Vector3fMake(0.2, -0.4, 0.0);
  122. vd[3].coord := Vector3fMake(0.2, 0.4, 0.0);
  123. vd[0].color := vLtYellow;
  124. vd[1].color := vLtYellow;
  125. vd[2].color := vLtYellow;
  126. vd[3].color := vLtYellow;
  127. with GLMesh1 do
  128. begin
  129. Vertices.Clear;
  130. Vertices.AddVertex3(vd[0], vd[1], vd[2]);
  131. Vertices.AddVertex(vd[3]);
  132. CalcNormals(fwCounterClockWise);
  133. end;
  134. vd[0].coord := Vector3fMake(-0.24, -0.35, 0.0);
  135. vd[1].coord := Vector3fMake(-0.24, 0.45, 0.0);
  136. vd[2].coord := Vector3fMake(0.24, -0.45, 0.0);
  137. vd[3].coord := Vector3fMake(0.24, 0.35, 0.0);
  138. vd[0].color := vLtBlue;
  139. vd[1].color := vLtBlue;
  140. vd[2].color := vLtBlue;
  141. vd[3].color := vLtBlue;
  142. with GLMesh2 do
  143. begin
  144. Vertices.Clear;
  145. Vertices.AddVertex3(vd[0], vd[1], vd[2]);
  146. Vertices.AddVertex(vd[3]);
  147. CalcNormals(fwCounterClockWise);
  148. end;
  149. vd[0].coord := Vector3fMake(-0.20, -0.35, 0.0);
  150. vd[1].coord := Vector3fMake(-0.20, 0.25, 0.0);
  151. vd[2].coord := Vector3fMake(0.20, -0.25, 0.0);
  152. vd[3].coord := Vector3fMake(0.20, 0.35, 0.0);
  153. vd[0].color := vLtPink;
  154. vd[1].color := vLtPink;
  155. vd[2].color := vLtPink;
  156. vd[3].color := vLtPink;
  157. with GLMesh3 do
  158. begin
  159. Vertices.Clear;
  160. Vertices.AddVertex3(vd[0], vd[1], vd[2]);
  161. Vertices.AddVertex(vd[3]);
  162. CalcNormals(fwCounterClockWise);
  163. end;
  164. vd[0].coord := Vector3fMake(0.0, -0.45, 0.0);
  165. vd[1].coord := Vector3fMake(-0.3, 0.0, 0.0);
  166. vd[2].coord := Vector3fMake(0.3, 0.0, 0.0);
  167. vd[3].coord := Vector3fMake(0.0, 0.45, 0.0);
  168. vd[0].color := vLtGreen;
  169. vd[1].color := vLtGreen;
  170. vd[2].color := vLtGreen;
  171. vd[3].color := vLtGreen;
  172. with GLMesh4 do
  173. begin
  174. Vertices.Clear;
  175. Vertices.AddVertex3(vd[0], vd[1], vd[2]);
  176. Vertices.AddVertex(vd[3]);
  177. CalcNormals(fwCounterClockWise);
  178. end;
  179. vd[0].coord := Vector3fMake(-0.3, -0.4, 0.0);
  180. vd[1].coord := Vector3fMake(-0.0, 0.5, 0.0);
  181. vd[2].coord := Vector3fMake(0.3, -0.4, 0.0);
  182. vd[0].color := vLtMagenta;
  183. vd[1].color := vLtMagenta;
  184. vd[2].color := vLtMagenta;
  185. with GLMesh5 do
  186. begin
  187. Vertices.Clear;
  188. Vertices.AddVertex3(vd[0], vd[1], vd[2]);
  189. CalcNormals(fwCounterClockWise);
  190. end;
  191. end;
  192. procedure TForm1.GLCadencer1Progress(Sender: TObject;
  193. const deltaTime, newTime: Double);
  194. procedure TurnOffOIT;
  195. begin
  196. ObjectContainer.Visible := True;
  197. ClearFrameBuffer.Visible := True;
  198. CustomRederer.Visible := False;
  199. LayeredFrameBuffer.Active := False;
  200. ScreenQuad.Visible := False;
  201. end;
  202. begin
  203. with GLMaterialLibrary1.Materials[0].Material.BlendingParams do
  204. begin
  205. if IsKeyDown('1') then
  206. begin
  207. SeparateBlendFunc := False;
  208. BlendFuncSFactor := bfSrcAlpha;
  209. BlendFuncDFactor := bfOneMinusSrcAlpha;
  210. TurnOffOIT;
  211. end
  212. else if IsKeyDown('2') then
  213. begin
  214. SeparateBlendFunc := False;
  215. BlendFuncSFactor := bfSrcAlpha;
  216. BlendFuncDFactor := bfOneMinusDstAlpha;
  217. TurnOffOIT;
  218. end
  219. else if IsKeyDown('3') then
  220. begin
  221. SeparateBlendFunc := False;
  222. BlendFuncSFactor := bfOne;
  223. BlendFuncDFactor := bfOneMinusSrcAlpha;
  224. TurnOffOIT;
  225. end
  226. else if IsKeyDown('4') then
  227. begin
  228. SeparateBlendFunc := False;
  229. BlendFuncSFactor := bfSrcAlpha;
  230. BlendFuncDFactor := bfOne;
  231. TurnOffOIT;
  232. end
  233. else if IsKeyDown('5') then
  234. begin
  235. SeparateBlendFunc := False;
  236. BlendFuncSFactor := bfSrcAlpha;
  237. BlendFuncDFactor := bfDstColor;
  238. TurnOffOIT;
  239. end
  240. else if IsKeyDown('6') then
  241. begin
  242. SeparateBlendFunc := True;
  243. BlendFuncSFactor := bfSrcAlpha;
  244. BlendFuncDFactor := bfDstAlpha;
  245. AlphaBlendFuncSFactor := bfSrcAlpha;
  246. AlphaBlendFuncDFactor := bfOneMinusSrcAlpha;
  247. TurnOffOIT;
  248. end
  249. else if IsKeyDown('7') then
  250. begin
  251. SeparateBlendFunc := True;
  252. BlendFuncSFactor := bfSrcColor;
  253. BlendFuncDFactor := bfDstColor;
  254. AlphaBlendFuncSFactor := bfSrcAlpha;
  255. AlphaBlendFuncDFactor := bfOneMinusSrcAlpha;
  256. TurnOffOIT;
  257. end
  258. else if IsKeyDown('8') and FOITEnabled then
  259. begin
  260. ObjectContainer.Visible := False;
  261. ClearFrameBuffer.Visible := False;
  262. CustomRederer.Visible := True;
  263. LayeredFrameBuffer.Active := True;
  264. ScreenQuad.Visible := True;
  265. end;
  266. GLSceneViewer1.Invalidate;
  267. end;
  268. end;
  269. procedure TForm1.CustomRedererRender(Sender: TObject;
  270. var rci: TGLRenderContextInfo);
  271. begin
  272. rci.ignoreBlendingRequests := True;
  273. rci.GLStates.Disable(stBlend);
  274. LayeredFrameBuffer.Layer := 0;
  275. gl.Clear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  276. Surround.Render(rci);
  277. GlDisk1.Render(rci);
  278. rci.GLStates.ColorClearValue := clrTransparent;
  279. LayeredFrameBuffer.Layer := 1;
  280. gl.Clear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  281. GLMesh1.Render(rci);
  282. LayeredFrameBuffer.Layer := 2;
  283. gl.Clear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  284. GLMesh2.Render(rci);
  285. LayeredFrameBuffer.Layer := 3;
  286. gl.Clear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  287. GLMesh3.Render(rci);
  288. LayeredFrameBuffer.Layer := 4;
  289. gl.Clear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  290. GLMesh4.Render(rci);
  291. LayeredFrameBuffer.Layer := 5;
  292. gl.Clear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  293. GLMesh5.Render(rci);
  294. rci.ignoreBlendingRequests := True;
  295. end;
  296. procedure TForm1.GLSceneViewer1AfterRender(Sender: TObject);
  297. begin
  298. with GLSceneViewer1.Buffer.RenderingContext.GL do
  299. FOITEnabled := VERSION_3_0 or EXT_texture_array;
  300. GLSceneViewer1.AfterRender := nil;
  301. end;
  302. procedure TForm1.GLSLShader1Apply(Shader: TGLCustomGLSLShader);
  303. begin
  304. with Shader, GLMaterialLibrary1 do
  305. begin
  306. Param['ColorLayers'].AsTexture[0] := TextureByName('ColorLayers');
  307. Param['DepthLayers'].AsTexture[1] := TextureByName('DepthLayers');
  308. end;
  309. CurrentGLContext.GLStates.Disable(stBlend);
  310. end;
  311. procedure TForm1.FormResize(Sender: TObject);
  312. begin
  313. LayeredFrameBuffer.Width := GLSceneViewer1.Width;
  314. LayeredFrameBuffer.Height := GLSceneViewer1.Height;
  315. end;
  316. end.