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.

533 lines
15 KiB

  1. /************************************************************************/
  2. /******************** Includes ******************************************/
  3. /************************************************************************/
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <stdlib.h>
  7. #include "viewer.h"
  8. //IID_IPMesh {0C154611-3C2C-11d0-A459-00AA00BDD621}
  9. __declspec(dllexport) DEFINE_GUID(IID_IPMesh,
  10. 0xc154611, 0x3c2c, 0x11d0, 0xa4, 0x59, 0x0, 0xaa, 0x0, 0xbd, 0xd6, 0x21);
  11. //IID_IPMeshGL {0C154612-3C2C-11d0-A459-00AA00BDD621}
  12. __declspec(dllexport) DEFINE_GUID(IID_IPMeshGL,
  13. 0xc154612, 0x3c2c, 0x11d0, 0xa4, 0x59, 0x0, 0xaa, 0x0, 0xbd, 0xd6, 0x21);
  14. /************************************************************************/
  15. /******************** Globals *******************************************/
  16. /************************************************************************/
  17. LPPMESH pPMesh;
  18. LPPMESHGL pPMeshGL;
  19. DWORD minV=0, maxV=0;
  20. BOOL pm_ready = FALSE;
  21. float pm_lod_level;
  22. float old_lod;
  23. float curquat[4], lastquat[4];
  24. WININFO g_wi;
  25. SCENE g_s;
  26. int OldScrollPos;
  27. /** OpenGL state **/
  28. BOOL renderDoubleBuffer = TRUE;
  29. int colormode = TRUE;
  30. enum NormalMode normal_mode = PER_VERTEX;
  31. BOOL linesmooth_enable = FALSE;
  32. BOOL polysmooth_enable = FALSE;
  33. GLenum cull_face = GL_FRONT;
  34. GLenum front_face = GL_CCW;
  35. BOOL cull_enable = FALSE;
  36. BOOL depth_mode = TRUE;
  37. BOOL fog_enable = FALSE;
  38. BOOL clip_enable = FALSE;
  39. GLenum shade_model = GL_FLAT;
  40. BOOL polystipple_enable = FALSE;
  41. BOOL linestipple_enable = FALSE;
  42. int matrixmode;
  43. enum TransformType tx_type = ORTHO_PROJECTION;
  44. BOOL dither_enable = TRUE;
  45. BOOL blend_enable = FALSE;
  46. GLenum sblendfunc = GL_SRC_ALPHA;
  47. GLenum dblendfunc = GL_ONE_MINUS_SRC_ALPHA;
  48. BOOL filled_mode = TRUE;
  49. BOOL edge_mode = FALSE;
  50. BOOL displaylist_mode = FALSE;
  51. GLfloat linewidth = 1.0;
  52. GLenum polymodefront = GL_FILL;
  53. GLenum polymodeback = GL_FILL;
  54. BOOL mblur_enable = FALSE;
  55. GLfloat blur_amount = 0.0;
  56. BOOL fsantimode = FALSE;
  57. BOOL fsaredraw = 0;
  58. GLfloat fsajitter = 0.0F;
  59. int cmface = GL_FRONT;
  60. int cmmode = GL_AMBIENT_AND_DIFFUSE;
  61. int cmenable = FALSE;
  62. BOOL tex_enable = FALSE; //************
  63. BOOL texgen_enable = FALSE;
  64. GLenum texenvmode = GL_DECAL;
  65. long tex_pack = 0;
  66. int tex_row = 0;
  67. int tex_col = 0;
  68. int tex_index = 0;
  69. int tex_xpix = 0;
  70. int tex_ypix = 0;
  71. int tex_numpix = 0;
  72. int tex_numcomp = 0;
  73. GLfloat tex_minfilter = GL_NEAREST;
  74. GLfloat tex_magfilter = GL_NEAREST;
  75. unsigned char *Image = NULL;
  76. unsigned char *TextureImage = NULL;
  77. BOOL light_enable = TRUE;
  78. int numInfLights = 0;
  79. int numLocalLights = 0;
  80. BOOL lighttwoside = FALSE;
  81. GLfloat localviewmode = 0.0F;
  82. /************************************************************************/
  83. /******************* Function Prototypes ********************************/
  84. /************************************************************************/
  85. void CustomizeWnd (HINSTANCE, LPWININFO);
  86. LONG APIENTRY MyWndProc(HWND, UINT, UINT, LONG);
  87. void SubclassWindow (HWND, WNDPROC);
  88. void UpdateWinTitle (HWND);
  89. void myHScrollFunc (int);
  90. BOOL read_pm(char *);
  91. void InitScene (LPSCENE);
  92. /************************************************************************/
  93. /******************* Code ***********************************************/
  94. /************************************************************************/
  95. void myHScrollFunc (int i)
  96. {
  97. OldScrollPos = g_s.scroll_pos;
  98. g_s.scroll_pos = i;
  99. if (g_s.scroll_pos != OldScrollPos)
  100. {
  101. if (pm_ready)
  102. {
  103. HRESULT hr;
  104. old_lod = pm_lod_level;
  105. pm_lod_level = (float) (g_s.scroll_pos/1000.0);
  106. DWORD nv = minV + DWORD((maxV - minV + 1) * pm_lod_level *
  107. 0.999999f);
  108. hr = pPMesh->SetNumVertices(nv);
  109. if (hr != S_OK)
  110. MessageBox (NULL, "SetNumVertices failed", "Error", MB_OK);
  111. DoGlStuff ();
  112. }
  113. UpdateWinTitle (g_wi.hWnd);
  114. }
  115. }
  116. void InitScene (LPSCENE lps)
  117. {
  118. lps->hither = DEFHITHER;
  119. lps->yon = DEFYONDER;
  120. lps->scale = 1.0;
  121. lps->angle = 0.0;
  122. lps->scroll_pos = 0; //auxGetScrollPos (AUX_HSCROLL);
  123. lps->from[0] /*X*/ = 0.0;
  124. lps->from[1] /*Y*/ = 0.0;
  125. lps->from[2] /*Z*/ = 5.0;
  126. lps->to[0] /*X*/ = 0.0;
  127. lps->to[1] /*Y*/ = 0.0;
  128. lps->to[2] /*Z*/ = 0.0;
  129. lps->up[0] /*X*/ = 0.0;
  130. lps->up[1] /*Y*/ = 1.0;
  131. lps->up[2] /*Z*/ = 0.0;
  132. lps->trans[0] /*X*/ = 0.0;
  133. lps->trans[1] /*Y*/ = 0.0;
  134. lps->trans[2] /*Z*/ = 0.0;
  135. lps->fov = 45.0;
  136. lps->aspect_ratio = 1.0;
  137. lps->zoom = 1.0;
  138. }
  139. void InitPM (void)
  140. {
  141. HRESULT hr;
  142. hr = CreatePMeshGL(IID_IPMesh, (void**)&pPMesh, NULL, 0);
  143. if (hr == S_OK)
  144. {
  145. hr = pPMesh->QueryInterface(IID_IPMeshGL, (LPVOID*)&pPMeshGL);
  146. if (hr != S_OK)
  147. MessageBox (NULL, "QI for IID_IPMeshGL failed", "Error",
  148. MB_OK);
  149. }
  150. else
  151. {
  152. MessageBox (NULL, "CreatePMeshGL failed", "Error", MB_OK);
  153. }
  154. }
  155. //*------------------------------------------------------------------------
  156. //| WinMain:
  157. //| Parameters:
  158. //| hInstance - Handle to current Data Segment
  159. //| hPrevInstance - Always NULL in Win32
  160. //| lpszCmdLine - Pointer to command line info
  161. //| nCmdShow - Integer value specifying how to start app.,
  162. //| (Iconic [7] or Normal [1,5])
  163. //*------------------------------------------------------------------------
  164. int WINAPI WinMain (HINSTANCE hInstance,
  165. HINSTANCE hPrevInstance,
  166. LPSTR lpszCmdLine,
  167. int nCmdShow)
  168. {
  169. int nReturn = 0;
  170. g_wi.wSize.cx = WIN_WIDTH;
  171. g_wi.wSize.cy = WIN_HEIGHT;
  172. auxInitDisplayMode (AUX_DEPTH | AUX_DOUBLE | AUX_RGB | AUX_HSCROLL);
  173. auxInitPosition (0, 0, WIN_WIDTH, WIN_HEIGHT);
  174. auxInitWindow ("Test");
  175. CustomizeWnd(hInstance, &g_wi);
  176. InitScene (&g_s);
  177. InitPM ();
  178. InitGL();
  179. auxReshapeFunc(SetViewWrap);
  180. auxIdleFunc(spin);
  181. auxHScrollFunc(myHScrollFunc);
  182. auxSetScrollPos (AUX_HSCROLL, auxGetScrollMin(AUX_HSCROLL));
  183. auxKeyFunc( AUX_UP, Key_up );
  184. auxKeyFunc( AUX_DOWN, Key_down );
  185. auxKeyFunc( AUX_i, Key_i ); //Initial Position
  186. auxKeyFunc( AUX_x, Key_x );
  187. auxKeyFunc( AUX_X, Key_X );
  188. auxKeyFunc( AUX_y, Key_y );
  189. auxKeyFunc( AUX_Y, Key_Y );
  190. auxKeyFunc( AUX_z, Key_z );
  191. auxKeyFunc( AUX_Z, Key_Z );
  192. //auxMouseFunc( AUX_LEFTBUTTON, AUX_MOUSEDOWN, trackball_MouseDown );
  193. //auxMouseFunc( AUX_LEFTBUTTON, AUX_MOUSEUP, trackball_MouseUp );
  194. //trackball_Init( g_wi.wSize.cx, g_wi.wSize.cy );
  195. auxMainLoop(DoGlStuff);
  196. return(0);
  197. }
  198. void CustomizeWnd(HINSTANCE hInstance, LPWININFO lpWI)
  199. {
  200. HWND hWnd;
  201. if ((hWnd = auxGetHWND()) == NULL)
  202. {
  203. OutputDebugString("auxGetHWND() failed\n");
  204. return;
  205. }
  206. lpWI->hWnd = hWnd;
  207. SubclassWindow (hWnd, (WNDPROC) MyWndProc);
  208. SendMessage(hWnd, WM_USER, 0L, 0L);
  209. lpWI->hMenu = LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(APPMENU));
  210. SetMenu(hWnd, lpWI->hMenu);
  211. DrawMenuBar(hWnd);
  212. UpdateWinTitle (hWnd);
  213. lpWI->rmouse_down = FALSE;
  214. lpWI->rmouseX = 0;
  215. lpWI->rmouseY = 0;
  216. lpWI->lmouse_down = FALSE;
  217. lpWI->lmouseX = 0;
  218. lpWI->lmouseY = 0;
  219. lpWI->wPosition.x = (int) 0;
  220. lpWI->wPosition.y = (int) 0;
  221. return;
  222. }
  223. /**************************************************************************\
  224. * function: SubclassWindow
  225. *
  226. * input parameters:
  227. * hwnd - window handle to be subclassed,
  228. * SubclassWndProc - the new window procedure.
  229. *
  230. \**************************************************************************/
  231. VOID SubclassWindow (HWND hwnd, WNDPROC SubclassWndProc)
  232. {
  233. LONG pfnOldProc;
  234. pfnOldProc = GetWindowLong (hwnd, GWL_WNDPROC);
  235. SetWindowLong (hwnd, GWL_USERDATA, (LONG) pfnOldProc);
  236. SetWindowLong (hwnd, GWL_WNDPROC, (LONG) SubclassWndProc);
  237. UpdateWinTitle (hwnd);
  238. }
  239. /**************************************************************************\
  240. *
  241. * function: MyWndProc
  242. *
  243. * input parameters: normal window procedure parameters.
  244. *
  245. \**************************************************************************/
  246. LONG APIENTRY MyWndProc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
  247. {
  248. WNDPROC pfnOldProc;
  249. static UINT uiTmID = 0;
  250. pfnOldProc = (WNDPROC) GetWindowLong (hwnd, GWL_USERDATA);
  251. switch (message) {
  252. case WM_INITMENUPOPUP:
  253. EnableMenuItem (g_wi.hMenu, MENU_POINT, MF_GRAYED);
  254. CheckMenuItem (g_wi.hMenu, MENU_WIREFRAME,
  255. ((edge_mode) ? MF_CHECKED : MF_UNCHECKED));
  256. CheckMenuItem (g_wi.hMenu, MENU_SOLID,
  257. ((filled_mode) ? MF_CHECKED : MF_UNCHECKED));
  258. CheckMenuItem (g_wi.hMenu, MENU_FLAT,
  259. ((shade_model == GL_FLAT)? MF_CHECKED:MF_UNCHECKED));
  260. CheckMenuItem (g_wi.hMenu, MENU_GOURAUD,
  261. ((shade_model == GL_SMOOTH)? MF_CHECKED:MF_UNCHECKED));
  262. CheckMenuItem (g_wi.hMenu, MENU_LIGHTING,
  263. ((light_enable)? MF_CHECKED:MF_UNCHECKED));
  264. CheckMenuItem (g_wi.hMenu, MENU_DEPTH,
  265. ((depth_mode)? MF_CHECKED:MF_UNCHECKED));
  266. if (!cull_enable)
  267. {
  268. EnableMenuItem (g_wi.hMenu, MENU_FRONTFACE, MF_GRAYED);
  269. EnableMenuItem (g_wi.hMenu, MENU_BACKFACE, MF_GRAYED);
  270. CheckMenuItem (g_wi.hMenu, MENU_CULL, MF_UNCHECKED);
  271. }
  272. else
  273. {
  274. EnableMenuItem (g_wi.hMenu, MENU_FRONTFACE, MF_ENABLED);
  275. EnableMenuItem (g_wi.hMenu, MENU_BACKFACE, MF_ENABLED);
  276. CheckMenuItem (g_wi.hMenu, MENU_CULL, MF_CHECKED);
  277. }
  278. CheckMenuItem (g_wi.hMenu, MENU_BACKFACE,
  279. ((cull_face==GL_BACK)? MF_CHECKED:MF_UNCHECKED));
  280. CheckMenuItem (g_wi.hMenu, MENU_FRONTFACE,
  281. ((cull_face==GL_FRONT)? MF_CHECKED:MF_UNCHECKED));
  282. CheckMenuItem (g_wi.hMenu, MENU_CCW,
  283. ((front_face==GL_CCW)? MF_CHECKED:MF_UNCHECKED));
  284. CheckMenuItem (g_wi.hMenu, MENU_CW,
  285. ((front_face==GL_CW)? MF_CHECKED:MF_UNCHECKED));
  286. break;
  287. case WM_COMMAND:
  288. switch (LOWORD(wParam))
  289. {
  290. case MENU_STATS:
  291. if (pm_ready)
  292. {
  293. DWORD nv, nf, mv, mf;
  294. char str[100];
  295. HRESULT hr;
  296. hr = pPMesh->GetNumFaces (&nf);
  297. if (hr != S_OK)
  298. MessageBox (NULL, "GetNumFaces failed", "Error", MB_OK);
  299. hr = pPMesh->GetNumVertices (&nv);
  300. if (hr != S_OK)
  301. MessageBox (NULL, "GetNumVertices failed", "Error", MB_OK);
  302. hr = pPMesh->GetMaxFaces (&mf);
  303. if (hr != S_OK)
  304. MessageBox (NULL, "GetMaxFaces failed", "Error", MB_OK);
  305. hr = pPMesh->GetMaxVertices (&mv);
  306. if (hr != S_OK)
  307. MessageBox (NULL, "GetMaxVertices failed", "Error", MB_OK);
  308. sprintf (str, "NumVerts = %d, NumFaces = %d\nMaxVerts = %d, MaxFaces = %d", nv, nf, mv, mf);
  309. MessageBox (NULL, str, "Stats", MB_OK);
  310. }
  311. break; // Not Implemented
  312. case MENU_FILE_OPEN_PMESH:
  313. {
  314. HRESULT hr;
  315. char* file = OpenPMFile(hwnd, "Open a PMesh file", 1);
  316. if (!file) break;
  317. hr = pPMesh->Load(file, NULL, &minV, &maxV, NULL);
  318. if (hr != S_OK)
  319. {
  320. pm_ready = FALSE;
  321. MessageBox (NULL, "Load failed", "Error", MB_OK);
  322. }
  323. else
  324. {
  325. char str[100];
  326. pm_ready = TRUE;
  327. sprintf (str, "Max = %d; Min = %d", maxV, minV);
  328. MessageBox (NULL, str, "Info", MB_OK);
  329. }
  330. break;
  331. }
  332. break; // Not Implemented
  333. case MENU_EXIT:
  334. PostMessage (hwnd, WM_CLOSE, 0, 0);
  335. break;
  336. case MENU_POINT:
  337. break;
  338. case MENU_CULL:
  339. cull_enable = !cull_enable;
  340. if (cull_enable)
  341. glEnable (GL_CULL_FACE);
  342. else
  343. glDisable (GL_CULL_FACE);
  344. break;
  345. case MENU_BACKFACE:
  346. cull_face = GL_BACK;
  347. if (cull_enable) glCullFace (cull_face);
  348. break;
  349. case MENU_FRONTFACE:
  350. cull_face = GL_FRONT;
  351. if (cull_enable) glCullFace (cull_face);
  352. break;
  353. case MENU_CCW:
  354. front_face = GL_CCW;
  355. glFrontFace (front_face);
  356. break;
  357. case MENU_CW:
  358. front_face = GL_CW;
  359. glFrontFace (front_face);
  360. break;
  361. case MENU_WIREFRAME:
  362. edge_mode = !edge_mode;
  363. break;
  364. case MENU_DEPTH:
  365. depth_mode = !depth_mode;
  366. if (depth_mode)
  367. {
  368. glEnable(GL_DEPTH_TEST);
  369. glDepthFunc(GL_LESS);
  370. glDepthMask(GL_TRUE);
  371. }
  372. else
  373. {
  374. glDisable(GL_DEPTH_TEST);
  375. glDepthMask(GL_FALSE);
  376. }
  377. break;
  378. case MENU_SOLID:
  379. filled_mode = !filled_mode;
  380. break;
  381. case MENU_FLAT:
  382. shade_model = GL_FLAT;
  383. glShadeModel (GL_FLAT);
  384. break;
  385. case MENU_GOURAUD:
  386. shade_model = GL_SMOOTH;
  387. glShadeModel (GL_SMOOTH);
  388. break;
  389. case MENU_LIGHTING:
  390. light_enable = !light_enable;
  391. if (light_enable)
  392. EnableLighting ();
  393. else
  394. DisableLighting ();
  395. break;
  396. default:
  397. MessageBox (NULL, "Not yet implemented\r\n", "Warning", MB_OK);
  398. return 0;
  399. }
  400. break;
  401. case WM_RBUTTONDOWN:
  402. SetCapture(hwnd);
  403. g_wi.rmouseX = LOWORD (lParam);
  404. g_wi.rmouseY = HIWORD (lParam);
  405. g_wi.rmouse_down = TRUE;
  406. DoGlStuff ();
  407. break;
  408. case WM_RBUTTONUP:
  409. ReleaseCapture();
  410. g_wi.rmouse_down = FALSE;
  411. DoGlStuff ();
  412. break;
  413. case WM_LBUTTONDOWN:
  414. SetCapture(hwnd);
  415. g_wi.lmouseX = LOWORD (lParam);
  416. g_wi.lmouseY = HIWORD (lParam);
  417. g_wi.lmouse_down = TRUE;
  418. DoGlStuff ();
  419. break;
  420. case WM_LBUTTONUP:
  421. ReleaseCapture();
  422. g_wi.lmouse_down = FALSE;
  423. DoGlStuff ();
  424. break;
  425. case WM_MOVE:
  426. g_wi.wPosition.x = (int) LOWORD(lParam);
  427. g_wi.wPosition.y = (int) HIWORD(lParam);
  428. break;
  429. case WM_USER:
  430. case WM_DESTROY:
  431. default:
  432. return (pfnOldProc)(hwnd, message, wParam, lParam);
  433. } /* end switch */
  434. //DoGlStuff ();
  435. return 0;
  436. }
  437. void UpdateWinTitle (HWND hwnd)
  438. {
  439. char str[100];
  440. sprintf (str, "LOD=%f", pm_lod_level);
  441. SetWindowText (hwnd, str);
  442. }