fTiles.pas 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. unit fTiles;
  2. interface
  3. uses
  4. Winapi.OpenGL,
  5. Winapi.Windows,
  6. System.SysUtils,
  7. System.Classes,
  8. System.Math,
  9. Vcl.Graphics,
  10. Vcl.Controls,
  11. Vcl.Forms,
  12. Vcl.Dialogs,
  13. Vcl.ExtCtrls,
  14. Vcl.Imaging.Jpeg,
  15. Vcl.StdCtrls,
  16. GLS.VectorTypes,
  17. GLS.Objects,
  18. GLS.Graph,
  19. GLS.Scene,
  20. GLS.SceneViewer,
  21. GLS.VectorGeometry,
  22. GLS.TilePlane,
  23. GLS.Texture,
  24. GLS.Cadencer,
  25. GLS.Context,
  26. GLS.Material,
  27. GLS.Coordinates,
  28. GLS.BaseClasses,
  29. GLS.RenderContextInfo,
  30. GLS.TextureFormat,
  31. GLS.Keyboard,
  32. GLS.Utils, GLS.SimpleNavigation;
  33. type
  34. TFormTiles = class(TForm)
  35. GLScene: TGLScene;
  36. GLSceneViewer1: TGLSceneViewer;
  37. GLCamera: TGLCamera;
  38. DCTarget: TGLDummyCube;
  39. GLXYZGrid: TGLXYZGrid;
  40. Panel1: TPanel;
  41. GLMaterialLibrary: TGLMaterialLibrary;
  42. GLLightSource: TGLLightSource;
  43. Timer1: TTimer;
  44. GLCadencer1: TGLCadencer;
  45. Label1: TLabel;
  46. CBMaterial: TComboBox;
  47. GLTilePlane: TGLTilePlane;
  48. GLDirectOpenGL: TGLDirectOpenGL;
  49. DCSelection: TGLDummyCube;
  50. GLLines1: TGLLines;
  51. BUPack: TButton;
  52. Label2: TLabel;
  53. CBShowGrid: TCheckBox;
  54. CBSortByMaterials: TCheckBox;
  55. GLSimpleNavigation1: TGLSimpleNavigation;
  56. procedure GLSceneViewer1MouseDown(Sender: TObject; Button: TMouseButton;
  57. Shift: TShiftState; X, Y: Integer);
  58. procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
  59. WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  60. procedure FormCreate(Sender: TObject);
  61. procedure Timer1Timer(Sender: TObject);
  62. procedure GLCadencer1Progress(Sender: TObject;
  63. const deltaTime, newTime: Double);
  64. procedure GLDirectOpenGLRender(Sender: TObject;
  65. var rci: TGLRenderContextInfo);
  66. procedure BUPackClick(Sender: TObject);
  67. procedure CBShowGridClick(Sender: TObject);
  68. procedure CBSortByMaterialsClick(Sender: TObject);
  69. private
  70. public
  71. mx, my: Integer;
  72. tileX, tileY: Integer;
  73. mip, translateOffset: TGLVector;
  74. translating: Boolean;
  75. end;
  76. var
  77. FormTiles: TFormTiles;
  78. implementation
  79. {$R *.dfm}
  80. procedure TFormTiles.FormCreate(Sender: TObject);
  81. var
  82. i, j: Integer;
  83. begin
  84. SetGLSceneMediaDir();
  85. GLMaterialLibrary.TexturePaths := GetCurrentDir();
  86. GLMaterialLibrary.LibMaterialByName('beigemarble').Material.Texture.Image.LoadFromFile('beigemarble.jpg');
  87. GLMaterialLibrary.LibMaterialByName('marbletiles').Material.Texture.Image.LoadFromFile('marbletiles.jpg');
  88. GLMaterialLibrary.LibMaterialByName('walkway').Material.Texture.Image.LoadFromFile('walkway.jpg');
  89. // fill the tiled area with random tiles
  90. RandSeed := 0;
  91. for i := -20 to 20 do
  92. for j := -20 to 20 do
  93. GLTilePlane.Tiles[i, j] :=
  94. Random(GLMaterialLibrary.Materials.Count - 1) + 1;
  95. // set all tile materials to anisotropic,
  96. // add them to the material selection combo
  97. for i := 0 to GLMaterialLibrary.Materials.Count - 1 do
  98. begin
  99. GLMaterialLibrary.Materials[i].Material.Texture.FilteringQuality :=
  100. tfAnisotropic;
  101. CBMaterial.Items.Add(GLMaterialLibrary.Materials[i].Name);
  102. end;
  103. CBMaterial.ItemIndex := 0;
  104. end;
  105. procedure TFormTiles.GLSceneViewer1MouseDown(Sender: TObject; Button: TMouseButton;
  106. Shift: TShiftState; X, Y: Integer);
  107. begin
  108. mx := X;
  109. my := Y;
  110. if Shift = [ssLeft] then
  111. begin
  112. GLTilePlane.Tiles[tileX, tileY] := CBMaterial.ItemIndex;
  113. GLTilePlane.StructureChanged;
  114. end
  115. else if Shift = [ssRight] then
  116. begin
  117. GLTilePlane.Tiles[tileX, tileY] := 0;
  118. GLTilePlane.StructureChanged;
  119. end;
  120. end;
  121. procedure TFormTiles.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  122. WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  123. begin
  124. GLCamera.AdjustDistanceToTarget(Power(1.1, WheelDelta / 120));
  125. end;
  126. procedure TFormTiles.GLCadencer1Progress(Sender: TObject;
  127. const deltaTime, newTime: Double);
  128. var
  129. ip: TGLVector;
  130. mp: TPoint;
  131. shiftDown: Boolean;
  132. begin
  133. shiftDown := (IsKeyDown(VK_LSHIFT) or IsKeyDown(VK_RSHIFT));
  134. DCSelection.Visible := not shiftDown;
  135. if DCSelection.Visible then
  136. GLSceneViewer1.Cursor := crDefault
  137. else
  138. GLSceneViewer1.Cursor := crHandPoint;
  139. GetCursorPos(mp);
  140. mp := GLSceneViewer1.ScreenToClient(mp);
  141. if PtInRect(GLSceneViewer1.ClientRect, mp) then
  142. begin
  143. GLSceneViewer1.Buffer.ScreenVectorIntersectWithPlaneXY
  144. (VectorMake(mp.X, GLSceneViewer1.Height - mp.Y, 0), 0, ip);
  145. tileX := Round(ip.X - 0.5);
  146. tileY := Round(ip.Y - 0.5);
  147. DCSelection.Position.SetPoint(tileX, tileY, 0);
  148. if shiftDown then
  149. begin
  150. if IsKeyDown(VK_LBUTTON) then
  151. begin
  152. if not translating then
  153. begin
  154. translateOffset := ip;
  155. translating := True;
  156. end;
  157. DCTarget.Position.Translate(VectorAdd(VectorSubtract(mip, ip),
  158. translateOffset))
  159. end
  160. else
  161. translating := False;
  162. if IsKeyDown(VK_RBUTTON) then
  163. begin
  164. GLCamera.MoveAroundTarget((my - mp.Y) * 0.5, (mx - mp.X) * 0.5);
  165. end;
  166. end
  167. else
  168. begin
  169. translating := False;
  170. if IsKeyDown(VK_LBUTTON) then
  171. begin
  172. GLTilePlane.Tiles[tileX, tileY] := CBMaterial.ItemIndex;
  173. GLTilePlane.StructureChanged;
  174. end;
  175. if IsKeyDown(VK_RBUTTON) then
  176. begin
  177. GLTilePlane.Tiles[tileX, tileY] := 0;
  178. GLTilePlane.StructureChanged;
  179. end;
  180. end;
  181. mx := mp.X;
  182. my := mp.Y;
  183. end;
  184. GLSceneViewer1.Invalidate;
  185. end;
  186. procedure TFormTiles.GLDirectOpenGLRender(Sender: TObject;
  187. var rci: TGLRenderContextInfo);
  188. begin
  189. // we clear the depth buffer, so that the grid is always in front of the
  190. // tile plane and won't Z-Fight with it
  191. glClear(GL_DEPTH_BUFFER_BIT);
  192. end;
  193. procedure TFormTiles.BUPackClick(Sender: TObject);
  194. begin
  195. // packing a tile area removes unused area from the in-memory structures
  196. GLTilePlane.Tiles.Pack;
  197. end;
  198. procedure TFormTiles.CBShowGridClick(Sender: TObject);
  199. begin
  200. GLXYZGrid.Visible := CBShowGrid.Checked;
  201. end;
  202. procedure TFormTiles.CBSortByMaterialsClick(Sender: TObject);
  203. begin
  204. GLTilePlane.SortByMaterials := CBSortByMaterials.Checked;
  205. end;
  206. procedure TFormTiles.Timer1Timer(Sender: TObject);
  207. begin
  208. Caption := GLSceneViewer1.FramesPerSecondText;
  209. GLSceneViewer1.ResetPerformanceMonitor;
  210. end;
  211. end.