fHeightField.pas 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. unit fHeightField;
  2. interface
  3. uses
  4. Winapi.OpenGL,
  5. System.SysUtils,
  6. System.Classes,
  7. System.Math,
  8. System.Types,
  9. Vcl.Graphics,
  10. Vcl.Controls,
  11. Vcl.Forms,
  12. Vcl.StdCtrls,
  13. Vcl.ComCtrls,
  14. Vcl.ExtCtrls,
  15. GLS.Scene,
  16. GLS.Graph,
  17. GLS.Objects,
  18. GLS.Texture,
  19. GLS.Cadencer,
  20. GLS.VectorGeometry,
  21. GLS.VectorTypes,
  22. GLS.SceneViewer,
  23. GLS.Color,
  24. GLS.Coordinates,
  25. GLS.BaseClasses;
  26. type
  27. TFormHeightField = class(TForm)
  28. GLScene1: TGLScene;
  29. GLSceneViewer1: TGLSceneViewer;
  30. GLCamera1: TGLCamera;
  31. GLLightSource1: TGLLightSource;
  32. HeightField1: TGLHeightField;
  33. Timer1: TTimer;
  34. Sphere1: TGLSphere;
  35. GLCadencer1: TGLCadencer;
  36. Lines1: TGLLines;
  37. Panel1: TPanel;
  38. Label1: TLabel;
  39. TrackBar1: TTrackBar;
  40. Label2: TLabel;
  41. TrackBar2: TTrackBar;
  42. Label3: TLabel;
  43. TrackBar3: TTrackBar;
  44. RadioGroup1: TRadioGroup;
  45. CheckBox1: TCheckBox;
  46. Label4: TLabel;
  47. ComboBox1: TComboBox;
  48. CheckBox2: TCheckBox;
  49. LabelFPS: TLabel;
  50. procedure GLSceneViewer1MouseDown(Sender: TObject; Button: TMouseButton;
  51. Shift: TShiftState; X, Y: Integer);
  52. procedure GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState;
  53. X, Y: Integer);
  54. procedure CheckBox1Click(Sender: TObject);
  55. procedure TrackBar1Change(Sender: TObject);
  56. procedure TrackBar2Change(Sender: TObject);
  57. procedure TrackBar3Change(Sender: TObject);
  58. procedure FormCreate(Sender: TObject);
  59. procedure RadioGroup1Click(Sender: TObject);
  60. procedure Timer1Timer(Sender: TObject);
  61. procedure ComboBox1Change(Sender: TObject);
  62. procedure Sphere1Progress(Sender: TObject;
  63. const deltaTime, newTime: Double);
  64. procedure CheckBox2Click(Sender: TObject);
  65. procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
  66. WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  67. private
  68. procedure Formula1(const X, Y: Single; var z: Single;
  69. var Color: TColorVector; var texPoint: TTexPoint);
  70. procedure Formula2(const X, Y: Single; var z: Single;
  71. var Color: TColorVector; var texPoint: TTexPoint);
  72. procedure Formula3(const X, Y: Single; var z: Single;
  73. var Color: TColorVector; var texPoint: TTexPoint);
  74. public
  75. mx, my: Integer;
  76. end;
  77. var
  78. FormHeightField: TFormHeightField;
  79. implementation
  80. {$R *.DFM}
  81. procedure TFormHeightField.FormCreate(Sender: TObject);
  82. begin
  83. // start with first formula
  84. HeightField1.OnGetHeight := Formula1;
  85. // no per-vertex coloring
  86. ComboBox1.ItemIndex := 1; // emission
  87. ComboBox1Change(Sender);
  88. end;
  89. procedure TFormHeightField.Formula1(const X, Y: Single; var z: Single;
  90. var Color: TColorVector; var texPoint: TTexPoint);
  91. begin
  92. // first formula
  93. z := VectorNorm(X, Y);
  94. z := cos(z * 12) / (2 * (z * 6.28 + 1));
  95. VectorLerp(clrBlue, clrRed, (z + 1) / 2, Color);
  96. end;
  97. procedure TFormHeightField.Formula2(const X, Y: Single; var z: Single;
  98. var Color: TColorVector; var texPoint: TTexPoint);
  99. begin
  100. // 2nd formula
  101. z := 0.5 * cos(X * 6.28) * sin(Sqrt(abs(Y)) * 6.28);
  102. VectorLerp(clrBlue, clrRed, (z + 1) / 2, Color);
  103. end;
  104. procedure TFormHeightField.Formula3(const X, Y: Single; var z: Single;
  105. var Color: TColorVector; var texPoint: TTexPoint);
  106. begin
  107. // 3rd formula, dynamic
  108. z := 1 / (1 + VectorNorm(Sphere1.position.X - X, Sphere1.position.Y - Y));
  109. if ((Round(X * 4) + Round(Y * 4)) and 1) = 1 then
  110. Color := clrBlue
  111. else
  112. Color := clrYellow;
  113. end;
  114. procedure TFormHeightField.RadioGroup1Click(Sender: TObject);
  115. begin
  116. Sphere1.Visible := False;
  117. // switch between formulas
  118. case RadioGroup1.ItemIndex of
  119. 0:
  120. HeightField1.OnGetHeight := Formula1;
  121. 1:
  122. HeightField1.OnGetHeight := Formula2;
  123. 2:
  124. begin
  125. HeightField1.OnGetHeight := Formula3;
  126. Sphere1.Visible := True;
  127. end;
  128. end;
  129. end;
  130. procedure TFormHeightField.Sphere1Progress(Sender: TObject;
  131. const deltaTime, newTime: Double);
  132. begin
  133. // move our little sphere around
  134. if Sphere1.Visible then
  135. begin
  136. Sphere1.position.SetPoint(cos(newTime * 2.3), sin(newTime), 1.5);
  137. HeightField1.StructureChanged;
  138. end;
  139. end;
  140. procedure TFormHeightField.CheckBox1Click(Sender: TObject);
  141. begin
  142. // enable two sided surface
  143. if CheckBox1.Checked then
  144. HeightField1.Options := HeightField1.Options + [hfoTwoSided]
  145. else
  146. HeightField1.Options := HeightField1.Options - [hfoTwoSided];
  147. end;
  148. procedure TFormHeightField.ComboBox1Change(Sender: TObject);
  149. begin
  150. // change per vertex color mode
  151. case ComboBox1.ItemIndex of
  152. 0:
  153. HeightField1.ColorMode := hfcmNone;
  154. 1:
  155. HeightField1.ColorMode := hfcmEmission;
  156. 2:
  157. HeightField1.ColorMode := hfcmDiffuse;
  158. end;
  159. end;
  160. procedure TFormHeightField.CheckBox2Click(Sender: TObject);
  161. begin
  162. GLLightSource1.Shining := CheckBox2.Checked;
  163. end;
  164. procedure TFormHeightField.TrackBar1Change(Sender: TObject);
  165. begin
  166. // adjust X extents
  167. with HeightField1.XSamplingScale do
  168. begin
  169. Min := -TrackBar1.position / 10;
  170. Max := TrackBar1.position / 10;
  171. end;
  172. end;
  173. procedure TFormHeightField.TrackBar2Change(Sender: TObject);
  174. begin
  175. // adjust Y extents
  176. with HeightField1.YSamplingScale do
  177. begin
  178. Min := -TrackBar2.position / 10;
  179. Max := TrackBar2.position / 10;
  180. end;
  181. end;
  182. procedure TFormHeightField.TrackBar3Change(Sender: TObject);
  183. begin
  184. // adjust grid steps (resolution)
  185. with HeightField1 do
  186. begin
  187. XSamplingScale.Step := TrackBar3.position / 1000;
  188. YSamplingScale.Step := TrackBar3.position / 1000;
  189. end;
  190. end;
  191. procedure TFormHeightField.Timer1Timer(Sender: TObject);
  192. begin
  193. // Display number of triangles used in the mesh
  194. // You will note that this number quickly gets out of hand if you are
  195. // using large high-resolution grids
  196. LabelFPS.Caption := Format('%d Triangles - %.2f FPS',
  197. [HeightField1.TriangleCount, GLSceneViewer1.FramesPerSecond]);
  198. GLSceneViewer1.ResetPerformanceMonitor;
  199. end;
  200. // following code takes care of camera movement, see camera & movement demos
  201. // for explanations and more samples
  202. procedure TFormHeightField.GLSceneViewer1MouseDown(Sender: TObject;
  203. Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  204. begin
  205. mx := X;
  206. my := Y;
  207. end;
  208. procedure TFormHeightField.GLSceneViewer1MouseMove(Sender: TObject;
  209. Shift: TShiftState; X, Y: Integer);
  210. begin
  211. if Shift <> [] then
  212. begin
  213. GLCamera1.MoveAroundTarget(my - Y, mx - X);
  214. mx := X;
  215. my := Y;
  216. end;
  217. end;
  218. procedure TFormHeightField.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  219. WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  220. begin
  221. GLCamera1 := GLSceneViewer1.Camera;
  222. GLCamera1.AdjustDistanceToTarget(Power(1.1, WheelDelta / 150));
  223. end;
  224. end.