fPortal.pas 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. unit fPortal;
  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. GLS.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. GLS.Utils;
  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. SetGLSceneMediaDir();
  85. for i := 0 to 15 do
  86. SGMap.Cells[i, i] := 'X';
  87. SGMap.Cells[8, 8] := '';
  88. SGMap.Col := 8;
  89. SGMap.Row := 12;
  90. with GLMaterialLibrary1 do
  91. begin
  92. AddTextureMaterial('gnd', 'walkway.jpg');
  93. with AddTextureMaterial('wall', 'rawwall.jpg') do
  94. begin
  95. TextureScale.Y := 3;
  96. end;
  97. end;
  98. BBProcessClick(Self);
  99. end;
  100. procedure TFormPortal.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  101. WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  102. begin
  103. GLCamera1.AdjustDistanceToTarget(Power(1.1, WheelDelta / 120));
  104. end;
  105. procedure TFormPortal.BBProcessClick(Sender: TObject);
  106. var
  107. X, Y, n: Integer;
  108. h: Single;
  109. Sector: TGLSectorMeshObject;
  110. Poly: TFGPolygon;
  111. begin
  112. h := 3;
  113. portalCount := 0;
  114. triangleCount := 0;
  115. Portal1.MeshObjects.Clear;
  116. for X := -7 to 8 do
  117. for Y := -7 to 8 do
  118. begin
  119. Sector := TGLSectorMeshObject.CreateOwned(Portal1.MeshObjects);
  120. with Sector.Vertices do
  121. begin
  122. n := Count;
  123. Add(X, 0, Y);
  124. Add(X + 1, 0, Y);
  125. Add(X + 1, 0, Y + 1);
  126. Add(X, 0, Y + 1);
  127. Add(X, h, Y);
  128. Add(X + 1, h, Y);
  129. Add(X + 1, h, Y + 1);
  130. Add(X, h, Y + 1);
  131. end;
  132. with Sector.TexCoords do
  133. begin
  134. Add(0, 0, 0);
  135. Add(1, 0, 0);
  136. Add(1, 1, 0);
  137. Add(0, 1, 0);
  138. end;
  139. // ground
  140. Sector.Normals.Add(0, 1, 0);
  141. if SGMap.Cells[X + 7, Y + 7] = '' then
  142. begin
  143. Poly := TFGPolygon.CreateOwned(Sector.FaceGroups);
  144. with Poly do
  145. begin
  146. MaterialName := 'gnd';
  147. Add(n + 0, 0, 0);
  148. Add(n + 3, 0, 3);
  149. Add(n + 2, 0, 2);
  150. Add(n + 1, 0, 1);
  151. end;
  152. end;
  153. // front wall
  154. Sector.Normals.Add(0, 0, 1);
  155. if (Y = -7) or (SGMap.Cells[X + 7, Y - 1 + 7] <> '') then
  156. begin
  157. Poly := TFGPolygon.CreateOwned(Sector.FaceGroups);
  158. Poly.MaterialName := 'wall';
  159. Inc(triangleCount, 2);
  160. end
  161. else
  162. begin
  163. Poly := TFGPortalPolygon.CreateOwned(Sector.FaceGroups);
  164. TFGPortalPolygon(Poly).DestinationSectorIndex := (X + 7) * 16 +
  165. (Y - 1 + 7);
  166. Inc(portalCount);
  167. end;
  168. with Poly do
  169. begin
  170. Add(n + 0, 1, 3);
  171. Add(n + 1, 1, 2);
  172. Add(n + 5, 1, 1);
  173. Add(n + 4, 1, 0);
  174. end;
  175. // left wall
  176. Sector.Normals.Add(1, 0, 0);
  177. if (X = -7) or (SGMap.Cells[X - 1 + 7, Y + 7] <> '') then
  178. begin
  179. Poly := TFGPolygon.CreateOwned(Sector.FaceGroups);
  180. Poly.MaterialName := 'wall';
  181. Inc(triangleCount, 2);
  182. end
  183. else
  184. begin
  185. Poly := TFGPortalPolygon.CreateOwned(Sector.FaceGroups);
  186. TFGPortalPolygon(Poly).DestinationSectorIndex := (X - 1 + 7) * 16
  187. + (Y + 7);
  188. Inc(portalCount);
  189. end;
  190. with Poly do
  191. begin
  192. Add(n + 4, 2, 1);
  193. Add(n + 7, 2, 0);
  194. Add(n + 3, 2, 3);
  195. Add(n + 0, 2, 2);
  196. end;
  197. // right wall
  198. Sector.Normals.Add(-1, 0, 0);
  199. if (X = 8) or (SGMap.Cells[X + 1 + 7, Y + 7] <> '') then
  200. begin
  201. Poly := TFGPolygon.CreateOwned(Sector.FaceGroups);
  202. Poly.MaterialName := 'wall';
  203. Inc(triangleCount, 2);
  204. end
  205. else
  206. begin
  207. Poly := TFGPortalPolygon.CreateOwned(Sector.FaceGroups);
  208. TFGPortalPolygon(Poly).DestinationSectorIndex := (X + 1 + 7) * 16
  209. + (Y + 7);
  210. Inc(portalCount);
  211. end;
  212. with Poly do
  213. begin
  214. Add(n + 1, 3, 3);
  215. Add(n + 2, 3, 2);
  216. Add(n + 6, 3, 1);
  217. Add(n + 5, 3, 0);
  218. end;
  219. // back wall
  220. Sector.Normals.Add(0, 0, 1);
  221. if (Y = 8) or (SGMap.Cells[X + 7, Y + 1 + 7] <> '') then
  222. begin
  223. Poly := TFGPolygon.CreateOwned(Sector.FaceGroups);
  224. Poly.MaterialName := 'wall';
  225. Inc(triangleCount, 2);
  226. end
  227. else
  228. begin
  229. Poly := TFGPortalPolygon.CreateOwned(Sector.FaceGroups);
  230. TFGPortalPolygon(Poly).DestinationSectorIndex := (X + 7) * 16 +
  231. (Y + 1 + 7);
  232. Inc(portalCount);
  233. end;
  234. with Poly do
  235. begin
  236. Add(n + 3, 4, 2);
  237. Add(n + 7, 4, 1);
  238. Add(n + 6, 4, 0);
  239. Add(n + 2, 4, 3);
  240. end;
  241. end;
  242. Portal1.StructureChanged;
  243. end;
  244. procedure TFormPortal.BUTurnLeftClick(Sender: TObject);
  245. begin
  246. DummyCube1.Turn(-15);
  247. GLCamera1.TransformationChanged;
  248. end;
  249. procedure TFormPortal.BUTurnRightClick(Sender: TObject);
  250. begin
  251. DummyCube1.Turn(+15);
  252. GLCamera1.TransformationChanged;
  253. end;
  254. procedure TFormPortal.BUForwardClick(Sender: TObject);
  255. begin
  256. DummyCube1.Move(-0.25);
  257. GLCamera1.TransformationChanged;
  258. end;
  259. procedure TFormPortal.BUBackwardClick(Sender: TObject);
  260. begin
  261. DummyCube1.Move(0.25);
  262. GLCamera1.TransformationChanged;
  263. end;
  264. procedure TFormPortal.Timer1Timer(Sender: TObject);
  265. begin
  266. Caption := Format('%.2f FPS - %d Portals - %d Triangles',
  267. [GLSceneViewer1.FramesPerSecond, portalCount, triangleCount]);
  268. GLSceneViewer1.ResetPerformanceMonitor;
  269. end;
  270. procedure TFormPortal.GLCadencer1Progress(Sender: TObject;
  271. const deltaTime, newTime: Double);
  272. begin
  273. if IsKeyDown('Z') or IsKeyDown('W') then
  274. DummyCube1.Move(-3 * deltaTime)
  275. else if IsKeyDown('S') then
  276. DummyCube1.Move(3 * deltaTime);
  277. if IsKeyDown('A') or IsKeyDown('Q') then
  278. DummyCube1.Turn(-60 * deltaTime)
  279. else if IsKeyDown('D') then
  280. DummyCube1.Turn(60 * deltaTime);
  281. GLCamera1.TransformationChanged;
  282. end;
  283. procedure TFormPortal.GLSceneViewer1MouseDown(Sender: TObject; Button: TMouseButton;
  284. Shift: TShiftState; X, Y: Integer);
  285. begin
  286. mx := X;
  287. my := Y;
  288. end;
  289. procedure TFormPortal.GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState;
  290. X, Y: Integer);
  291. begin
  292. if ssLeft in Shift then
  293. begin
  294. GLCamera1.MoveAroundTarget(my - Y, mx - X);
  295. end;
  296. mx := X;
  297. my := Y;
  298. end;
  299. procedure TFormPortal.SGMapSetEditText(Sender: TObject; ACol, ARow: Integer;
  300. const Value: String);
  301. begin
  302. if CBAuto.Checked then
  303. BBProcessClick(Self);
  304. end;
  305. procedure TFormPortal.CBFogClick(Sender: TObject);
  306. begin
  307. if CBFog.Checked then
  308. GLCamera1.DepthOfView := 11
  309. else
  310. GLCamera1.DepthOfView := 100;
  311. GLSceneViewer1.Buffer.FogEnable := CBFog.Checked;
  312. end;
  313. end.