Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

526 lines
12 KiB

  1. /******************************************************************************\
  2. * This is a part of the Microsoft Source Code Samples.
  3. * Copyright (C) 1993 Microsoft Corporation.
  4. * All rights reserved.
  5. * This source code is only intended as a supplement to
  6. * Microsoft Development Tools and/or WinHelp documentation.
  7. * See these sources for detailed information regarding the
  8. * Microsoft samples programs.
  9. \******************************************************************************/
  10. #include <windows.h>
  11. #include <GL/gl.h>
  12. #include <GL/glu.h>
  13. #include "stonehen.h"
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include "atmosphe.h"
  17. #include "scene.h"
  18. #include "callback.h"
  19. #include "setpixel.h"
  20. extern int use_lighting;
  21. extern int draw_shadows;
  22. extern int use_normal_fog;
  23. extern int use_textures;
  24. extern int texture_hack; // HACK HACK - only texture map stones for now
  25. extern int use_telescope;
  26. extern int use_antialias;
  27. extern int cb_demo_mode;
  28. BOOL Con;
  29. BOOL bTimeScale[5];
  30. extern GLfloat time_scale;
  31. GLfloat TimeScale[] = {0, 1, 10, 100, 500};
  32. char szAppName[] = "Stonehenge";
  33. extern TimeDate last_update;
  34. int curr_weather;
  35. HGLRC hRC;
  36. int iTimer;
  37. /* forward declarations of helper functions in this module */
  38. HWND WINAPI InitializeWindow (HINSTANCE, int);
  39. VOID WINAPI InitializeMenu (HWND, HMENU);
  40. LONG WINAPI CommandHandler (HWND, UINT, LONG);
  41. LONG WINAPI MainWndProc (HWND, UINT, UINT, LONG);
  42. /* entry point of this executable */
  43. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  44. {
  45. MSG msg;
  46. HWND hWnd;
  47. /* previous instances do not exist in Win32 */
  48. if (hPrevInstance)
  49. return 0;
  50. if (!(hWnd = InitializeWindow (hInstance, nCmdShow)))
  51. return FALSE;
  52. /* main window message loop */
  53. while (GetMessage (&msg, NULL, 0, 0))
  54. {
  55. TranslateMessage (&msg);
  56. DispatchMessage (&msg);
  57. }
  58. /* return success of application */
  59. return TRUE;
  60. }
  61. HWND WINAPI InitializeWindow (HINSTANCE hInstance, int nCmdShow)
  62. {
  63. WNDCLASS wc;
  64. HWND hWnd;
  65. RECT rect;
  66. /* Register the frame class */
  67. wc.style = CS_OWNDC;
  68. wc.lpfnWndProc = (WNDPROC)MainWndProc;
  69. wc.cbClsExtra = 0;
  70. wc.cbWndExtra = 0;
  71. wc.hInstance = hInstance;
  72. wc.hIcon = LoadIcon (hInstance, szAppName);
  73. wc.hCursor = LoadCursor (NULL,IDC_ARROW);
  74. wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  75. wc.lpszMenuName = szAppName;
  76. wc.lpszClassName = szAppName;
  77. if (!RegisterClass (&wc) )
  78. return FALSE;
  79. rect.left = 100;
  80. rect.top = 100;
  81. rect.right = 652;
  82. rect.bottom = 500;
  83. AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
  84. /* Create the frame */
  85. hWnd = CreateWindow (szAppName,
  86. "OpenGL Stonehenge Demo",
  87. WS_OVERLAPPEDWINDOW,
  88. rect.left,
  89. rect.top,
  90. WINDSIZEX(rect),
  91. WINDSIZEY(rect),
  92. NULL,
  93. NULL,
  94. hInstance,
  95. NULL);
  96. /* make sure window was created */
  97. if (!hWnd)
  98. return FALSE;
  99. InitializeMenu(hWnd, (HMENU) GetMenu(hWnd));
  100. SendMessage(hWnd, WM_INIT, NULL, NULL);
  101. /* show and update main window */
  102. ShowWindow (hWnd, nCmdShow);
  103. UpdateWindow (hWnd);
  104. return hWnd;
  105. }
  106. /* main window procedure */
  107. LONG WINAPI MainWndProc (
  108. HWND hWnd,
  109. UINT uMsg,
  110. UINT uParam,
  111. LONG lParam)
  112. {
  113. LONG lRet = 1;
  114. switch (uMsg)
  115. {
  116. case WM_CREATE:
  117. {
  118. HDC hDC;
  119. /* This is equivalent to the find_visual routine */
  120. hDC = GetDC(hWnd);
  121. /*
  122. pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
  123. pfd.nVersion = 1;
  124. pfd.dwFlags = PFD_DRAW_TO_WINDOW |
  125. PFD_SUPPORT_OPENGL |
  126. PFD_DOUBLEBUFFER); //GLX_DOUBLEBUFFER
  127. pfd.iPixelType = PFD_TYPE_RGBA; //GLX_RGBA
  128. pfd.cColorBits = 8;
  129. pfd.cRedBits = 1; //GLX_RED_SIZE
  130. pfd.cRedShift = 0;
  131. pfd.cGreenBits = 1; //GLX_GREEN_SIZE
  132. pfd.cGreenShift = 0;
  133. pfd.cBlueBits = 1; //GLX_BLUE_SIZE
  134. pfd.cBlueShift = 0;
  135. pfd.cAlphaBits = 0;
  136. pfd.cAlphaShift = 0;
  137. pfd.cAccumBits = 0; //ACCUM NOT SUPPORTED
  138. pfd.cAccumRedBits = 0; //GLX_ACCUM_RED_SIZE
  139. pfd.cAccumGreenBits = 0; //GLX_ACCUM_GREEN_SIZE
  140. pfd.cAccumBlueBits = 0; //GLX_ACCUM_BLUE_SIZE
  141. pfd.cAccumAlphaBits = 0; //GLX_ACCUM_ALPHA_SIZE
  142. pfd.cDepthBits = 1; //GLX_DEPTH_SIZE
  143. pfd.cStencilBits = 1; //GLX_STENCIL_SIZE
  144. pfd.cAuxBuffers = 0;
  145. pfd.iLayerType = PFD_MAIN_PLANE;
  146. pfd.bReserved = 0;
  147. pfd.dwLayerMask =
  148. pfd.dwVisibleMask =
  149. pfd.dwDamageMask = 0;
  150. iPixelFormat = ChoosePixelFormat(hDC, &pfd);
  151. if (iPixelFormat == 0) {
  152. char text[128];
  153. wsprintf(text, "ChoosePixelFormat failed %d", GetLastError());
  154. MessageBox (GetFocus(),
  155. text,
  156. szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND);
  157. }
  158. */
  159. bSetupPixelFormat(hDC);
  160. hRC = wglCreateContext( hDC );
  161. Con = wglMakeCurrent( hDC, hRC );
  162. ReleaseDC(hWnd, hDC);
  163. // iTimer = SetTimer(hWnd, 1, 1000, NULL);
  164. }
  165. break;
  166. case WM_TIMER:
  167. {
  168. PostMessage(hWnd, WM_PAINT, NULL, NULL);
  169. }
  170. break;
  171. case WM_PAINT:
  172. {
  173. HDC hDC;
  174. PAINTSTRUCT ps;
  175. hDC = BeginPaint(hWnd, &ps);
  176. EndPaint(hWnd, &ps);
  177. drawWP(hWnd);
  178. }
  179. break;
  180. case WM_INIT:
  181. {
  182. scene_init();
  183. last_update.read_time();
  184. resetViewerCB(NULL, NULL, NULL);
  185. }
  186. break;
  187. case WM_SIZE:
  188. {
  189. resizeCB(hWnd, NULL, NULL);
  190. }
  191. break;
  192. case WM_COMMAND:
  193. /* handle all command messages in a localized function */
  194. lRet = CommandHandler (hWnd, uParam, lParam);
  195. break;
  196. case WM_LBUTTONDOWN:
  197. {
  198. GLwDrawingAreaCallbackStruct *call_data;
  199. call_data = (GLwDrawingAreaCallbackStruct *) LocalAlloc(0, sizeof(GLwDrawingAreaCallbackStruct));
  200. call_data->event = (XEvent *) LocalAlloc(0, sizeof(XEvent));
  201. call_data->event->type = ButtonPress;
  202. call_data->event->xbutton.button = Button1;
  203. call_data->event->xbutton.x = LOWORD(lParam);
  204. call_data->event->xbutton.y = HIWORD(lParam);
  205. inputCB(hWnd, NULL, (LPVOID)call_data);
  206. LocalFree(call_data->event);
  207. LocalFree(call_data);
  208. }
  209. break;
  210. case WM_RBUTTONDOWN:
  211. {
  212. GLwDrawingAreaCallbackStruct *call_data;
  213. call_data = (GLwDrawingAreaCallbackStruct *) LocalAlloc(0, sizeof(GLwDrawingAreaCallbackStruct));
  214. call_data->event = (XEvent *) LocalAlloc(0, sizeof(XEvent));
  215. call_data->event->type = ButtonPress;
  216. call_data->event->xbutton.button = Button2;
  217. call_data->event->xbutton.x = LOWORD(lParam);
  218. call_data->event->xbutton.y = HIWORD(lParam);
  219. inputCB(hWnd, NULL, (LPVOID)call_data);
  220. LocalFree(call_data->event);
  221. LocalFree(call_data);
  222. }
  223. break;
  224. case WM_LBUTTONUP:
  225. {
  226. GLwDrawingAreaCallbackStruct *call_data;
  227. call_data = (GLwDrawingAreaCallbackStruct *) LocalAlloc(0, sizeof(GLwDrawingAreaCallbackStruct));
  228. call_data->event = (XEvent *) LocalAlloc(0, sizeof(XEvent));
  229. call_data->event->type = ButtonRelease;
  230. call_data->event->xbutton.button = Button1;
  231. inputCB(hWnd, NULL, (LPVOID)call_data);
  232. LocalFree(call_data->event);
  233. LocalFree(call_data);
  234. }
  235. break;
  236. case WM_RBUTTONUP:
  237. {
  238. GLwDrawingAreaCallbackStruct *call_data;
  239. call_data = (GLwDrawingAreaCallbackStruct *) LocalAlloc(0, sizeof(GLwDrawingAreaCallbackStruct));
  240. call_data->event = (XEvent *) LocalAlloc(0, sizeof(XEvent));
  241. call_data->event->type = ButtonRelease;
  242. call_data->event->xbutton.button = Button2;
  243. inputCB(hWnd, NULL, (LPVOID)call_data);
  244. LocalFree(call_data->event);
  245. LocalFree(call_data);
  246. }
  247. break;
  248. case WM_MOUSEMOVE:
  249. {
  250. GLwDrawingAreaCallbackStruct *call_data;
  251. call_data = (GLwDrawingAreaCallbackStruct *) LocalAlloc(0, sizeof(GLwDrawingAreaCallbackStruct));
  252. call_data->event = (XEvent *) LocalAlloc(0, sizeof(XEvent));
  253. call_data->event->type = MotionNotify;
  254. call_data->event->xmotion.x = LOWORD(lParam);
  255. call_data->event->xmotion.y = HIWORD(lParam);
  256. inputCB(hWnd, NULL, (LPVOID)call_data);
  257. LocalFree(call_data->event);
  258. LocalFree(call_data);
  259. }
  260. break;
  261. case WM_CLOSE:
  262. {
  263. HGLRC hRC;
  264. if(hRC = wglGetCurrentContext())
  265. wglDeleteContext(hRC);
  266. //KillTimer(iTimer);
  267. /* call destroy window to cleanup and go away */
  268. DestroyWindow (hWnd);
  269. }
  270. break;
  271. case WM_DESTROY:
  272. {
  273. wglDeleteContext(wglGetCurrentContext());
  274. PostQuitMessage (0);
  275. }
  276. break;
  277. default:
  278. /* pass all unhandled messages to DefWindowProc */
  279. lRet = DefWindowProc (hWnd, uMsg, uParam, lParam);
  280. break;
  281. }
  282. /* return 1 if handled message, 0 if not */
  283. return lRet;
  284. }
  285. /* handle all WM_COMMAND messages here */
  286. LONG WINAPI CommandHandler (
  287. HWND hWnd,
  288. UINT uParam,
  289. LONG lParam)
  290. {
  291. int i;
  292. HMENU hMenu;
  293. switch (LOWORD(uParam))
  294. {
  295. case IDM_EXIT:
  296. /* exit application */
  297. PostMessage (hWnd, WM_CLOSE, 0, 0L);
  298. break;
  299. case IDM_LIGHTING:
  300. hMenu = GetMenu(hWnd);
  301. use_lighting = !use_lighting;
  302. CheckMenuItem(hMenu,IDM_LIGHTING,(use_lighting?MF_CHECKED:MF_UNCHECKED));
  303. break;
  304. case IDM_SHADOWS:
  305. hMenu = GetMenu(hWnd);
  306. draw_shadows = !draw_shadows;
  307. CheckMenuItem(hMenu,IDM_SHADOWS,(draw_shadows?MF_CHECKED:MF_UNCHECKED));
  308. break;
  309. case IDM_FOG:
  310. hMenu = GetMenu(hWnd);
  311. use_normal_fog = !use_normal_fog;
  312. CheckMenuItem(hMenu,IDM_FOG,(use_normal_fog?MF_CHECKED:MF_UNCHECKED));
  313. break;
  314. #ifdef TEXTURE
  315. case IDM_TEXTUREMAP:
  316. hMenu = GetMenu(hWnd);
  317. /* HACK HACK HACK
  318. * This would be right, but for now I only want to map the stones, nothing
  319. * else, so I have a new variable - texture_hack
  320. use_textures = !use_textures;
  321. CheckMenuItem(hMenu,IDM_TEXTUREMAP,(use_textures?MF_CHECKED:MF_UNCHECKED));
  322. */
  323. texture_hack = !texture_hack;
  324. CheckMenuItem(hMenu,IDM_TEXTUREMAP,(texture_hack?MF_CHECKED:MF_UNCHECKED));
  325. break;
  326. #endif
  327. case IDM_TELESCOPE:
  328. hMenu = GetMenu(hWnd);
  329. use_telescope = !use_telescope;
  330. CheckMenuItem(hMenu,IDM_TELESCOPE,(use_telescope?MF_CHECKED:MF_UNCHECKED));
  331. break;
  332. case IDM_ANTIALIAS:
  333. hMenu = GetMenu(hWnd);
  334. use_antialias = !use_antialias;
  335. CheckMenuItem(hMenu,IDM_ANTIALIAS,(use_antialias?MF_CHECKED:MF_UNCHECKED));
  336. break;
  337. case IDM_CLEAR:
  338. case IDM_FOGGY:
  339. case IDM_VERYFOGGY:
  340. case IDM_RAINY:
  341. hMenu = GetMenu(hWnd);
  342. /* If this value is already checked, we do nothing */
  343. if(curr_weather != (LOWORD(uParam) - IDM_CLEAR))
  344. {
  345. CheckMenuItem(hMenu, curr_weather + IDM_CLEAR, MF_UNCHECKED);
  346. CheckMenuItem(hMenu, LOWORD(uParam), MF_CHECKED);
  347. curr_weather = LOWORD(uParam) - IDM_CLEAR;
  348. scene_set_weather(weathers[curr_weather]);
  349. }
  350. break;
  351. case IDM_CURRENTTIME:
  352. currentTimeCB(hWnd);
  353. break;
  354. case IDM_10AM:
  355. time10amCB(hWnd);
  356. break;
  357. case IDM_NOON:
  358. time12pmCB(hWnd);
  359. break;
  360. case IDM_4PM:
  361. time4pmCB(hWnd);
  362. break;
  363. case IDM_HOLDTIME:
  364. case IDM_SCALE1:
  365. case IDM_SCALE10:
  366. case IDM_SCALE100:
  367. case IDM_SCALE500:
  368. hMenu = GetMenu(hWnd);
  369. /* If this value is already checked, we do nothing */
  370. if(!bTimeScale[LOWORD(uParam) - IDM_HOLDTIME])
  371. {
  372. for(i=0;!bTimeScale[i];i++);
  373. time_scale = TimeScale[LOWORD(uParam) - IDM_HOLDTIME];
  374. CheckMenuItem(hMenu, IDM_HOLDTIME + i, MF_UNCHECKED);
  375. bTimeScale[i] = FALSE;
  376. CheckMenuItem(hMenu, LOWORD(uParam), MF_CHECKED);
  377. bTimeScale[LOWORD(uParam) - IDM_HOLDTIME] = TRUE;
  378. timeSpeedCB(hWnd, NULL, NULL);
  379. }
  380. break;
  381. case IDM_DEMOMODE:
  382. hMenu = GetMenu(hWnd);
  383. cb_demo_mode = !cb_demo_mode;
  384. CheckMenuItem(hMenu,IDM_DEMOMODE,(cb_demo_mode?MF_CHECKED:MF_UNCHECKED));
  385. demo_modeCB(hWnd, NULL, NULL);
  386. break;
  387. case IDM_RESET:
  388. resetViewerCB(hWnd, NULL, NULL);
  389. break;
  390. default:
  391. return FALSE;
  392. }
  393. return TRUE;
  394. }
  395. VOID WINAPI InitializeMenu (HWND hWnd, HMENU hMenu)
  396. {
  397. curr_weather = def_weather_index;
  398. CheckMenuItem(hMenu, IDM_CLEAR + curr_weather, MF_CHECKED);
  399. CheckMenuItem(hMenu, IDM_LIGHTING, MF_CHECKED);
  400. bTimeScale[0] = TRUE;
  401. bTimeScale[1] = FALSE;
  402. bTimeScale[2] = FALSE;
  403. bTimeScale[3] = FALSE;
  404. bTimeScale[4] = FALSE;
  405. CheckMenuItem(hMenu, IDM_HOLDTIME, MF_CHECKED);
  406. cb_demo_mode = FALSE;
  407. }