fChrismasD.pas 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. unit fChrismasD;
  2. interface
  3. uses
  4. Winapi.Windows,
  5. Winapi.OpenGL,
  6. System.SysUtils,
  7. System.Classes,
  8. System.Math,
  9. Vcl.Graphics,
  10. Vcl.Controls,
  11. Vcl.Forms,
  12. Vcl.Dialogs,
  13. Vcl.ExtCtrls,
  14. Vcl.Imaging.Jpeg,
  15. Vcl.Menus,
  16. GLS.Scene,
  17. GLS.BaseClasses,
  18. GLS.VectorFileObjects,
  19. GLS.Objects,
  20. GLS.SceneViewer,
  21. GLS.Texture,
  22. GLS.Cadencer,
  23. GLS.SkyDome,
  24. GLS.ParticleFX,
  25. GLS.VectorGeometry,
  26. GLS.LensFlare,
  27. GLS.BitmapFont,
  28. GLS.WindowsFont,
  29. GLS.HUDObjects,
  30. GLS.VectorTypes,
  31. GLS.ScreenSaver,
  32. GLS.ShadowPlane,
  33. GLS.File3DS,
  34. GLS.FileOBJ,
  35. GLS.GeomObjects,
  36. GLS.Material,
  37. GLS.Coordinates,
  38. GLS.Color,
  39. GLS.SoundManager,
  40. GLS.Sounds.BASS,
  41. BASS.Import,
  42. GLS.FireFX,
  43. GLS.FileWAV,
  44. GLS.Utils;
  45. type
  46. TMain = class(TForm)
  47. Scene: TGLScene;
  48. Viewer: TGLSceneViewer;
  49. Camera: TGLCamera;
  50. dcFirTree: TGLDummyCube;
  51. FFFirTree: TGLFreeForm;
  52. LSRoom: TGLLightSource;
  53. POFirTree2: TGLProxyObject;
  54. POFirTree3: TGLProxyObject;
  55. Cadencer: TGLCadencer;
  56. dcCameraTarget: TGLDummyCube;
  57. FFFirePlace: TGLFreeForm;
  58. MaterialLibrary: TGLMaterialLibrary;
  59. LSFire: TGLLightSource;
  60. PFXFire: TGLPolygonPFXManager;
  61. dcFireSource: TGLDummyCube;
  62. ParticleFXRenderer: TGLParticleFXRenderer;
  63. cyLog: TGLCylinder;
  64. DCLensFlares: TGLDummyCube;
  65. LensFlare1: TGLLensFlare;
  66. LensFlare2: TGLLensFlare;
  67. LensFlare3: TGLLensFlare;
  68. LensFlare4: TGLLensFlare;
  69. SMBASS: TGLSMBASS;
  70. SoundLibrary: TGLSoundLibrary;
  71. DCDecoWhite: TGLDummyCube;
  72. dcBalls: TGLDummyCube;
  73. SPWhiteBall: TGLSphere;
  74. POWhiteBall1: TGLProxyObject;
  75. SPGoldBall: TGLSphere;
  76. POGoldBall1: TGLProxyObject;
  77. DCDecoGold: TGLDummyCube;
  78. POGoldBall2: TGLProxyObject;
  79. LFFireLens: TGLLensFlare;
  80. LensFlare5: TGLLensFlare;
  81. POWhiteBall2: TGLProxyObject;
  82. POGoldBall3: TGLProxyObject;
  83. POWhiteBall3: TGLProxyObject;
  84. LensFlare6: TGLLensFlare;
  85. PFXTree: TGLPolygonPFXManager;
  86. WindowsBitmapFont: TGLWindowsBitmapFont;
  87. Cube1: TGLCube;
  88. dcGifts: TGLDummyCube;
  89. Cube2: TGLCube;
  90. ShadowPlane: TGLShadowPlane;
  91. DCTree: TGLDummyCube;
  92. Cube3: TGLCube;
  93. Cube4: TGLCube;
  94. dcFire: TGLDummyCube;
  95. ScreenSaver: TGLScreenSaver;
  96. Timer: TTimer;
  97. HUDSprite: TGLHUDSprite;
  98. ftCountDown: TGLFlatText;
  99. ftYear: TGLFlatText;
  100. ftCongratulations: TGLFlatText;
  101. FireFXManager: TGLFireFXManager;
  102. procedure FormCreate(Sender: TObject);
  103. procedure CadencerProgress(Sender: TObject;
  104. const deltaTime, newTime: Double);
  105. procedure FormResize(Sender: TObject);
  106. procedure FormKeyPress(Sender: TObject; var Key: Char);
  107. procedure TimerTimer(Sender: TObject);
  108. procedure ScreenSaverCloseQuery(Sender: TObject; var CanClose: Boolean);
  109. procedure ScreenSaverExecute(Sender: TObject);
  110. procedure ScreenSaverPreview(Sender: TObject; previewHwnd: HWND);
  111. procedure ViewerMouseMove(Sender: TObject; Shift: TShiftState;
  112. X, Y: Integer);
  113. procedure ViewerMouseDown(Sender: TObject; Button: TMouseButton;
  114. Shift: TShiftState; X, Y: Integer);
  115. procedure ViewerDblClick(Sender: TObject);
  116. procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
  117. WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  118. public
  119. AssetPath: TFileName;
  120. mx, my: Integer;
  121. FireLight: Single;
  122. inPreview, inSaver: Boolean;
  123. bStream: Cardinal;
  124. end;
  125. var
  126. Main: TMain;
  127. implementation
  128. {$R *.dfm}
  129. procedure TMain.FormCreate(Sender: TObject);
  130. begin
  131. AssetPath := GetCurrentAssetPath();
  132. Randomize;
  133. // Load static models
  134. SetCurrentDir(AssetPath + '\model');
  135. ffFirTree.LoadFromFile('firtree.3ds');
  136. ffFirePlace.LoadFromFile('fireplace.3ds');
  137. FireLight := 0.5;
  138. FTYear.Text := '';
  139. // Set current dir for audio files
  140. SetCurrentDir(AssetPath + '\audio');
  141. end;
  142. procedure TMain.FormResize(Sender: TObject);
  143. begin
  144. Camera.SceneScale := Width / 640;
  145. if Visible then
  146. HUDSprite.Position.X := Self.Width - 200;
  147. if (Width >= Screen.Width) then
  148. ViewerDblClick(Self);
  149. end;
  150. procedure TMain.FormKeyPress(Sender: TObject; var Key: Char);
  151. begin
  152. Key := #0;
  153. Application.Terminate;
  154. end;
  155. procedure TMain.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  156. WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  157. begin
  158. Camera.AdjustDistanceToTarget(Power(1.1, WheelDelta / 120));
  159. end;
  160. procedure TMain.ViewerDblClick(Sender: TObject);
  161. begin
  162. if (not inPreview) and (not inSaver) and (not Application.Terminated) and
  163. (BorderStyle <> bsNone) then
  164. begin
  165. BorderStyle := bsNone;
  166. FormStyle := fsStayOnTop;
  167. Align := alClient;
  168. end;
  169. end;
  170. procedure TMain.ViewerMouseDown(Sender: TObject; Button: TMouseButton;
  171. Shift: TShiftState; X, Y: Integer);
  172. begin
  173. mx := X;
  174. my := Y;
  175. end;
  176. procedure TMain.ViewerMouseMove(Sender: TObject; Shift: TShiftState;
  177. X, Y: Integer);
  178. begin
  179. if Shift = [ssLeft] then
  180. begin
  181. Camera.MoveAroundTarget(my - Y, mx - X);
  182. mx := X;
  183. my := Y;
  184. end;
  185. end;
  186. procedure TMain.CadencerProgress(Sender: TObject;
  187. const deltaTime, newTime: Double);
  188. begin
  189. FireLight := ClampValue(FireLight + Random * 0.4 - 0.2, 0, 1);
  190. LSFire.Diffuse.Color := VectorLerp(clrYellow, VectorMake(0.5, 0, 0, 1),
  191. FireLight);
  192. LSFire.Position.Y := FireLight * 0.1;
  193. if inPreview then
  194. HUDSprite.Visible := False;
  195. if HUDSprite.Visible then
  196. begin
  197. HUDSprite.Material.FrontProperties.Diffuse.Alpha :=
  198. HUDSprite.Material.FrontProperties.Diffuse.Alpha - deltaTime * 0.03;
  199. if HUDSprite.Material.FrontProperties.Diffuse.Alpha < 0.01 then
  200. HUDSprite.Visible := False;
  201. end;
  202. DCFirTree.Turn(deltaTime);
  203. Viewer.Invalidate();
  204. end;
  205. procedure TMain.TimerTimer(Sender: TObject);
  206. var
  207. i: Integer;
  208. t: TDateTime;
  209. buf: String;
  210. Y, m, d: Word;
  211. TheChristmas,
  212. isArrived: Boolean;
  213. begin
  214. TheChristmas := false; // Merry Christmas or Happy New Year!
  215. Caption := Format('%.1f FPS', [Viewer.FramesPerSecond]);
  216. Viewer.ResetPerformanceMonitor;
  217. if SMBASS.Active and (bStream = 0) then
  218. begin
  219. bStream := BASS_StreamCreateFile(False, PAnsiChar('Jingle_Bells_64.mp3'), 0,
  220. 0, BASS_STREAM_AUTOFREE);
  221. BASS_ChannelPlay(bStream, True);
  222. end;
  223. DecodeDate(Now(), Y, m, d);
  224. if TheChristmas then
  225. begin
  226. t := EncodeDate(Y, 12, 25) - Now();
  227. ftCongratulations.Text := 'Merry Christmas!';
  228. end
  229. else
  230. begin
  231. t := EncodeDate(Y + 1, 01, 01) - Now();
  232. ftCongratulations.Text := 'Happy New Year!';
  233. ftYear.Text := IntToStr(Y + 1);
  234. end;
  235. if (t < 1) and (t > -1) then
  236. dcGifts.Visible := True;
  237. if t >= 2 then
  238. begin
  239. buf := IntToStr(Trunc(t)) + ' days, ';
  240. i := Round(Frac(t) * 24);
  241. if i > 1 then
  242. buf := buf + IntToStr(i) + ' hours...'
  243. else
  244. buf := buf + IntToStr(i) + ' hour...';
  245. ftCountDown.Text := buf;
  246. end
  247. else
  248. begin
  249. t := t * 24;
  250. if t > 1 then
  251. begin
  252. buf := IntToStr(Trunc(t)) + ' hours, ';
  253. i := Round(Frac(t) * 60);
  254. if i > 1 then
  255. buf := buf + IntToStr(i) + ' minutes...'
  256. else
  257. buf := buf + IntToStr(i) + ' minute...';
  258. ftCountDown.Text := buf;
  259. end
  260. else
  261. begin
  262. t := t * 60;
  263. ftCountDown.Text := IntToStr(Trunc(t)) + ' minutes, ' +
  264. IntToStr(Round(Frac(t) * 60)) + ' seconds...';
  265. end;
  266. end;
  267. end;
  268. procedure TMain.ScreenSaverCloseQuery(Sender: TObject; var CanClose: Boolean);
  269. begin
  270. Application.Terminate;
  271. CanClose := False;
  272. end;
  273. procedure TMain.ScreenSaverExecute(Sender: TObject);
  274. begin
  275. inSaver := True;
  276. end;
  277. procedure TMain.ScreenSaverPreview(Sender: TObject; previewHwnd: HWND);
  278. begin
  279. inPreview := True;
  280. end;
  281. end.