fEarthD.pas 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. unit fEarthD;
  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. GLScene.VectorTypes,
  20. GLScene.VectorGeometry,
  21. GLS.Material,
  22. GLS.Cadencer,
  23. GLS.LensFlare,
  24. GLS.Scene,
  25. GLS.Objects,
  26. GLS.Coordinates,
  27. GLS.SkyDome,
  28. GLS.SceneViewer,
  29. GLS.Texture,
  30. GLS.RenderContextInfo,
  31. GLS.Color,
  32. GLS.State,
  33. GLScene.Utils,
  34. GLS.Context,
  35. GLS.TextureFormat,
  36. GLSL.TextureShaders,
  37. GLS.BaseClasses,
  38. GLS.PersistentClasses,
  39. Vcl.BaseImageCollection,
  40. Vcl.ImageCollection,
  41. Vcl.ImgList,
  42. Vcl.VirtualImageList,
  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. // -----------------------------------------
  149. implementation
  150. // -----------------------------------------
  151. {$R *.dfm}
  152. procedure TFormEarth.FormCreate(Sender: TObject);
  153. begin
  154. Path := GetCurrentAssetPath();
  155. // dir for star catalog
  156. SetCurrentDir(Path + '\data');
  157. FileName := 'Yale_BSC.stars';
  158. SkyDome.Bands.Clear;
  159. if FileExists(FileName) then
  160. SkyDome.Stars.LoadStarsFile(FileName);
  161. LoadConstellationLines;
  162. TimeMultiplier := 1;
  163. tvPlanets.Select(tvPlanets.Items[3]);
  164. tvPlanets.FullExpand;
  165. // dir for maps of planets
  166. SetCurrentDir(Path + '\map');
  167. end;
  168. //--------------------------------------------------------------------------------
  169. procedure TFormEarth.GLSceneViewerBeforeRender(Sender: TObject);
  170. begin
  171. LensFlareSun.PreRender(Sender as TGLSceneBuffer);
  172. // if no multitexturing or no combiner support, turn off city lights
  173. GLPlanetMaps.Materials[0].Shader := GLEarthCombiner;
  174. GLPlanetMaps.Materials[0].Texture2Name := 'earthNight';
  175. end;
  176. //--------------------------------------------------------------------------------
  177. function TFormEarth.AtmosphereColor(const rayStart, rayEnd: TGLVector): TGLColorVector;
  178. var
  179. i, n: Integer;
  180. atmPoint, normal: TGLVector;
  181. altColor: TGLColorVector;
  182. alt, rayLength, contrib, decay, intensity, invN: Single;
  183. begin
  184. Result := clrTransparent;
  185. rayLength := VectorDistance(rayStart, rayEnd);
  186. n := Round(3 * rayLength * invAtmosphereHeight) + 2;
  187. if n > 10 then
  188. n := 10;
  189. invN := cIntDivTable[n]; // 1/n;
  190. contrib := rayLength * invN * cOpacity;
  191. decay := 1 - contrib * 0.5;
  192. contrib := contrib * (1 / 1.1);
  193. for i := n - 1 downto 0 do
  194. begin
  195. VectorLerp(rayStart, rayEnd, i * invN, atmPoint);
  196. // diffuse lighting normal
  197. normal := VectorNormalize(atmPoint);
  198. // diffuse lighting intensity
  199. intensity := VectorDotProduct(normal, lightingVector) + 0.1;
  200. if PInteger(@intensity)^ > 0 then
  201. begin
  202. // sample on the lit side
  203. intensity := intensity * contrib;
  204. alt := (VectorLength(atmPoint) - cEarthRadius) * invAtmosphereHeight;
  205. VectorLerp(cLowAtmColor, cHighAtmColor, alt, altColor);
  206. Result.X := Result.X * decay + altColor.X * intensity;
  207. Result.Y := Result.Y * decay + altColor.Y * intensity;
  208. Result.Z := Result.Z * decay + altColor.Z * intensity;
  209. end
  210. else
  211. begin
  212. // sample on the dark sid
  213. Result.X := Result.X * decay;
  214. Result.Y := Result.Y * decay;
  215. Result.Z := Result.Z * decay;
  216. end;
  217. end;
  218. Result.W := n * contrib * cOpacity * 0.1;
  219. end;
  220. //-----------------------------------------------------------------------
  221. function TFormEarth.ComputeColor(var rayDest: TGLVector; mayHitGround: Boolean): TGLColorVector;
  222. var
  223. ai1, ai2, pi1, pi2: TGLVector;
  224. rayVector: TGLVector;
  225. begin
  226. rayVector := VectorNormalize(VectorSubtract(rayDest, eyePos));
  227. if RayCastSphereIntersect(eyePos, rayVector, NullHmgPoint, cAtmosphereRadius, ai1, ai2) > 1 then
  228. begin
  229. // atmosphere hit
  230. if mayHitGround and (RayCastSphereIntersect(eyePos, rayVector, NullHmgPoint,
  231. cEarthRadius, pi1,
  232. pi2) > 0) then
  233. begin
  234. // hit ground
  235. Result := AtmosphereColor(ai1, pi1);
  236. end
  237. else
  238. begin
  239. // through atmosphere only
  240. Result := AtmosphereColor(ai1, ai2);
  241. end;
  242. rayDest := ai1;
  243. end
  244. else
  245. Result := clrTransparent;
  246. end;
  247. //------------------------------------------------------------------------
  248. // DirectOpenGLRender for atmosphere
  249. //------------------------------------------------------------------------
  250. procedure TFormEarth.DirectOpenGLRender(Sender: TObject; var rci: TGLRenderContextInfo);
  251. const
  252. cSlices = 60;
  253. var
  254. i, j, k0, k1: Integer;
  255. cosCache, sinCache: array [0 .. cSlices] of Single;
  256. pVertex, pColor: PVectorArray;
  257. begin
  258. sunPos := LightSourceSun.AbsolutePosition;
  259. eyePos := Camera.AbsolutePosition;
  260. diskNormal := VectorNegate(eyePos);
  261. NormalizeVector(diskNormal);
  262. diskRight := VectorCrossProduct(Camera.AbsoluteUp, diskNormal);
  263. NormalizeVector(diskRight);
  264. diskUp := VectorCrossProduct(diskNormal, diskRight);
  265. NormalizeVector(diskUp);
  266. invAtmosphereHeight := 1 / (cAtmosphereRadius - cEarthRadius);
  267. lightingVector := VectorNormalize(sunPos); // sun at infinity
  268. PrepareSinCosCache(sinCache, cosCache, 0, 360);
  269. GetMem(pVertex, 2 * (cSlices + 1) * SizeOf(TGLVector));
  270. GetMem(pColor, 2 * (cSlices + 1) * SizeOf(TGLVector));
  271. rci.GLStates.DepthWriteMask := False;
  272. rci.GLStates.Disable(stLighting);
  273. rci.GLStates.Enable(stBlend);
  274. rci.GLStates.SetBlendFunc(bfSrcAlpha, bfOneMinusSrcAlpha);
  275. for i := 0 to 13 do
  276. begin
  277. if i < 5 then
  278. radius := cEarthRadius * Sqrt(i * (1 / 5))
  279. else
  280. radius := cEarthRadius + (i - 5.1) * (cAtmosphereRadius - cEarthRadius) * (1 / 6.9);
  281. radius := SphereVisibleRadius(VectorLength(eyePos), radius);
  282. k0 := (i and 1) * (cSlices + 1);
  283. k1 := (cSlices + 1) - k0;
  284. for j := 0 to cSlices do
  285. begin
  286. VectorCombine(diskRight, diskUp, cosCache[j] * radius, sinCache[j] * radius, pVertex[k0 + j]);
  287. if i < 13 then
  288. pColor[k0 + j] := ComputeColor(pVertex[k0 + j], i <= 7);
  289. if i = 0 then
  290. Break;
  291. end;
  292. if i > 1 then
  293. begin
  294. if i = 13 then
  295. begin
  296. glBegin(GL_QUAD_STRIP);
  297. for j := cSlices downto 0 do
  298. begin
  299. glColor4fv(@pColor[k1 + j]);
  300. glVertex3fv(@pVertex[k1 + j]);
  301. glColor4fv(@clrTransparent);
  302. glVertex3fv(@pVertex[k0 + j]);
  303. end;
  304. glEnd;
  305. end
  306. else
  307. begin
  308. glBegin(GL_QUAD_STRIP);
  309. for j := cSlices downto 0 do
  310. begin
  311. glColor4fv(@pColor[k1 + j]);
  312. glVertex3fv(@pVertex[k1 + j]);
  313. glColor4fv(@pColor[k0 + j]);
  314. glVertex3fv(@pVertex[k0 + j]);
  315. end;
  316. glEnd;
  317. end;
  318. end
  319. else if i = 1 then
  320. begin
  321. glBegin(GL_TRIANGLE_FAN);
  322. glColor4fv(@pColor[k1]);
  323. glVertex3fv(@pVertex[k1]);
  324. for j := k0 + cSlices downto k0 do
  325. begin
  326. glColor4fv(@pColor[j]);
  327. glVertex3fv(@pVertex[j]);
  328. end;
  329. glEnd;
  330. end;
  331. end;
  332. rci.GLStates.DepthWriteMask := True;
  333. FreeMem(pVertex);
  334. FreeMem(pColor);
  335. end;
  336. //-------------------------------------------------
  337. // Constellation Lines
  338. //-------------------------------------------------
  339. procedure TFormEarth.LoadConstellationLines;
  340. var
  341. sl, line: TStrings;
  342. pos1, pos2: TAffineVector;
  343. i: Integer;
  344. begin
  345. sl := TStringList.Create;
  346. line := TStringList.Create;
  347. sl.LoadFromFile('ConstellationLines.dat');
  348. for i := 0 to sl.Count - 1 do
  349. begin
  350. line.CommaText := sl[i];
  351. pos1 := LonLatToPos(StrToFloatDef(line[0], 0), StrToFloatDef(line[1], 0));
  352. ConstellationLines.AddNode(pos1);
  353. pos2 := LonLatToPos(StrToFloatDef(line[2], 0), StrToFloatDef(line[3], 0));
  354. ConstellationLines.AddNode(pos2);
  355. end;
  356. sl.Free;
  357. line.Free;
  358. end;
  359. //----------------------------------------------------------------------------
  360. procedure TFormEarth.miConstLinesClick(Sender: TObject);
  361. begin
  362. ConstellationsAlpha := 0.5 - ConstellationsAlpha;
  363. end;
  364. procedure TFormEarth.miConstBoundariesClick(Sender: TObject);
  365. begin
  366. ConstellationsAlpha := 0.5 - ConstellationsAlpha;
  367. end;
  368. //-----------------------------------------------------------------------------
  369. procedure TFormEarth.TimerTimer(Sender: TObject);
  370. begin
  371. Caption := Format('Earth ' + '%.1f FPS', [GLSceneViewer.FramesPerSecond]);
  372. GLSceneViewer.ResetPerformanceMonitor;
  373. end;
  374. //---------------------------------------------------------------------------
  375. procedure TFormEarth.tvPlanetsClick(Sender: TObject);
  376. var
  377. I: Integer;
  378. begin
  379. for I := 0 to dcSolarSystem.Count - 1 do
  380. dcSolarSystem.Children[I].Visible := False;
  381. case tvPlanets.Selected.StateIndex of
  382. 0: begin
  383. sfSun.Visible := True;
  384. end;
  385. 1: begin
  386. sfMercury.Visible := True;
  387. end;
  388. 2: begin
  389. sfVenus.Visible := True;
  390. end;
  391. 3: begin
  392. Camera.MoveTo(sfEarth);
  393. Cameracontroller.MoveTo(sfEarth);
  394. Camera.TargetObject := sfEarth;
  395. Cameracontroller.TargetObject := sfEarth;
  396. end;
  397. 4: begin
  398. Camera.MoveTo(sfMoon);
  399. Cameracontroller.MoveTo(sfMoon);
  400. Camera.TargetObject := sfMoon;
  401. Cameracontroller.TargetObject := sfMoon;
  402. end;
  403. 5: begin
  404. sfMars.Visible := True;
  405. end;
  406. 6: begin
  407. // to be replaced with ffDeimos
  408. sfDeimos.Visible := True;
  409. end;
  410. 7: begin
  411. // to be replaced with ffPhobos
  412. sfPhobos.Visible := True;
  413. end;
  414. 8: begin
  415. sfJupiter.Visible := True;
  416. end;
  417. 9: begin
  418. sfIo.Visible := True;
  419. end;
  420. 10: begin
  421. sfEuropa.Visible := True;
  422. end;
  423. 11: begin
  424. sfCallisto.Visible := True;
  425. end;
  426. 12: begin
  427. sfGanymede.Visible := True;
  428. end;
  429. 13: begin
  430. // should have rings
  431. sfSaturn.Visible := True;
  432. diskSaturnUp.Visible := True;
  433. diskSaturnDn.Visible := True;
  434. end;
  435. 14: begin
  436. sfEnceladus.Visible := True;
  437. end;
  438. 15: begin
  439. sfTitan.Visible := True;
  440. end;
  441. 16: begin
  442. sfUranus.Visible := True;
  443. end;
  444. 17: begin
  445. sfNeptune.Visible := True;
  446. end;
  447. 18: begin
  448. sfPluto.Visible := True;
  449. end;
  450. 19: begin
  451. sfCharon.Visible := True;
  452. end;
  453. end;
  454. end;
  455. //--------------------------------------------------------------------------------
  456. procedure TFormEarth.GLCadencerProgress(Sender: TObject; const deltaTime, newTime: Double);
  457. var
  458. d : Double;
  459. p : TAffineVector;
  460. begin
  461. d := GMTDateTimeToJulianDay(Now-2+newTime*timeMultiplier);
  462. sfEarth.TurnAngle := sfEarth.TurnAngle + deltaTime * TimeMultiplier;
  463. p := ComputePlanetPosition(cSunOrbitalElements, d);
  464. ScaleVector(p, 0.5*cAUToKilometers*(1/cEarthRadius));
  465. LensFlareSun.Position.AsAffineVector := p;
  466. // moon rotates on itself and around earth (not sure about the rotation direction!)
  467. p := ComputePlanetPosition(cMoonOrbitalElements, d);
  468. ScaleVector(p, 0.5*cAUToKilometers*(1/cEarthRadius));
  469. dcMoon.TurnAngle := dcMoon.TurnAngle + deltaTime * TimeMultiplier / 29.5;
  470. sfMoon.TurnAngle := 180 - dcMoon.TurnAngle;
  471. // Honour camera movements
  472. if (dmy <> 0) or (dmx <> 0) then
  473. begin
  474. Cameracontroller.MoveAroundTarget(ClampValue(dmy * 0.3, -5, 5), ClampValue(dmx * 0.3, -5, 5));
  475. dmx := 0;
  476. dmy := 0;
  477. end;
  478. // This gives us smoother camera movements
  479. CameraTimeSteps := CameraTimeSteps + deltaTime;
  480. while CameraTimeSteps > 0.005 do
  481. begin
  482. Camera.Position.AsVector := VectorLerp(Camera.Position.AsVector,
  483. Cameracontroller.Position.AsVector, 0.05);
  484. CameraTimeSteps := CameraTimeSteps - 0.005;
  485. end;
  486. // Smooth constellation lines appearance/disappearance
  487. if ConstellationLines.LineColor.Alpha <> ConstellationsAlpha then
  488. begin
  489. ConstellationLines.LineColor.Alpha :=
  490. ClampValue(ConstellationLines.LineColor.Alpha +
  491. Sign(ConstellationsAlpha - ConstellationLines.LineColor.Alpha) * deltaTime, 0, 0.5);
  492. ConstellationLines.Visible := (ConstellationLines.LineColor.Alpha > 0);
  493. end;
  494. end;
  495. //--------------------------------------------------------------------------------
  496. procedure TFormEarth.GLSceneViewerMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
  497. X, Y: Integer);
  498. begin
  499. mx := X;
  500. my := Y;
  501. end;
  502. procedure TFormEarth.GLSceneViewerMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
  503. begin
  504. if Shift = [ssLeft] then
  505. begin
  506. dmx := dmx + (mx - X);
  507. dmy := dmy + (my - Y);
  508. end
  509. else if Shift = [ssRight] then
  510. Camera.FocalLength := Camera.FocalLength * Power(1.05, (my - Y) * 0.1);
  511. mx := X;
  512. my := Y;
  513. end;
  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. procedure TFormEarth.FormKeyPress(Sender: TObject; var Key: Char);
  561. begin
  562. case Key of
  563. #27:
  564. FormEarth.Close;
  565. 'm', 'M':
  566. begin
  567. Camera.MoveTo(sfMoon);
  568. Cameracontroller.MoveTo(sfMoon);
  569. Camera.TargetObject := sfMoon;
  570. Cameracontroller.TargetObject := sfMoon;
  571. end;
  572. 'e', 'E':
  573. begin
  574. Camera.MoveTo(dcEarth);
  575. Cameracontroller.MoveTo(dcEarth);
  576. Camera.TargetObject := dcEarth;
  577. Cameracontroller.TargetObject := dcEarth;
  578. end;
  579. 'h':
  580. if not HighResResourcesLoaded then
  581. begin
  582. GLSceneViewer.Cursor := crHourGlass;
  583. try
  584. LoadHighResTexture(GLPlanetMaps.Materials[0], 'earth_4096.jpg');
  585. LoadHighResTexture(GLPlanetMaps.Materials[1], 'earth_night_4096.jpg');
  586. LoadHighResTexture(GLPlanetMaps.Materials[2], 'moon_2048.jpg');
  587. GLSceneViewer.Buffer.AntiAliasing := aa2x;
  588. finally
  589. GLSceneViewer.Cursor := crDefault;
  590. end;
  591. HighResResourcesLoaded := True;
  592. end;
  593. 'c':
  594. ConstellationsAlpha := 0.5 - ConstellationsAlpha;
  595. '0' .. '9':
  596. TimeMultiplier := Power(Integer(Key) - Integer('0'), 3);
  597. end;
  598. end;
  599. procedure TFormEarth.Exit1Click(Sender: TObject);
  600. begin
  601. Close;
  602. end;
  603. end.