fOcclusionQueryD.pas 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. unit fOcclusionQueryD;
  2. interface
  3. uses
  4. Winapi.OpenGL,
  5. System.SysUtils,
  6. System.Variants,
  7. System.Classes,
  8. System.UITypes,
  9. Vcl.Graphics,
  10. Vcl.Controls,
  11. Vcl.Forms,
  12. Vcl.Dialogs,
  13. Vcl.StdCtrls,
  14. Vcl.ExtCtrls,
  15. GLS.Scene,
  16. GLScene.VectorTypes,
  17. GLS.GeomObjects,
  18. GLS.Objects,
  19. GLS.Cadencer,
  20. GLS.SceneViewer,
  21. GLS.Coordinates,
  22. GLS.BaseClasses,
  23. GLS.RenderContextInfo,
  24. GLS.Context;
  25. type
  26. TFormOcclusionQuery = class(TForm)
  27. GLScene1: TGLScene;
  28. GLSceneViewer1: TGLSceneViewer;
  29. GLCadencer1: TGLCadencer;
  30. GLCamera1: TGLCamera;
  31. GLCube1: TGLCube;
  32. GLCylinder1: TGLCylinder;
  33. GLDummyCube1: TGLDummyCube;
  34. OGLBeginQueries: TGLDirectOpenGL;
  35. dcTestObjects: TGLDummyCube;
  36. OGLEndQueries: TGLDirectOpenGL;
  37. GLTorus1: TGLTorus;
  38. GLLightSource1: TGLLightSource;
  39. GLDummyCube2: TGLDummyCube;
  40. GLCube2: TGLCube;
  41. Timer1: TTimer;
  42. Panel1: TPanel;
  43. Label1: TLabel;
  44. Label2: TLabel;
  45. Label3: TLabel;
  46. GLCone1: TGLCone;
  47. CheckBox1: TCheckBox;
  48. LabelFPS: TLabel;
  49. procedure OGLBeginQueriesRender(Sender: TObject;
  50. var rci: TGLRenderContextInfo);
  51. procedure OGLEndQueriesRender(Sender: TObject;
  52. var rci: TGLRenderContextInfo);
  53. procedure FormDestroy(Sender: TObject);
  54. procedure GLCadencer1Progress(Sender: TObject; const deltaTime,
  55. newTime: Double);
  56. procedure Timer1Timer(Sender: TObject);
  57. procedure GLSceneViewer1BeforeRender(Sender: TObject);
  58. private
  59. public
  60. end;
  61. var
  62. FormOcclusionQuery: TFormOcclusionQuery;
  63. TimerQuery: TGLTimerQueryHandle;
  64. OcclusionQuery: TGLOcclusionQueryHandle;
  65. bOcclusionQuery: TGLBooleanOcclusionQueryHandle;
  66. queriesCreated: boolean;
  67. timerQuerySupported: Boolean;
  68. timeTaken: Integer; // in nanoseconds
  69. samplesPassed: Integer;
  70. implementation
  71. {$R *.dfm}
  72. //------------------------------------------------------------------------------
  73. procedure TFormOcclusionQuery.GLCadencer1Progress(Sender: TObject; const deltaTime,
  74. newTime: Double);
  75. begin
  76. // Move some of the scene objects around
  77. GLDummyCube1.Position.X := Sin(newTime);
  78. dcTestObjects.Turn(DeltaTime * 50);
  79. dcTestObjects.Position.z := 2 * Sin(newTime);
  80. GLDummyCube2.Position.X := -sin(newTime);
  81. end;
  82. procedure TFormOcclusionQuery.GLSceneViewer1BeforeRender(Sender: TObject);
  83. begin
  84. // Occlusion queries are supported by extensions with lower version of OpenGL.
  85. // To use them, you'd need to check if GL_NV_occlusion_query or GL_ARB_occlusion_query
  86. // extensions are present, and makes the appropriate calls to the functions/procedures
  87. // they provide.
  88. if (not TGLOcclusionQueryHandle.IsSupported) then
  89. begin
  90. Messagedlg('Requires hardware that supports occlusion queries to run',
  91. mtError, [mbOK], 0);
  92. Close;
  93. end;
  94. end;
  95. procedure TFormOcclusionQuery.OGLBeginQueriesRender(Sender: TObject;
  96. var rci: TGLRenderContextInfo);
  97. begin
  98. // Generate the queries, if not already created
  99. if not queriesCreated then
  100. begin
  101. OcclusionQuery := TGLOcclusionQueryHandle.CreateAndAllocate();
  102. CheckBox1.Enabled := TGLBooleanOcclusionQueryHandle.IsSupported;
  103. if CheckBox1.Enabled then
  104. bOcclusionQuery := TGLBooleanOcclusionQueryHandle.CreateAndAllocate();
  105. timerQuerySupported := TGLTimerQueryHandle.IsSupported;
  106. if timerQuerySupported then
  107. TimerQuery := TGLTimerQueryHandle.CreateAndAllocate();
  108. queriesCreated := true;
  109. end;
  110. // Begin the timer + occlusion queries
  111. if timerQuerySupported then
  112. TimerQuery.BeginQuery;
  113. if CheckBox1.Checked then
  114. bOcclusionQuery.BeginQuery
  115. else
  116. OcclusionQuery.BeginQuery;
  117. end;
  118. procedure TFormOcclusionQuery.OGLEndQueriesRender(Sender: TObject;
  119. var rci: TGLRenderContextInfo);
  120. var
  121. lQuery: TGLQueryHandle;
  122. begin
  123. // End the timer + occlusion queries
  124. if CheckBox1.Checked then
  125. lQuery := bOcclusionQuery
  126. else
  127. lQuery := OcclusionQuery;
  128. lQuery.EndQuery;
  129. if timerQuerySupported then
  130. TimerQuery.EndQuery;
  131. // Most of the frame rate is lost waiting for results to become available
  132. // + updating the captions every frame, but as this is a demo, we want to
  133. // see what is going on.
  134. while not lQuery.IsResultAvailable do
  135. { wait }; // would normally do something in this period before checking if
  136. // result is available
  137. samplesPassed := OcclusionQuery.PixelCount;
  138. if timerQuerySupported then
  139. begin
  140. while not TimerQuery.IsResultAvailable do ; (* wait *)
  141. // would normally do something in this period before checking if result is available
  142. timeTaken := TimerQuery.Time;
  143. // Use this line instead of the one above to use 64 bit timer, to allow
  144. // recording time periods more than a couple of seconds (requires Delphi 7+)
  145. // timeTaken := TimerQuery.QueryResultUInt64;
  146. end;
  147. case CheckBox1.Checked of
  148. True:
  149. begin
  150. label3.Visible := not lQuery.QueryResultBool;
  151. end;
  152. False:
  153. begin
  154. label3.Visible := (samplesPassed = 0);
  155. label2.caption := 'Number of test pixels visible: ' + IntToStr(samplesPassed);
  156. end;
  157. end;
  158. end;
  159. procedure TFormOcclusionQuery.Timer1Timer(Sender: TObject);
  160. begin
  161. // Convert time taken from ns => ms & display
  162. if timerQuerySupported then
  163. label1.caption := 'Time taken: ' + FloatToSTr(timeTaken / 1000000) + ' ms'
  164. else
  165. label1.Caption := 'Time query unavailable, requires hardware support';
  166. LabelFPS.Caption := GLSceneViewer1.FramesPerSecondText(0);
  167. GLSceneViewer1.ResetPerformanceMonitor;
  168. end;
  169. procedure TFormOcclusionQuery.FormDestroy(Sender: TObject);
  170. begin
  171. // Delete the queries
  172. TimerQuery.Free;
  173. OcclusionQuery.Free;
  174. bOcclusionQuery.Free;
  175. end;
  176. end.