fdEarth.pas 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655
  1. unit fdEarth;
  2. interface
  3. uses
  4. Winapi.OpenGL,
  5. Winapi.OpenGLext,
  6. System.SysUtils,
  7. System.Classes,
  8. System.Types,
  9. System.Math,
  10. System.ImageList,
  11. Vcl.Graphics,
  12. Vcl.Controls,
  13. Vcl.Forms,
  14. Vcl.ExtCtrls,
  15. Vcl.Imaging.Jpeg,
  16. Vcl.Imaging.pngimage,
  17. Vcl.Menus,
  18. Vcl.ComCtrls,
  19. Vcl.BaseImageCollection,
  20. Vcl.ImageCollection,
  21. Vcl.ImgList,
  22. Vcl.VirtualImageList,
  23. Stage.VectorTypes,
  24. Stage.VectorGeometry,
  25. GLS.Material,
  26. GLS.Cadencer,
  27. GLS.LensFlare,
  28. GLS.Scene,
  29. GLS.Objects,
  30. GLS.Coordinates,
  31. GLS.SkyDome,
  32. GLS.SceneViewer,
  33. GLS.Texture,
  34. GLS.RenderContextInfo,
  35. GLS.Color,
  36. GLS.State,
  37. Stage.Utils,
  38. GLS.Context,
  39. Stage.TextureFormat,
  40. GLSL.TextureShaders,
  41. GLS.BaseClasses,
  42. GLS.PersistentClasses,
  43. GLS.GeomObjects;
  44. type
  45. TFormEarth = class(TForm)
  46. GLScene: TGLScene;
  47. GLSceneViewer: TGLSceneViewer;
  48. Camera: TGLCamera;
  49. sfEarth: TGLSphere;
  50. LightSourceSun: TGLLightSource;
  51. DirectOpenGL: TGLDirectOpenGL;
  52. GLCadencer: TGLCadencer;
  53. Timer: TTimer;
  54. sfMoon: TGLSphere;
  55. dcEarth: TGLDummyCube;
  56. dcMoon: TGLDummyCube;
  57. LensFlareSun: TGLLensFlare;
  58. GLPlanetMaps: TGLMaterialLibrary;
  59. GLEarthCombiner: TGLTexCombineShader;
  60. Cameracontroller: TGLCamera;
  61. SkyDome: TGLSkyDome;
  62. ConstellationLines: TGLLines;
  63. MainMenu: TMainMenu;
  64. File1: TMenuItem;
  65. Open1: TMenuItem;
  66. Save1: TMenuItem;
  67. SaveAs1: TMenuItem;
  68. Exit1: TMenuItem;
  69. N1: TMenuItem;
  70. miView: TMenuItem;
  71. Hide1: TMenuItem;
  72. Show1: TMenuItem;
  73. N3: TMenuItem;
  74. Help1: TMenuItem;
  75. About1: TMenuItem;
  76. PanelLeft: TPanel;
  77. tvPlanets: TTreeView;
  78. miConstLines: TMenuItem;
  79. VirtPlanetSymbols: TVirtualImageList;
  80. PlanetSymbols: TImageCollection;
  81. sfMercury: TGLSphere;
  82. dcSolarSystem: TGLDummyCube;
  83. sfSun: TGLSphere;
  84. sfVenus: TGLSphere;
  85. sfMars: TGLSphere;
  86. sfJupiter: TGLSphere;
  87. sfSaturn: TGLSphere;
  88. sfNeptune: TGLSphere;
  89. sfUranus: TGLSphere;
  90. sfPluto: TGLSphere;
  91. sfCharon: TGLSphere;
  92. sfEnceladus: TGLSphere;
  93. sfTitan: TGLSphere;
  94. sfIo: TGLSphere;
  95. sfEuropa: TGLSphere;
  96. sfCallisto: TGLSphere;
  97. sfGanymede: TGLSphere;
  98. sfDeimos: TGLSphere;
  99. sfPhobos: TGLSphere;
  100. diskSaturnUp: TGLDisk;
  101. diskSaturnDn: TGLDisk;
  102. procedure FormCreate(Sender: TObject);
  103. procedure DirectOpenGLRender(Sender: TObject; var rci: TGLRenderContextInfo);
  104. procedure TimerTimer(Sender: TObject);
  105. procedure GLCadencerProgress(Sender: TObject; const deltaTime, newTime: Double);
  106. procedure GLSceneViewerMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
  107. X, Y: Integer);
  108. procedure GLSceneViewerMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
  109. procedure FormMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer;
  110. MousePos: TPoint; var Handled: Boolean);
  111. procedure GLSceneViewerDblClick(Sender: TObject);
  112. procedure FormKeyPress(Sender: TObject; var Key: Char);
  113. procedure GLSceneViewerBeforeRender(Sender: TObject);
  114. procedure Exit1Click(Sender: TObject);
  115. procedure tvPlanetsClick(Sender: TObject);
  116. procedure miConstLinesClick(Sender: TObject);
  117. procedure miConstBoundariesClick(Sender: TObject);
  118. procedure Hide1Click(Sender: TObject);
  119. procedure Show1Click(Sender: TObject);
  120. public
  121. ConstellationsAlpha: Single;
  122. TimeMultiplier: Single;
  123. mx, my, dmx, dmy: Integer;
  124. HighResResourcesLoaded: Boolean;
  125. CameraTimeSteps: Single;
  126. radius, invAtmosphereHeight: Single;
  127. sunPos, eyePos, lightingVector: TGLVector;
  128. diskNormal, diskRight, diskUp: TGLVector;
  129. procedure LoadHighResTexture(LibMat: TGLLibMaterial; const FileName: string);
  130. private
  131. FileName, Path: TFileName;
  132. procedure LoadConstellationLines;
  133. function AtmosphereColor(const rayStart, rayEnd: TGLVector): TGLColorVector;
  134. function ComputeColor(var rayDest: TGLVector; mayHitGround: Boolean): TGLColorVector;
  135. end;
  136. var
  137. FormEarth: TFormEarth;
  138. const
  139. cOpacity: Single = 5;
  140. // unrealisticly thick atmospheres look better :)
  141. cAtmosphereRadius: Single = 0.55;
  142. // use value slightly lower than actual radius, for antialiasing effect
  143. cEarthRadius: Single = 0.495;
  144. cLowAtmColor: TGLColorVector = (X: 1; Y: 1; Z: 1; W: 1);
  145. cHighAtmColor: TGLColorVector = (X: 0; Y: 0; Z: 1; W: 1);
  146. cIntDivTable: array [2 .. 20] of Single = (1 / 2, 1 / 3, 1 / 4, 1 / 5, 1 / 6, 1 / 7, 1 / 8, 1 / 9,
  147. 1 / 10, 1 / 11, 1 / 12, 1 / 13, 1 / 14, 1 / 15, 1 / 16, 1 / 17, 1 / 18, 1 / 19, 1 / 20);
  148. implementation //==============================================================
  149. {$R *.dfm}
  150. procedure TFormEarth.FormCreate(Sender: TObject);
  151. begin
  152. Path := GetCurrentAssetPath();
  153. // dir for star catalog
  154. SetCurrentDir(Path + '\data');
  155. FileName := 'Yale_BSC.stars';
  156. SkyDome.Bands.Clear;
  157. if FileExists(FileName) then
  158. SkyDome.Stars.LoadStarsFile(FileName);
  159. LoadConstellationLines;
  160. TimeMultiplier := 1;
  161. tvPlanets.Select(tvPlanets.Items[3]);
  162. tvPlanets.FullExpand;
  163. // dir for maps of planets
  164. SetCurrentDir(Path + '\map');
  165. end;
  166. //--------------------------------------------------------------------------------
  167. procedure TFormEarth.GLSceneViewerBeforeRender(Sender: TObject);
  168. begin
  169. LensFlareSun.PreRender(Sender as TGLSceneBuffer);
  170. // if no multitexturing or no combiner support, turn off city lights
  171. GLPlanetMaps.Materials[0].Shader := GLEarthCombiner;
  172. GLPlanetMaps.Materials[0].Texture2Name := 'earthNight';
  173. end;
  174. //--------------------------------------------------------------------------------
  175. function TFormEarth.AtmosphereColor(const rayStart, rayEnd: TGLVector): TGLColorVector;
  176. var
  177. i, n: Integer;
  178. atmPoint, normal: TGLVector;
  179. altColor: TGLColorVector;
  180. alt, rayLength, contrib, decay, intensity, invN: Single;
  181. begin
  182. Result := clrTransparent;
  183. rayLength := VectorDistance(rayStart, rayEnd);
  184. n := Round(3 * rayLength * invAtmosphereHeight) + 2;
  185. if n > 10 then
  186. n := 10;
  187. invN := cIntDivTable[n]; // 1/n;
  188. contrib := rayLength * invN * cOpacity;
  189. decay := 1 - contrib * 0.5;
  190. contrib := contrib * (1 / 1.1);
  191. for i := n - 1 downto 0 do
  192. begin
  193. VectorLerp(rayStart, rayEnd, i * invN, atmPoint);
  194. // diffuse lighting normal
  195. normal := VectorNormalize(atmPoint);
  196. // diffuse lighting intensity
  197. intensity := VectorDotProduct(normal, lightingVector) + 0.1;
  198. if PInteger(@intensity)^ > 0 then
  199. begin
  200. // sample on the lit side
  201. intensity := intensity * contrib;
  202. alt := (VectorLength(atmPoint) - cEarthRadius) * invAtmosphereHeight;
  203. VectorLerp(cLowAtmColor, cHighAtmColor, alt, altColor);
  204. Result.X := Result.X * decay + altColor.X * intensity;
  205. Result.Y := Result.Y * decay + altColor.Y * intensity;
  206. Result.Z := Result.Z * decay + altColor.Z * intensity;
  207. end
  208. else
  209. begin
  210. // sample on the dark sid
  211. Result.X := Result.X * decay;
  212. Result.Y := Result.Y * decay;
  213. Result.Z := Result.Z * decay;
  214. end;
  215. end;
  216. Result.W := n * contrib * cOpacity * 0.1;
  217. end;
  218. //-----------------------------------------------------------------------
  219. function TFormEarth.ComputeColor(var rayDest: TGLVector; mayHitGround: Boolean): TGLColorVector;
  220. var
  221. ai1, ai2, pi1, pi2: TGLVector;
  222. rayVector: TGLVector;
  223. begin
  224. rayVector := VectorNormalize(VectorSubtract(rayDest, eyePos));
  225. if RayCastSphereIntersect(eyePos, rayVector, NullHmgPoint, cAtmosphereRadius, ai1, ai2) > 1 then
  226. begin
  227. // atmosphere hit
  228. if mayHitGround and (RayCastSphereIntersect(eyePos, rayVector, NullHmgPoint,
  229. cEarthRadius, pi1,
  230. pi2) > 0) then
  231. begin
  232. // hit ground
  233. Result := AtmosphereColor(ai1, pi1);
  234. end
  235. else
  236. begin
  237. // through atmosphere only
  238. Result := AtmosphereColor(ai1, ai2);
  239. end;
  240. rayDest := ai1;
  241. end
  242. else
  243. Result := clrTransparent;
  244. end;
  245. //------------------------------------------------------------------------
  246. // DirectOpenGLRender for atmosphere
  247. //------------------------------------------------------------------------
  248. procedure TFormEarth.DirectOpenGLRender(Sender: TObject; var rci: TGLRenderContextInfo);
  249. const
  250. cSlices = 60;
  251. var
  252. i, j, k0, k1: Integer;
  253. cosCache, sinCache: array [0 .. cSlices] of Single;
  254. pVertex, pColor: PVectorArray;
  255. begin
  256. sunPos := LightSourceSun.AbsolutePosition;
  257. eyePos := Camera.AbsolutePosition;
  258. diskNormal := VectorNegate(eyePos);
  259. NormalizeVector(diskNormal);
  260. diskRight := VectorCrossProduct(Camera.AbsoluteUp, diskNormal);
  261. NormalizeVector(diskRight);
  262. diskUp := VectorCrossProduct(diskNormal, diskRight);
  263. NormalizeVector(diskUp);
  264. invAtmosphereHeight := 1 / (cAtmosphereRadius - cEarthRadius);
  265. lightingVector := VectorNormalize(sunPos); // sun at infinity
  266. PrepareSinCosCache(sinCache, cosCache, 0, 360);
  267. GetMem(pVertex, 2 * (cSlices + 1) * SizeOf(TGLVector));
  268. GetMem(pColor, 2 * (cSlices + 1) * SizeOf(TGLVector));
  269. rci.GLStates.DepthWriteMask := False;
  270. rci.GLStates.Disable(stLighting);
  271. rci.GLStates.Enable(stBlend);
  272. rci.GLStates.SetBlendFunc(bfSrcAlpha, bfOneMinusSrcAlpha);
  273. for i := 0 to 13 do
  274. begin
  275. if i < 5 then
  276. radius := cEarthRadius * Sqrt(i * (1 / 5))
  277. else
  278. radius := cEarthRadius + (i - 5.1) * (cAtmosphereRadius - cEarthRadius) * (1 / 6.9);
  279. radius := SphereVisibleRadius(VectorLength(eyePos), radius);
  280. k0 := (i and 1) * (cSlices + 1);
  281. k1 := (cSlices + 1) - k0;
  282. for j := 0 to cSlices do
  283. begin
  284. VectorCombine(diskRight, diskUp, cosCache[j] * radius, sinCache[j] * radius, pVertex[k0 + j]);
  285. if i < 13 then
  286. pColor[k0 + j] := ComputeColor(pVertex[k0 + j], i <= 7);
  287. if i = 0 then
  288. Break;
  289. end;
  290. if i > 1 then
  291. begin
  292. if i = 13 then
  293. begin
  294. glBegin(GL_QUAD_STRIP);
  295. for j := cSlices downto 0 do
  296. begin
  297. glColor4fv(@pColor[k1 + j]);
  298. glVertex3fv(@pVertex[k1 + j]);
  299. glColor4fv(@clrTransparent);
  300. glVertex3fv(@pVertex[k0 + j]);
  301. end;
  302. glEnd;
  303. end
  304. else
  305. begin
  306. glBegin(GL_QUAD_STRIP);
  307. for j := cSlices downto 0 do
  308. begin
  309. glColor4fv(@pColor[k1 + j]);
  310. glVertex3fv(@pVertex[k1 + j]);
  311. glColor4fv(@pColor[k0 + j]);
  312. glVertex3fv(@pVertex[k0 + j]);
  313. end;
  314. glEnd;
  315. end;
  316. end
  317. else if i = 1 then
  318. begin
  319. glBegin(GL_TRIANGLE_FAN);
  320. glColor4fv(@pColor[k1]);
  321. glVertex3fv(@pVertex[k1]);
  322. for j := k0 + cSlices downto k0 do
  323. begin
  324. glColor4fv(@pColor[j]);
  325. glVertex3fv(@pVertex[j]);
  326. end;
  327. glEnd;
  328. end;
  329. end;
  330. rci.GLStates.DepthWriteMask := True;
  331. FreeMem(pVertex);
  332. FreeMem(pColor);
  333. end;
  334. //-------------------------------------------------
  335. // Constellation Lines
  336. //-------------------------------------------------
  337. procedure TFormEarth.LoadConstellationLines;
  338. var
  339. sl, line: TStrings;
  340. pos1, pos2: TAffineVector;
  341. i: Integer;
  342. begin
  343. sl := TStringList.Create;
  344. line := TStringList.Create;
  345. sl.LoadFromFile('ConstellationLines.dat');
  346. for i := 0 to sl.Count - 1 do
  347. begin
  348. line.CommaText := sl[i];
  349. pos1 := LonLatToPos(StrToFloatDef(line[0], 0), StrToFloatDef(line[1], 0));
  350. ConstellationLines.AddNode(pos1);
  351. pos2 := LonLatToPos(StrToFloatDef(line[2], 0), StrToFloatDef(line[3], 0));
  352. ConstellationLines.AddNode(pos2);
  353. end;
  354. sl.Free;
  355. line.Free;
  356. end;
  357. //----------------------------------------------------------------------------
  358. procedure TFormEarth.miConstLinesClick(Sender: TObject);
  359. begin
  360. ConstellationsAlpha := 0.5 - ConstellationsAlpha;
  361. end;
  362. procedure TFormEarth.miConstBoundariesClick(Sender: TObject);
  363. begin
  364. ConstellationsAlpha := 0.5 - ConstellationsAlpha;
  365. end;
  366. //-----------------------------------------------------------------------------
  367. procedure TFormEarth.TimerTimer(Sender: TObject);
  368. begin
  369. Caption := Format('Earth ' + '%.1f FPS', [GLSceneViewer.FramesPerSecond]);
  370. GLSceneViewer.ResetPerformanceMonitor;
  371. end;
  372. //---------------------------------------------------------------------------
  373. procedure TFormEarth.tvPlanetsClick(Sender: TObject);
  374. var
  375. I: Integer;
  376. begin
  377. for I := 0 to dcSolarSystem.Count - 1 do
  378. dcSolarSystem.Children[I].Visible := False;
  379. case tvPlanets.Selected.StateIndex of
  380. 0: begin
  381. sfSun.Visible := True;
  382. end;
  383. 1: begin
  384. sfMercury.Visible := True;
  385. end;
  386. 2: begin
  387. sfVenus.Visible := True;
  388. end;
  389. 3: begin
  390. Camera.MoveTo(sfEarth);
  391. Cameracontroller.MoveTo(sfEarth);
  392. Camera.TargetObject := sfEarth;
  393. Cameracontroller.TargetObject := sfEarth;
  394. end;
  395. 4: begin
  396. Camera.MoveTo(sfMoon);
  397. Cameracontroller.MoveTo(sfMoon);
  398. Camera.TargetObject := sfMoon;
  399. Cameracontroller.TargetObject := sfMoon;
  400. end;
  401. 5: begin
  402. sfMars.Visible := True;
  403. end;
  404. 6: begin
  405. // to be replaced with ffDeimos
  406. sfDeimos.Visible := True;
  407. end;
  408. 7: begin
  409. // to be replaced with ffPhobos
  410. sfPhobos.Visible := True;
  411. end;
  412. 8: begin
  413. sfJupiter.Visible := True;
  414. end;
  415. 9: begin
  416. sfIo.Visible := True;
  417. end;
  418. 10: begin
  419. sfEuropa.Visible := True;
  420. end;
  421. 11: begin
  422. sfCallisto.Visible := True;
  423. end;
  424. 12: begin
  425. sfGanymede.Visible := True;
  426. end;
  427. 13: begin
  428. // with rings
  429. sfSaturn.Visible := True;
  430. diskSaturnUp.Visible := True;
  431. diskSaturnDn.Visible := True;
  432. end;
  433. 14: begin
  434. sfEnceladus.Visible := True;
  435. end;
  436. 15: begin
  437. sfTitan.Visible := True;
  438. end;
  439. 16: begin
  440. sfUranus.Visible := True;
  441. end;
  442. 17: begin
  443. sfNeptune.Visible := True;
  444. end;
  445. 18: begin
  446. sfPluto.Visible := True;
  447. end;
  448. 19: begin
  449. sfCharon.Visible := True;
  450. end;
  451. end;
  452. end;
  453. //--------------------------------------------------------------------------------
  454. procedure TFormEarth.GLCadencerProgress(Sender: TObject; const deltaTime, newTime: Double);
  455. var
  456. d : Double;
  457. p : TAffineVector;
  458. begin
  459. d := GMTDateTimeToJulianDay(Now-2+newTime*timeMultiplier);
  460. sfEarth.TurnAngle := sfEarth.TurnAngle + deltaTime * TimeMultiplier;
  461. p := ComputePlanetPosition(cSunOrbitalElements, d);
  462. ScaleVector(p, 0.5*cAUToKilometers*(1/cEarthRadius));
  463. LensFlareSun.Position.AsAffineVector := p;
  464. // moon rotates on itself and around earth (not sure about the rotation direction!)
  465. p := ComputePlanetPosition(cMoonOrbitalElements, d);
  466. ScaleVector(p, 0.5*cAUToKilometers*(1/cEarthRadius));
  467. dcMoon.TurnAngle := dcMoon.TurnAngle + deltaTime * TimeMultiplier / 29.5;
  468. sfMoon.TurnAngle := 180 - dcMoon.TurnAngle;
  469. // Honour camera movements
  470. if (dmy <> 0) or (dmx <> 0) then
  471. begin
  472. Cameracontroller.MoveAroundTarget(ClampValue(dmy * 0.3, -5, 5), ClampValue(dmx * 0.3, -5, 5));
  473. dmx := 0;
  474. dmy := 0;
  475. end;
  476. // This gives us smoother camera movements
  477. CameraTimeSteps := CameraTimeSteps + deltaTime;
  478. while CameraTimeSteps > 0.005 do
  479. begin
  480. Camera.Position.AsVector := VectorLerp(Camera.Position.AsVector,
  481. Cameracontroller.Position.AsVector, 0.05);
  482. CameraTimeSteps := CameraTimeSteps - 0.005;
  483. end;
  484. // Smooth constellation lines appearance/disappearance
  485. if ConstellationLines.LineColor.Alpha <> ConstellationsAlpha then
  486. begin
  487. ConstellationLines.LineColor.Alpha :=
  488. ClampValue(ConstellationLines.LineColor.Alpha +
  489. Sign(ConstellationsAlpha - ConstellationLines.LineColor.Alpha) * deltaTime, 0, 0.5);
  490. ConstellationLines.Visible := (ConstellationLines.LineColor.Alpha > 0);
  491. end;
  492. end;
  493. //--------------------------------------------------------------------------------
  494. procedure TFormEarth.GLSceneViewerMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
  495. X, Y: Integer);
  496. begin
  497. mx := X;
  498. my := Y;
  499. end;
  500. //---------------------------------------------------------------------------
  501. procedure TFormEarth.GLSceneViewerMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
  502. begin
  503. if Shift = [ssLeft] then
  504. begin
  505. dmx := dmx + (mx - X);
  506. dmy := dmy + (my - Y);
  507. end
  508. else if Shift = [ssRight] then
  509. Camera.FocalLength := Camera.FocalLength * Power(1.05, (my - Y) * 0.1);
  510. mx := X;
  511. my := Y;
  512. end;
  513. //---------------------------------------------------------------------------
  514. procedure TFormEarth.Hide1Click(Sender: TObject);
  515. begin
  516. PanelLeft.Visible := False;
  517. end;
  518. procedure TFormEarth.Show1Click(Sender: TObject);
  519. begin
  520. PanelLeft.Visible := True;
  521. end;
  522. //--------------------------------------------------------------------------------
  523. procedure TFormEarth.FormMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer;
  524. MousePos: TPoint; var Handled: Boolean);
  525. var
  526. f: Single;
  527. begin
  528. if (WheelDelta > 0) or (Cameracontroller.Position.VectorLength > 0.90) then
  529. begin
  530. f := Power(1.05, WheelDelta * (1 / 120));
  531. Cameracontroller.AdjustDistanceToTarget(f);
  532. end;
  533. Handled := True;
  534. end;
  535. //--------------------------------------------------------------------------------
  536. procedure TFormEarth.GLSceneViewerDblClick(Sender: TObject);
  537. begin
  538. GLSceneViewer.OnMouseMove := nil;
  539. if WindowState = wsMaximized then
  540. begin
  541. WindowState := wsNormal;
  542. BorderStyle := bsSizeToolWin;
  543. end
  544. else
  545. begin
  546. BorderStyle := bsNone;
  547. WindowState := wsMaximized;
  548. end;
  549. GLSceneViewer.OnMouseMove := GLSceneViewerMouseMove;
  550. end;
  551. //---------------------------------------------------------------------------
  552. procedure TFormEarth.LoadHighResTexture(LibMat: TGLLibMaterial; const FileName: string);
  553. begin
  554. if FileExists(FileName) then
  555. begin
  556. LibMat.Material.Texture.Compression := tcStandard;
  557. LibMat.Material.Texture.Image.LoadFromFile(FileName);
  558. end;
  559. end;
  560. //---------------------------------------------------------------------------
  561. procedure TFormEarth.FormKeyPress(Sender: TObject; var Key: Char);
  562. begin
  563. case Key of
  564. #27:
  565. FormEarth.Close;
  566. 'm', 'M':
  567. begin
  568. Camera.MoveTo(sfMoon);
  569. Cameracontroller.MoveTo(sfMoon);
  570. Camera.TargetObject := sfMoon;
  571. Cameracontroller.TargetObject := sfMoon;
  572. end;
  573. 'e', 'E':
  574. begin
  575. Camera.MoveTo(dcEarth);
  576. Cameracontroller.MoveTo(dcEarth);
  577. Camera.TargetObject := dcEarth;
  578. Cameracontroller.TargetObject := dcEarth;
  579. end;
  580. 'h':
  581. if not HighResResourcesLoaded then
  582. begin
  583. GLSceneViewer.Cursor := crHourGlass;
  584. try
  585. LoadHighResTexture(GLPlanetMaps.Materials[0], 'earth_4096.jpg');
  586. LoadHighResTexture(GLPlanetMaps.Materials[1], 'earth_night_4096.jpg');
  587. LoadHighResTexture(GLPlanetMaps.Materials[2], 'moon_2048.jpg');
  588. GLSceneViewer.Buffer.AntiAliasing := aa2x;
  589. finally
  590. GLSceneViewer.Cursor := crDefault;
  591. end;
  592. HighResResourcesLoaded := True;
  593. end;
  594. 'c':
  595. ConstellationsAlpha := 0.5 - ConstellationsAlpha;
  596. '0' .. '9':
  597. TimeMultiplier := Power(Integer(Key) - Integer('0'), 3);
  598. end;
  599. end;
  600. //---------------------------------------------------------------------------
  601. procedure TFormEarth.Exit1Click(Sender: TObject);
  602. begin
  603. Close;
  604. end;
  605. end.