fPortalD.pas 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. unit fPortalD;
  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.Dialogs,
  13. Vcl.Grids,
  14. Vcl.StdCtrls,
  15. Vcl.ExtCtrls,
  16. Vcl.Imaging.Jpeg,
  17. GLS.Scene,
  18. Stage.VectorTypes,
  19. GLS.PersistentClasses,
  20. Stage.Keyboard,
  21. GLS.Coordinates,
  22. GLS.BaseClasses,
  23. GLS.XCollection,
  24. Stage.Utils,
  25. GLS.Texture,
  26. GLS.VectorFileObjects,
  27. GLS.Objects,
  28. GLS.Cadencer,
  29. GLS.Portal,
  30. GLS.SceneViewer,
  31. GLS.Material,
  32. GLS.SimpleNavigation;
  33. type
  34. TFormPortal = class(TForm)
  35. Label1: TLabel;
  36. GLScene1: TGLScene;
  37. GLSceneViewer1: TGLSceneViewer;
  38. Label2: TLabel;
  39. BUForward: TButton;
  40. BUTurnLeft: TButton;
  41. BUTurnRight: TButton;
  42. BUBackward: TButton;
  43. SGMap: TStringGrid;
  44. GLMaterialLibrary1: TGLMaterialLibrary;
  45. BBProcess: TButton;
  46. GLLightSource1: TGLLightSource;
  47. DummyCube1: TGLDummyCube;
  48. GLCamera1: TGLCamera;
  49. Timer1: TTimer;
  50. GLCadencer1: TGLCadencer;
  51. Portal1: TGLPortal;
  52. Label3: TLabel;
  53. CBAuto: TCheckBox;
  54. CBFog: TCheckBox;
  55. procedure FormCreate(Sender: TObject);
  56. procedure BBProcessClick(Sender: TObject);
  57. procedure BUTurnLeftClick(Sender: TObject);
  58. procedure BUTurnRightClick(Sender: TObject);
  59. procedure BUForwardClick(Sender: TObject);
  60. procedure BUBackwardClick(Sender: TObject);
  61. procedure Timer1Timer(Sender: TObject);
  62. procedure GLCadencer1Progress(Sender: TObject;
  63. const deltaTime, newTime: Double);
  64. procedure SGMapSetEditText(Sender: TObject; ACol, ARow: Integer;
  65. const Value: String);
  66. procedure CBFogClick(Sender: TObject);
  67. procedure GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState;
  68. X, Y: Integer);
  69. procedure GLSceneViewer1MouseDown(Sender: TObject; Button: TMouseButton;
  70. Shift: TShiftState; X, Y: Integer);
  71. procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
  72. WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  73. private
  74. mx, my: Integer;
  75. public
  76. portalCount, triangleCount: Integer;
  77. end;
  78. var
  79. FormPortal: TFormPortal;
  80. implementation
  81. {$R *.DFM}
  82. procedure TFormPortal.FormCreate(Sender: TObject);
  83. var
  84. i: Integer;
  85. begin
  86. var Path: TFileName := GetCurrentAssetPath();
  87. // Load Texture for ground
  88. SetCurrentDir(Path + '\texture');
  89. for i := 0 to 15 do
  90. SGMap.Cells[i, i] := 'X';
  91. SGMap.Cells[8, 8] := '';
  92. SGMap.Col := 8;
  93. SGMap.Row := 12;
  94. with GLMaterialLibrary1 do
  95. begin
  96. AddTextureMaterial('gnd', 'walkway.jpg');
  97. with AddTextureMaterial('wall', 'rawwall.jpg') do
  98. begin
  99. TextureScale.Y := 3;
  100. end;
  101. end;
  102. BBProcessClick(Self);
  103. end;
  104. procedure TFormPortal.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  105. WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  106. begin
  107. GLCamera1.AdjustDistanceToTarget(Power(1.1, WheelDelta / 120));
  108. end;
  109. procedure TFormPortal.BBProcessClick(Sender: TObject);
  110. var
  111. X, Y, n: Integer;
  112. h: Single;
  113. Sector: TGLSectorMeshObject;
  114. Poly: TFGPolygon;
  115. begin
  116. h := 3;
  117. portalCount := 0;
  118. triangleCount := 0;
  119. Portal1.MeshObjects.Clear;
  120. for X := -7 to 8 do
  121. for Y := -7 to 8 do
  122. begin
  123. Sector := TGLSectorMeshObject.CreateOwned(Portal1.MeshObjects);
  124. with Sector.Vertices do
  125. begin
  126. n := Count;
  127. Add(X, 0, Y);
  128. Add(X + 1, 0, Y);
  129. Add(X + 1, 0, Y + 1);
  130. Add(X, 0, Y + 1);
  131. Add(X, h, Y);
  132. Add(X + 1, h, Y);
  133. Add(X + 1, h, Y + 1);
  134. Add(X, h, Y + 1);
  135. end;
  136. with Sector.TexCoords do
  137. begin
  138. Add(0, 0, 0);
  139. Add(1, 0, 0);
  140. Add(1, 1, 0);
  141. Add(0, 1, 0);
  142. end;
  143. // ground
  144. Sector.Normals.Add(0, 1, 0);
  145. if SGMap.Cells[X + 7, Y + 7] = '' then
  146. begin
  147. Poly := TFGPolygon.CreateOwned(Sector.FaceGroups);
  148. with Poly do
  149. begin
  150. MaterialName := 'gnd';
  151. Add(n + 0, 0, 0);
  152. Add(n + 3, 0, 3);
  153. Add(n + 2, 0, 2);
  154. Add(n + 1, 0, 1);
  155. end;
  156. end;
  157. // front wall
  158. Sector.Normals.Add(0, 0, 1);
  159. if (Y = -7) or (SGMap.Cells[X + 7, Y - 1 + 7] <> '') then
  160. begin
  161. Poly := TFGPolygon.CreateOwned(Sector.FaceGroups);
  162. Poly.MaterialName := 'wall';
  163. Inc(triangleCount, 2);
  164. end
  165. else
  166. begin
  167. Poly := TFGPortalPolygon.CreateOwned(Sector.FaceGroups);
  168. TFGPortalPolygon(Poly).DestinationSectorIndex := (X + 7) * 16 +
  169. (Y - 1 + 7);
  170. Inc(portalCount);
  171. end;
  172. with Poly do
  173. begin
  174. Add(n + 0, 1, 3);
  175. Add(n + 1, 1, 2);
  176. Add(n + 5, 1, 1);
  177. Add(n + 4, 1, 0);
  178. end;
  179. // left wall
  180. Sector.Normals.Add(1, 0, 0);
  181. if (X = -7) or (SGMap.Cells[X - 1 + 7, Y + 7] <> '') then
  182. begin
  183. Poly := TFGPolygon.CreateOwned(Sector.FaceGroups);
  184. Poly.MaterialName := 'wall';
  185. Inc(triangleCount, 2);
  186. end
  187. else
  188. begin
  189. Poly := TFGPortalPolygon.CreateOwned(Sector.FaceGroups);
  190. TFGPortalPolygon(Poly).DestinationSectorIndex := (X - 1 + 7) * 16
  191. + (Y + 7);
  192. Inc(portalCount);
  193. end;
  194. with Poly do
  195. begin
  196. Add(n + 4, 2, 1);
  197. Add(n + 7, 2, 0);
  198. Add(n + 3, 2, 3);
  199. Add(n + 0, 2, 2);
  200. end;
  201. // right wall
  202. Sector.Normals.Add(-1, 0, 0);
  203. if (X = 8) or (SGMap.Cells[X + 1 + 7, Y + 7] <> '') then
  204. begin
  205. Poly := TFGPolygon.CreateOwned(Sector.FaceGroups);
  206. Poly.MaterialName := 'wall';
  207. Inc(triangleCount, 2);
  208. end
  209. else
  210. begin
  211. Poly := TFGPortalPolygon.CreateOwned(Sector.FaceGroups);
  212. TFGPortalPolygon(Poly).DestinationSectorIndex := (X + 1 + 7) * 16
  213. + (Y + 7);
  214. Inc(portalCount);
  215. end;
  216. with Poly do
  217. begin
  218. Add(n + 1, 3, 3);
  219. Add(n + 2, 3, 2);
  220. Add(n + 6, 3, 1);
  221. Add(n + 5, 3, 0);
  222. end;
  223. // back wall
  224. Sector.Normals.Add(0, 0, 1);
  225. if (Y = 8) or (SGMap.Cells[X + 7, Y + 1 + 7] <> '') then
  226. begin
  227. Poly := TFGPolygon.CreateOwned(Sector.FaceGroups);
  228. Poly.MaterialName := 'wall';
  229. Inc(triangleCount, 2);
  230. end
  231. else
  232. begin
  233. Poly := TFGPortalPolygon.CreateOwned(Sector.FaceGroups);
  234. TFGPortalPolygon(Poly).DestinationSectorIndex := (X + 7) * 16 +
  235. (Y + 1 + 7);
  236. Inc(portalCount);
  237. end;
  238. with Poly do
  239. begin
  240. Add(n + 3, 4, 2);
  241. Add(n + 7, 4, 1);
  242. Add(n + 6, 4, 0);
  243. Add(n + 2, 4, 3);
  244. end;
  245. end;
  246. Portal1.StructureChanged;
  247. end;
  248. procedure TFormPortal.BUTurnLeftClick(Sender: TObject);
  249. begin
  250. DummyCube1.Turn(-15);
  251. GLCamera1.TransformationChanged;
  252. end;
  253. procedure TFormPortal.BUTurnRightClick(Sender: TObject);
  254. begin
  255. DummyCube1.Turn(+15);
  256. GLCamera1.TransformationChanged;
  257. end;
  258. procedure TFormPortal.BUForwardClick(Sender: TObject);
  259. begin
  260. DummyCube1.Move(-0.25);
  261. GLCamera1.TransformationChanged;
  262. end;
  263. procedure TFormPortal.BUBackwardClick(Sender: TObject);
  264. begin
  265. DummyCube1.Move(0.25);
  266. GLCamera1.TransformationChanged;
  267. end;
  268. procedure TFormPortal.Timer1Timer(Sender: TObject);
  269. begin
  270. Caption := Format('%.2f FPS - %d Portals - %d Triangles',
  271. [GLSceneViewer1.FramesPerSecond, portalCount, triangleCount]);
  272. GLSceneViewer1.ResetPerformanceMonitor;
  273. end;
  274. procedure TFormPortal.GLCadencer1Progress(Sender: TObject;
  275. const deltaTime, newTime: Double);
  276. begin
  277. if IsKeyDown('Z') or IsKeyDown('W') then
  278. DummyCube1.Move(-3 * deltaTime)
  279. else if IsKeyDown('S') then
  280. DummyCube1.Move(3 * deltaTime);
  281. if IsKeyDown('A') or IsKeyDown('Q') then
  282. DummyCube1.Turn(-60 * deltaTime)
  283. else if IsKeyDown('D') then
  284. DummyCube1.Turn(60 * deltaTime);
  285. GLCamera1.TransformationChanged;
  286. end;
  287. procedure TFormPortal.GLSceneViewer1MouseDown(Sender: TObject; Button: TMouseButton;
  288. Shift: TShiftState; X, Y: Integer);
  289. begin
  290. mx := X;
  291. my := Y;
  292. end;
  293. procedure TFormPortal.GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState;
  294. X, Y: Integer);
  295. begin
  296. if ssLeft in Shift then
  297. begin
  298. GLCamera1.MoveAroundTarget(my - Y, mx - X);
  299. end;
  300. mx := X;
  301. my := Y;
  302. end;
  303. procedure TFormPortal.SGMapSetEditText(Sender: TObject; ACol, ARow: Integer;
  304. const Value: String);
  305. begin
  306. if CBAuto.Checked then
  307. BBProcessClick(Self);
  308. end;
  309. procedure TFormPortal.CBFogClick(Sender: TObject);
  310. begin
  311. if CBFog.Checked then
  312. GLCamera1.DepthOfView := 11
  313. else
  314. GLCamera1.DepthOfView := 100;
  315. GLSceneViewer1.Buffer.FogEnable := CBFog.Checked;
  316. end;
  317. end.