fPortalD.pas 8.3 KB

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