MessageProc.cpp 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121
  1. //-------------------------------------------------------------------------------
  2. /**
  3. * This program is distributed under the terms of the GNU Lesser General
  4. * Public License (LGPL).
  5. *
  6. * ASSIMP Viewer Utility
  7. *
  8. */
  9. //-------------------------------------------------------------------------------
  10. #include "stdafx.h"
  11. #include "assimp_view.h"
  12. namespace AssimpView {
  13. // Static array to keep custom color values
  14. COLORREF g_aclCustomColors[16] =
  15. {0};
  16. //-------------------------------------------------------------------------------
  17. // Setup file associations for all formats supported by the library
  18. //
  19. // File associations are registered in HKCU\Software\Classes. They might
  20. // be overwritten by global file associations.
  21. //-------------------------------------------------------------------------------
  22. void MakeFileAssociations()
  23. {
  24. /*
  25. ; .wscript
  26. root: HKCR; Flags: deletekey; Subkey: ".uscript"; ValueType: string; ValueData: "UE_WSCRIPT_CLASS"; Components: rt
  27. root: HKCR; Flags: deletekey; Subkey: "UE_WSCRIPT_CLASS"; ValueName:; ValueType: string; ValueData: "UtopicEngine Console Script"; Components: rt
  28. root: HKCR; Flags: deletekey; Subkey: "UE_WSCRIPT_CLASS\shell\open\command"; ValueName:; ValueType: string; ValueData: "notepad.exe %1"; Components: rt
  29. */
  30. char szTemp2[MAX_PATH];
  31. char szTemp[MAX_PATH + 10];
  32. GetModuleFileName(NULL,szTemp2,MAX_PATH);
  33. sprintf(szTemp,"%s %%1",szTemp2);
  34. HKEY hTemp;
  35. // -------------------------------------------------
  36. // .3ds
  37. // -------------------------------------------------
  38. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.3ds",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  39. RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"AV3DSCLASS",(DWORD)strlen("AV3DSCLASS")+1);
  40. RegCloseKey(hTemp);
  41. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AV3DSCLASS",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  42. RegCloseKey(hTemp);
  43. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AV3DSCLASS\\shell\\open\\command",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  44. RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)szTemp,(DWORD)strlen(szTemp)+1);
  45. RegCloseKey(hTemp);
  46. // -------------------------------------------------
  47. // .x
  48. // -------------------------------------------------
  49. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.x",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  50. RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"AVXCLASS",(DWORD)strlen("AVXCLASS")+1);
  51. RegCloseKey(hTemp);
  52. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVXCLASS",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  53. RegCloseKey(hTemp);
  54. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVXCLASS\\shell\\open\\command",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  55. RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)szTemp,(DWORD)strlen(szTemp)+1);
  56. RegCloseKey(hTemp);
  57. // -------------------------------------------------
  58. // .obj
  59. // -------------------------------------------------
  60. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.obj",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  61. RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"AVOBJCLASS",(DWORD)strlen("AVOBJCLASS")+1);
  62. RegCloseKey(hTemp);
  63. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVOBJCLASS",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  64. RegCloseKey(hTemp);
  65. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVOBJCLASS\\shell\\open\\command",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  66. RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)szTemp,(DWORD)strlen(szTemp)+1);
  67. RegCloseKey(hTemp);
  68. // -------------------------------------------------
  69. // .ms3d
  70. // -------------------------------------------------
  71. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.ms3d",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  72. RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"AVMS3DCLASS",(DWORD)strlen("AVMS3DCLASS")+1);
  73. RegCloseKey(hTemp);
  74. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVMS3DCLASS",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  75. RegCloseKey(hTemp);
  76. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVMS3DCLASS\\shell\\open\\command",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  77. RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)szTemp,(DWORD)strlen(szTemp)+1);
  78. RegCloseKey(hTemp);
  79. // -------------------------------------------------
  80. // .md3
  81. // -------------------------------------------------
  82. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.md3",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  83. RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"AVMD3CLASS",(DWORD)strlen("AVMD3CLASS")+1);
  84. RegCloseKey(hTemp);
  85. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVMD3CLASS",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  86. RegCloseKey(hTemp);
  87. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVMD3CLASS\\shell\\open\\command",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  88. RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)szTemp,(DWORD)strlen(szTemp)+1);
  89. RegCloseKey(hTemp);
  90. // -------------------------------------------------
  91. // .md2
  92. // -------------------------------------------------
  93. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.md2",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  94. RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"AVMD2CLASS",(DWORD)strlen("AVMD2CLASS")+1);
  95. RegCloseKey(hTemp);
  96. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVMD3CLASS",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  97. RegCloseKey(hTemp);
  98. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVMD2CLASS\\shell\\open\\command",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  99. RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)szTemp,(DWORD)strlen(szTemp)+1);
  100. RegCloseKey(hTemp);
  101. // -------------------------------------------------
  102. // .md4
  103. // -------------------------------------------------
  104. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.md4",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  105. RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"AVMD4CLASS",(DWORD)strlen("AVMD4CLASS")+1);
  106. RegCloseKey(hTemp);
  107. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVMD4CLASS",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  108. RegCloseKey(hTemp);
  109. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVMD4CLASS\\shell\\open\\command",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  110. RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)szTemp,(DWORD)strlen(szTemp)+1);
  111. RegCloseKey(hTemp);
  112. // -------------------------------------------------
  113. // .md5
  114. // -------------------------------------------------
  115. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.md5",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  116. RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"AVMD5CLASS",(DWORD)strlen("AVMD5CLASS")+1);
  117. RegCloseKey(hTemp);
  118. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVMD5CLASS",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  119. RegCloseKey(hTemp);
  120. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVMD5CLASS\\shell\\open\\command",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  121. RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)szTemp,(DWORD)strlen(szTemp)+1);
  122. RegCloseKey(hTemp);
  123. // -------------------------------------------------
  124. // .ply
  125. // -------------------------------------------------
  126. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.ply",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  127. RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"AVPLYCLASS",(DWORD)strlen("AVPLYCLASS")+1);
  128. RegCloseKey(hTemp);
  129. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVPLYCLASS",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  130. RegCloseKey(hTemp);
  131. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVPLYCLASS\\shell\\open\\command",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  132. RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)szTemp,(DWORD)strlen(szTemp)+1);
  133. RegCloseKey(hTemp);
  134. CLogDisplay::Instance().AddEntry("[OK] File assocations have been registered",
  135. D3DCOLOR_ARGB(0xFF,0,0xFF,0));
  136. }
  137. //-------------------------------------------------------------------------------
  138. // Recreate all specular materials depending on the current specularity settings
  139. //
  140. // Diffuse-only materials are ignored.
  141. // Must be called after specular highlights have been toggled
  142. //-------------------------------------------------------------------------------
  143. void UpdateSpecularMaterials()
  144. {
  145. if (g_pcAsset && g_pcAsset->pcScene)
  146. {
  147. for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
  148. {
  149. if (aiShadingMode_Phong == g_pcAsset->apcMeshes[i]->eShadingMode)
  150. {
  151. DeleteMaterial(g_pcAsset->apcMeshes[i]);
  152. CreateMaterial(g_pcAsset->apcMeshes[i],g_pcAsset->pcScene->mMeshes[i]);
  153. }
  154. }
  155. }
  156. }
  157. //-------------------------------------------------------------------------------
  158. // Handle command line parameters
  159. //
  160. // The function loads an asset specified on the command line as first argument
  161. // Other command line parameters are not handled
  162. //-------------------------------------------------------------------------------
  163. void HandleCommandLine(char* p_szCommand)
  164. {
  165. char* sz = p_szCommand;
  166. //bool bQuak = false;
  167. if (strlen(sz) < 2)return;
  168. if (*sz == '\"')
  169. {
  170. char* sz2 = strrchr(sz,'\"');
  171. if (sz2)*sz2 = 0;
  172. }
  173. strcpy( g_szFileName, sz );
  174. LoadAsset();
  175. }
  176. //-------------------------------------------------------------------------------
  177. // Main message procedure of the application
  178. //
  179. // The function handles all incoming messages for the main window.
  180. // However, if does not directly process input commands.
  181. // NOTE: Due to the impossibility to process WM_CHAR messages in dialogs
  182. // properly the code for all hotkeys has been moved to the WndMain
  183. //-------------------------------------------------------------------------------
  184. INT_PTR CALLBACK MessageProc(HWND hwndDlg,UINT uMsg,
  185. WPARAM wParam,LPARAM lParam)
  186. {
  187. UNREFERENCED_PARAMETER(lParam);
  188. UNREFERENCED_PARAMETER(wParam);
  189. int xPos,yPos;
  190. int xPos2,yPos2;
  191. int fHalfX;
  192. int fHalfY;
  193. TRACKMOUSEEVENT sEvent;
  194. switch (uMsg)
  195. {
  196. case WM_INITDIALOG:
  197. CheckDlgButton(hwndDlg,IDC_TOGGLEMS,BST_CHECKED);
  198. CheckDlgButton(hwndDlg,IDC_ZOOM,BST_CHECKED);
  199. CheckDlgButton(hwndDlg,IDC_AUTOROTATE,BST_CHECKED);
  200. SetDlgItemText(hwndDlg,IDC_EVERT,"0");
  201. SetDlgItemText(hwndDlg,IDC_EFACE,"0");
  202. SetDlgItemText(hwndDlg,IDC_EMAT,"0");
  203. SetDlgItemText(hwndDlg,IDC_ESHADER,"0");
  204. return TRUE;
  205. case WM_MOUSEWHEEL:
  206. if (!g_bFPSView)
  207. {
  208. g_sCamera.vPos.z += GET_WHEEL_DELTA_WPARAM(wParam) / 50.0f;
  209. }
  210. else
  211. {
  212. g_sCamera.vPos += (GET_WHEEL_DELTA_WPARAM(wParam) / 50.0f) *
  213. g_sCamera.vLookAt.Normalize();
  214. }
  215. return TRUE;
  216. case WM_MOUSELEAVE:
  217. g_bMousePressed = false;
  218. g_bMousePressedR = false;
  219. g_bMousePressedM = false;
  220. g_bMousePressedBoth = false;
  221. return TRUE;
  222. case WM_LBUTTONDBLCLK:
  223. CheckDlgButton(hwndDlg,IDC_AUTOROTATE,
  224. IsDlgButtonChecked(hwndDlg,IDC_AUTOROTATE) == BST_CHECKED
  225. ? BST_UNCHECKED : BST_CHECKED);
  226. g_sOptions.bRotate = !g_sOptions.bRotate;
  227. return TRUE;
  228. case WM_CLOSE:
  229. PostQuitMessage(0);
  230. DestroyWindow(hwndDlg);
  231. return TRUE;
  232. case WM_LBUTTONDOWN:
  233. g_bMousePressed = true;
  234. // register a mouse track handler to be sure we'll know
  235. // when the mouse leaves the display view again
  236. sEvent.cbSize = sizeof(TRACKMOUSEEVENT);
  237. sEvent.dwFlags = TME_LEAVE;
  238. sEvent.hwndTrack = g_hDlg;
  239. sEvent.dwHoverTime = HOVER_DEFAULT;
  240. TrackMouseEvent(&sEvent);
  241. if (g_bMousePressedR)
  242. {
  243. g_bMousePressed = false;
  244. g_bMousePressedR = false;
  245. g_bMousePressedBoth = true;
  246. return TRUE;
  247. }
  248. // need to determine the position of the mouse and the
  249. // distance from the center
  250. xPos = (int)(short)LOWORD(lParam);
  251. yPos = (int)(short)HIWORD(lParam);
  252. xPos -= 10;
  253. yPos -= 10;
  254. xPos2 = xPos-3;
  255. yPos2 = yPos-5;
  256. RECT sRect;
  257. GetWindowRect(GetDlgItem(g_hDlg,IDC_RT),&sRect);
  258. sRect.right -= sRect.left;
  259. sRect.bottom -= sRect.top;
  260. // if the mouse klick was inside the viewer panel
  261. // give the focus to it
  262. if (xPos > 0 && xPos < sRect.right && yPos > 0 && yPos < sRect.bottom)
  263. {
  264. SetFocus(GetDlgItem(g_hDlg,IDC_RT));
  265. }
  266. // g_bInvert stores whether the mouse has started on the negative
  267. // x or on the positive x axis of the imaginary coordinate system
  268. // with origin p at the center of the HUD texture
  269. xPos -= sRect.right/2;
  270. yPos -= sRect.bottom/2;
  271. if (xPos > 0)g_bInvert = true;
  272. else g_bInvert = false;
  273. D3DSURFACE_DESC sDesc;
  274. g_pcTexture->GetLevelDesc(0,&sDesc);
  275. fHalfX = (int)(((float)sRect.right-(float)sDesc.Width) / 2.0f);
  276. fHalfY = (int)(((float)sRect.bottom-(float)sDesc.Height) / 2.0f);
  277. // Determine the input operation to perform for this position
  278. g_eClick = EClickPos_Outside;
  279. if (xPos2 >= fHalfX && xPos2 < fHalfX + (int)sDesc.Width &&
  280. yPos2 >= fHalfY && yPos2 < fHalfY + (int)sDesc.Height &&
  281. NULL != g_szImageMask)
  282. {
  283. // inside the texture. Lookup the grayscale value from it
  284. xPos2 -= fHalfX;
  285. yPos2 -= fHalfY;
  286. unsigned char chValue = g_szImageMask[xPos2 + yPos2 * sDesc.Width];
  287. if (chValue > 0xFF-20)
  288. {
  289. g_eClick = EClickPos_Circle;
  290. }
  291. else if (chValue < 0xFF-20 && chValue > 185)
  292. {
  293. g_eClick = EClickPos_CircleHor;
  294. }
  295. else if (chValue > 0x10 && chValue < 185)
  296. {
  297. g_eClick = EClickPos_CircleVert;
  298. }
  299. }
  300. // OLD version of this code. Not using a texture lookup to
  301. // determine the exact position, but using maths and the fact
  302. // that we have a circle f(x) = m +rx ;-)
  303. #if 0
  304. g_eClick = EClickPos_Circle;
  305. if (yPos < 10 && yPos > -10)
  306. {
  307. if ((xPos2 > fHalfX-5 && xPos2 < fHalfX+15) ||
  308. (xPos2 > fHalfX+(int)sDesc.Width-10 && xPos2 < fHalfX+(int)sDesc.Width+10))
  309. {
  310. g_eClick = EClickPos_CircleHor;
  311. }
  312. }
  313. else if (xPos < 10 && xPos > -10)
  314. {
  315. if ((yPos2 > fHalfY-5 && yPos2 < fHalfY+15) ||
  316. (yPos2 > fHalfY+(int)sDesc.Height-10 && yPos2 < fHalfY+(int)sDesc.Height+10))
  317. {
  318. g_eClick = EClickPos_CircleVert;
  319. }
  320. }
  321. else if (sqrtf((float)(xPos * xPos + yPos * yPos)) > (float)(sDesc.Width/2))
  322. {
  323. g_eClick = EClickPos_Outside;
  324. }
  325. #endif
  326. return TRUE;
  327. case WM_RBUTTONDOWN:
  328. g_bMousePressedR = true;
  329. sEvent.cbSize = sizeof(TRACKMOUSEEVENT);
  330. sEvent.dwFlags = TME_LEAVE;
  331. sEvent.hwndTrack = g_hDlg;
  332. sEvent.dwHoverTime = HOVER_DEFAULT;
  333. TrackMouseEvent(&sEvent);
  334. if (g_bMousePressed)
  335. {
  336. g_bMousePressedR = false;
  337. g_bMousePressed = false;
  338. g_bMousePressedBoth = true;
  339. }
  340. return TRUE;
  341. case WM_MBUTTONDOWN:
  342. g_bMousePressedM = true;
  343. sEvent.cbSize = sizeof(TRACKMOUSEEVENT);
  344. sEvent.dwFlags = TME_LEAVE;
  345. sEvent.hwndTrack = g_hDlg;
  346. sEvent.dwHoverTime = HOVER_DEFAULT;
  347. TrackMouseEvent(&sEvent);
  348. return TRUE;
  349. case WM_LBUTTONUP:
  350. g_bMousePressed = false;
  351. g_bMousePressedBoth = false;
  352. return TRUE;
  353. case WM_RBUTTONUP:
  354. g_bMousePressedR = false;
  355. g_bMousePressedBoth = false;
  356. return TRUE;
  357. case WM_MBUTTONUP:
  358. g_bMousePressedM = false;
  359. return TRUE;
  360. case WM_COMMAND:
  361. if (ID_VIEWER_QUIT == LOWORD(wParam))
  362. {
  363. PostQuitMessage(0);
  364. DestroyWindow(hwndDlg);
  365. }
  366. else if (ID_VIEWER_RESETVIEW == LOWORD(wParam))
  367. {
  368. g_sCamera.vPos = aiVector3D(0.0f,0.0f,-10.0f);
  369. g_sCamera.vLookAt = aiVector3D(0.0f,0.0f,1.0f);
  370. g_sCamera.vUp = aiVector3D(0.0f,1.0f,0.0f);
  371. g_sCamera.vRight = aiVector3D(0.0f,1.0f,0.0f);
  372. g_mWorldRotate = aiMatrix4x4();
  373. g_mWorld = aiMatrix4x4();
  374. // don't forget to reset the st
  375. CBackgroundPainter::Instance().ResetSB();
  376. }
  377. else if (ID__HELP == LOWORD(wParam))
  378. {
  379. DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_AVHELP),
  380. hwndDlg,&HelpDialogProc);
  381. }
  382. else if (ID__ABOUT == LOWORD(wParam))
  383. {
  384. DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_ABOUTBOX),
  385. hwndDlg,&AboutMessageProc);
  386. }
  387. else if (ID_VIEWER_H == LOWORD(wParam))
  388. {
  389. MakeFileAssociations();
  390. }
  391. else if (ID_BACKGROUND_CLEAR == LOWORD(wParam))
  392. {
  393. D3DCOLOR clrColor = D3DCOLOR_ARGB(0xFF,100,100,100);
  394. CBackgroundPainter::Instance().SetColor(clrColor);
  395. HKEY hTemp;
  396. RegCreateKeyEx(HKEY_CURRENT_USER,
  397. "Software\\ASSIMP\\Viewer",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  398. RegSetValueExA(hTemp,"LastSkyBoxSrc",0,REG_SZ,(const BYTE*)"",MAX_PATH);
  399. RegSetValueExA(hTemp,"LastTextureSrc",0,REG_SZ,(const BYTE*)"",MAX_PATH);
  400. RegSetValueExA(hTemp,"Color",0,REG_DWORD,(const BYTE*)&clrColor,4);
  401. RegCloseKey(hTemp);
  402. }
  403. else if (ID_BACKGROUND_SETCOLOR == LOWORD(wParam))
  404. {
  405. HKEY hTemp;
  406. RegCreateKeyEx(HKEY_CURRENT_USER,
  407. "Software\\ASSIMP\\Viewer",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  408. RegSetValueExA(hTemp,"LastSkyBoxSrc",0,REG_SZ,(const BYTE*)"",MAX_PATH);
  409. RegSetValueExA(hTemp,"LastTextureSrc",0,REG_SZ,(const BYTE*)"",MAX_PATH);
  410. CHOOSECOLOR clr;
  411. clr.lStructSize = sizeof(CHOOSECOLOR);
  412. clr.hwndOwner = hwndDlg;
  413. clr.Flags = CC_RGBINIT | CC_FULLOPEN;
  414. clr.rgbResult = RGB(100,100,100);
  415. clr.lpCustColors = g_aclCustomColors;
  416. clr.lpfnHook = NULL;
  417. clr.lpTemplateName = NULL;
  418. clr.lCustData = NULL;
  419. ChooseColor(&clr);
  420. D3DCOLOR clrColor = D3DCOLOR_ARGB(0xFF,
  421. GetRValue(clr.rgbResult),
  422. GetGValue(clr.rgbResult),
  423. GetBValue(clr.rgbResult));
  424. CBackgroundPainter::Instance().SetColor(clrColor);
  425. RegSetValueExA(hTemp,"Color",0,REG_DWORD,(const BYTE*)&clrColor,4);
  426. RegCloseKey(hTemp);
  427. }
  428. else if (ID_BACKGROUND_LOADTEXTURE == LOWORD(wParam))
  429. {
  430. char szFileName[MAX_PATH];
  431. DWORD dwTemp = MAX_PATH;
  432. HKEY hTemp;
  433. RegCreateKeyEx(HKEY_CURRENT_USER,
  434. "Software\\ASSIMP\\Viewer",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  435. if(ERROR_SUCCESS != RegQueryValueEx(hTemp,"TextureSrc",NULL,NULL,
  436. (BYTE*)szFileName,&dwTemp))
  437. {
  438. // Key was not found. Use C:
  439. strcpy(szFileName,"");
  440. }
  441. else
  442. {
  443. // need to remove the file name
  444. char* sz = strrchr(szFileName,'\\');
  445. if (!sz)sz = strrchr(szFileName,'/');
  446. if (!sz)*sz = 0;
  447. }
  448. OPENFILENAME sFilename1 = {
  449. sizeof(OPENFILENAME),
  450. g_hDlg,GetModuleHandle(NULL),
  451. "Textures\0*.png;*.dds;*.tga;*.bmp;*.tif;*.ppm;*.ppx;*.jpg;*.jpeg;*.exr\0*.*\0", NULL, 0, 1,
  452. szFileName, MAX_PATH, NULL, 0, NULL,
  453. "Open texture as background",
  454. OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_NOCHANGEDIR,
  455. 0, 1, ".jpg", 0, NULL, NULL
  456. };
  457. if(GetOpenFileName(&sFilename1) == 0) return TRUE;
  458. // Now store the file in the registry
  459. RegSetValueExA(hTemp,"TextureSrc",0,REG_SZ,(const BYTE*)szFileName,MAX_PATH);
  460. RegSetValueExA(hTemp,"LastTextureSrc",0,REG_SZ,(const BYTE*)szFileName,MAX_PATH);
  461. RegSetValueExA(hTemp,"LastSkyBoxSrc",0,REG_SZ,(const BYTE*)"",MAX_PATH);
  462. RegCloseKey(hTemp);
  463. CBackgroundPainter::Instance().SetTextureBG(szFileName);
  464. }
  465. else if (ID_BACKGROUND_LOADSKYBOX == LOWORD(wParam))
  466. {
  467. char szFileName[MAX_PATH];
  468. DWORD dwTemp = MAX_PATH;
  469. HKEY hTemp;
  470. RegCreateKeyEx(HKEY_CURRENT_USER,
  471. "Software\\ASSIMP\\Viewer",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  472. if(ERROR_SUCCESS != RegQueryValueEx(hTemp,"SkyBoxSrc",NULL,NULL,
  473. (BYTE*)szFileName,&dwTemp))
  474. {
  475. // Key was not found. Use C:
  476. strcpy(szFileName,"");
  477. }
  478. else
  479. {
  480. // need to remove the file name
  481. char* sz = strrchr(szFileName,'\\');
  482. if (!sz)sz = strrchr(szFileName,'/');
  483. if (!sz)*sz = 0;
  484. }
  485. OPENFILENAME sFilename1 = {
  486. sizeof(OPENFILENAME),
  487. g_hDlg,GetModuleHandle(NULL),
  488. "Skyboxes\0*.dds\0*.*\0", NULL, 0, 1,
  489. szFileName, MAX_PATH, NULL, 0, NULL,
  490. "Open skybox as background",
  491. OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_NOCHANGEDIR,
  492. 0, 1, ".dds", 0, NULL, NULL
  493. };
  494. if(GetOpenFileName(&sFilename1) == 0) return TRUE;
  495. // Now store the file in the registry
  496. RegSetValueExA(hTemp,"SkyBoxSrc",0,REG_SZ,(const BYTE*)szFileName,MAX_PATH);
  497. RegSetValueExA(hTemp,"LastSkyBoxSrc",0,REG_SZ,(const BYTE*)szFileName,MAX_PATH);
  498. RegSetValueExA(hTemp,"LastTextureSrc",0,REG_SZ,(const BYTE*)"",MAX_PATH);
  499. RegCloseKey(hTemp);
  500. CBackgroundPainter::Instance().SetCubeMapBG(szFileName);
  501. }
  502. else if (ID_VIEWER_SAVESCREENSHOTTOFILE == LOWORD(wParam))
  503. {
  504. char szFileName[MAX_PATH];
  505. DWORD dwTemp = MAX_PATH;
  506. HKEY hTemp;
  507. RegCreateKeyEx(HKEY_CURRENT_USER,
  508. "Software\\ASSIMP\\Viewer",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  509. if(ERROR_SUCCESS != RegQueryValueEx(hTemp,"ScreenShot",NULL,NULL,
  510. (BYTE*)szFileName,&dwTemp))
  511. {
  512. // Key was not found. Use C:
  513. strcpy(szFileName,"");
  514. }
  515. else
  516. {
  517. // need to remove the file name
  518. char* sz = strrchr(szFileName,'\\');
  519. if (!sz)sz = strrchr(szFileName,'/');
  520. if (!sz)*sz = 0;
  521. }
  522. OPENFILENAME sFilename1 = {
  523. sizeof(OPENFILENAME),
  524. g_hDlg,GetModuleHandle(NULL),
  525. "PNG Images\0*.png", NULL, 0, 1,
  526. szFileName, MAX_PATH, NULL, 0, NULL,
  527. "Save Screenshot to file",
  528. OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_NOCHANGEDIR,
  529. 0, 1, ".png", 0, NULL, NULL
  530. };
  531. if(GetSaveFileName(&sFilename1) == 0) return TRUE;
  532. // Now store the file in the registry
  533. RegSetValueExA(hTemp,"ScreenShot",0,REG_SZ,(const BYTE*)szFileName,MAX_PATH);
  534. RegCloseKey(hTemp);
  535. IDirect3DSurface9* pi;
  536. g_piDevice->GetRenderTarget(0,&pi);
  537. D3DXSaveSurfaceToFile(szFileName,D3DXIFF_PNG,
  538. pi,NULL,NULL);
  539. pi->Release();
  540. }
  541. else if (ID_VIEWER_OPEN == LOWORD(wParam))
  542. {
  543. char szFileName[MAX_PATH];
  544. DWORD dwTemp = MAX_PATH;
  545. HKEY hTemp;
  546. RegCreateKeyEx(HKEY_CURRENT_USER,
  547. "Software\\ASSIMP\\Viewer",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  548. if(ERROR_SUCCESS != RegQueryValueEx(hTemp,"CurrentApp",NULL,NULL,
  549. (BYTE*)szFileName,&dwTemp))
  550. {
  551. // Key was not found. Use C:
  552. strcpy(szFileName,"");
  553. }
  554. else
  555. {
  556. // need to remove the file name
  557. char* sz = strrchr(szFileName,'\\');
  558. if (!sz)sz = strrchr(szFileName,'/');
  559. if (!sz)*sz = 0;
  560. }
  561. OPENFILENAME sFilename1 = {
  562. sizeof(OPENFILENAME),
  563. g_hDlg,GetModuleHandle(NULL),
  564. "ASSIMP assets\0*.x;*.obj;*.ms3d;*.3ds;*.md3;*.md1;*.md2;*.md4;*.md5;*.ply\0All files\0*.*", NULL, 0, 1,
  565. szFileName, MAX_PATH, NULL, 0, NULL,
  566. "Import Asset into ASSIMP",
  567. OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_NOCHANGEDIR,
  568. 0, 1, ".x", 0, NULL, NULL
  569. };
  570. if(GetOpenFileName(&sFilename1) == 0) return TRUE;
  571. // Now store the file in the registry
  572. RegSetValueExA(hTemp,"CurrentApp",0,REG_SZ,(const BYTE*)szFileName,MAX_PATH);
  573. RegCloseKey(hTemp);
  574. if (0 != strcmp(g_szFileName,szFileName))
  575. {
  576. strcpy(g_szFileName, szFileName);
  577. DeleteAssetData();
  578. DeleteAsset();
  579. LoadAsset();
  580. }
  581. }
  582. else if (ID_VIEWER_CLOSEASSET == LOWORD(wParam))
  583. {
  584. DeleteAssetData();
  585. DeleteAsset();
  586. }
  587. else if (BN_CLICKED == HIWORD(wParam))
  588. {
  589. if (IDC_TOGGLEMS == LOWORD(wParam))
  590. {
  591. g_sOptions.bMultiSample = !g_sOptions.bMultiSample;
  592. DeleteAssetData();
  593. ShutdownDevice();
  594. if (0 == CreateDevice())
  595. {
  596. CLogDisplay::Instance().AddEntry(
  597. "[ERROR] Failed to toggle MultiSampling mode");
  598. g_sOptions.bMultiSample = !g_sOptions.bMultiSample;
  599. CreateDevice();
  600. }
  601. CreateAssetData();
  602. if (g_sOptions.bMultiSample)
  603. {
  604. CLogDisplay::Instance().AddEntry(
  605. "[OK] Changed MultiSampling mode to the maximum value for this device");
  606. }
  607. else
  608. {
  609. CLogDisplay::Instance().AddEntry(
  610. "[OK] MultiSampling has been disabled");
  611. }
  612. }
  613. else if (IDC_TOGGLEMAT == LOWORD(wParam))
  614. {
  615. g_sOptions.bRenderMats = !g_sOptions.bRenderMats;
  616. }
  617. else if (IDC_NOSPECULAR == LOWORD(wParam))
  618. {
  619. g_sOptions.bNoSpecular = !g_sOptions.bNoSpecular;
  620. UpdateSpecularMaterials();
  621. }
  622. else if (IDC_ZOOM == LOWORD(wParam))
  623. {
  624. g_bFPSView = !g_bFPSView;
  625. SetupFPSView();
  626. }
  627. else if (IDC_TOGGLENORMALS == LOWORD(wParam))
  628. {
  629. g_sOptions.bRenderNormals = !g_sOptions.bRenderNormals;
  630. }
  631. else if (IDC_LOWQUALITY == LOWORD(wParam))
  632. {
  633. g_sOptions.bLowQuality = !g_sOptions.bLowQuality;
  634. }
  635. else if (IDC_3LIGHTS == LOWORD(wParam))
  636. {
  637. g_sOptions.b3Lights = !g_sOptions.b3Lights;
  638. }
  639. else if (IDC_LIGHTROTATE == LOWORD(wParam))
  640. {
  641. g_sOptions.bLightRotate = !g_sOptions.bLightRotate;
  642. }
  643. else if (IDC_AUTOROTATE == LOWORD(wParam))
  644. {
  645. g_sOptions.bRotate = !g_sOptions.bRotate;
  646. }
  647. else if (IDC_TOGGLEWIRE == LOWORD(wParam))
  648. {
  649. if (g_sOptions.eDrawMode == RenderOptions::WIREFRAME)
  650. g_sOptions.eDrawMode = RenderOptions::NORMAL;
  651. else g_sOptions.eDrawMode = RenderOptions::WIREFRAME;
  652. }
  653. }
  654. return TRUE;
  655. };
  656. return FALSE;
  657. }
  658. //-------------------------------------------------------------------------------
  659. // Message prcoedure for the progress dialog
  660. //-------------------------------------------------------------------------------
  661. INT_PTR CALLBACK ProgressMessageProc(HWND hwndDlg,UINT uMsg,
  662. WPARAM wParam,LPARAM lParam)
  663. {
  664. UNREFERENCED_PARAMETER(lParam);
  665. switch (uMsg)
  666. {
  667. case WM_INITDIALOG:
  668. SendDlgItemMessage(hwndDlg,IDC_PROGRESS,PBM_SETRANGE,0,
  669. MAKELPARAM(0,500));
  670. SetTimer(hwndDlg,0,40,NULL);
  671. return TRUE;
  672. case WM_CLOSE:
  673. EndDialog(hwndDlg,0);
  674. return TRUE;
  675. case WM_COMMAND:
  676. if (IDOK == LOWORD(wParam))
  677. {
  678. #if 0
  679. g_bLoadingCanceled = true;
  680. TerminateThread(g_hThreadHandle,5);
  681. g_pcAsset = NULL;
  682. EndDialog(hwndDlg,0);
  683. #endif
  684. // PROBLEM: If we terminate the loader thread, ASSIMP's state
  685. // is undefined. Any further attempts to load assets will
  686. // fail.
  687. exit(5);
  688. // return TRUE;
  689. }
  690. case WM_TIMER:
  691. UINT iPos = (UINT)SendDlgItemMessage(hwndDlg,IDC_PROGRESS,PBM_GETPOS,0,0);
  692. iPos += 10;
  693. if (iPos > 490)iPos = 0;
  694. SendDlgItemMessage(hwndDlg,IDC_PROGRESS,PBM_SETPOS,iPos,0);
  695. if (g_bLoadingFinished)
  696. {
  697. EndDialog(hwndDlg,0);
  698. return TRUE;
  699. }
  700. return TRUE;
  701. }
  702. return FALSE;
  703. }
  704. //-------------------------------------------------------------------------------
  705. // Message procedure for the about dialog
  706. //-------------------------------------------------------------------------------
  707. INT_PTR CALLBACK AboutMessageProc(HWND hwndDlg,UINT uMsg,
  708. WPARAM wParam,LPARAM lParam)
  709. {
  710. UNREFERENCED_PARAMETER(lParam);
  711. switch (uMsg)
  712. {
  713. case WM_CLOSE:
  714. EndDialog(hwndDlg,0);
  715. return TRUE;
  716. case WM_COMMAND:
  717. if (IDOK == LOWORD(wParam))
  718. {
  719. EndDialog(hwndDlg,0);
  720. return TRUE;
  721. }
  722. }
  723. return FALSE;
  724. }
  725. };
  726. using namespace AssimpView;
  727. //-------------------------------------------------------------------------------
  728. // Entry point to the application
  729. //-------------------------------------------------------------------------------
  730. int APIENTRY _tWinMain(HINSTANCE hInstance,
  731. HINSTANCE hPrevInstance,
  732. LPTSTR lpCmdLine,
  733. int nCmdShow)
  734. {
  735. UNREFERENCED_PARAMETER(hPrevInstance);
  736. UNREFERENCED_PARAMETER(lpCmdLine);
  737. // needed for the RichEdit control in the about/help dialog
  738. LoadLibrary( "riched20.dll" );
  739. InitCommonControls();
  740. g_hInstance = hInstance;
  741. if (0 == InitD3D())
  742. {
  743. MessageBox(NULL,"Failed to initialize Direct3D 9",
  744. "ASSIMP ModelViewer",MB_OK);
  745. return -6;
  746. }
  747. HWND hDlg = CreateDialog(hInstance,MAKEINTRESOURCE(IDD_DIALOGMAIN),
  748. NULL,&MessageProc);
  749. if (NULL == hDlg)
  750. {
  751. MessageBox(NULL,"Failed to create dialog from resource",
  752. "ASSIMP ModelViewer",MB_OK);
  753. return -5;
  754. }
  755. g_hDlg = hDlg;
  756. MSG uMsg;
  757. memset(&uMsg,0,sizeof( MSG));
  758. ShowWindow( hDlg, nCmdShow );
  759. UpdateWindow( hDlg );
  760. if (0 == CreateDevice(true,false,true))
  761. {
  762. MessageBox(NULL,"Failed to initialize Direct3D 9 (2)",
  763. "ASSIMP ModelViewer",MB_OK);
  764. return -4;
  765. }
  766. CLogDisplay::Instance().AddEntry("[OK] The viewer has been initialized successfully");
  767. // recover background skyboxes/textures from the last session
  768. HKEY hTemp;
  769. union
  770. {
  771. char szFileName[MAX_PATH];
  772. D3DCOLOR clrColor;
  773. };
  774. DWORD dwTemp = MAX_PATH;
  775. RegCreateKeyEx(HKEY_CURRENT_USER,
  776. "Software\\ASSIMP\\Viewer",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
  777. if(ERROR_SUCCESS == RegQueryValueEx(hTemp,"LastSkyBoxSrc",NULL,NULL,
  778. (BYTE*)szFileName,&dwTemp) && '\0' != szFileName[0])
  779. {
  780. CBackgroundPainter::Instance().SetCubeMapBG(szFileName);
  781. }
  782. else if(ERROR_SUCCESS == RegQueryValueEx(hTemp,"LastTextureSrc",NULL,NULL,
  783. (BYTE*)szFileName,&dwTemp) && '\0' != szFileName[0])
  784. {
  785. CBackgroundPainter::Instance().SetTextureBG(szFileName);
  786. }
  787. else if(ERROR_SUCCESS == RegQueryValueEx(hTemp,"Color",NULL,NULL,
  788. (BYTE*)&clrColor,&dwTemp))
  789. {
  790. CBackgroundPainter::Instance().SetColor(clrColor);
  791. }
  792. RegCloseKey(hTemp);
  793. // now handle command line arguments
  794. HandleCommandLine(lpCmdLine);
  795. double adLast[30];
  796. for (int i = 0; i < 30;++i)adLast[i] = 0.0f;
  797. int iCurrent = 0;
  798. double g_dCurTime = 0;
  799. double g_dLastTime = 0;
  800. while( uMsg.message != WM_QUIT )
  801. {
  802. if( PeekMessage( &uMsg, NULL, 0, 0, PM_REMOVE ) )
  803. {
  804. TranslateMessage( &uMsg );
  805. DispatchMessage( &uMsg );
  806. if (WM_CHAR == uMsg.message)
  807. {
  808. switch ((char)uMsg.wParam)
  809. {
  810. case 'M':
  811. case 'm':
  812. CheckDlgButton(g_hDlg,IDC_TOGGLEMS,
  813. IsDlgButtonChecked(g_hDlg,IDC_TOGGLEMS) == BST_CHECKED
  814. ? BST_UNCHECKED : BST_CHECKED);
  815. g_sOptions.bMultiSample = !g_sOptions.bMultiSample;
  816. DeleteAssetData();
  817. ShutdownDevice();
  818. if (0 == CreateDevice())
  819. {
  820. CLogDisplay::Instance().AddEntry(
  821. "[ERROR] Failed to toggle MultiSampling mode");
  822. g_sOptions.bMultiSample = !g_sOptions.bMultiSample;
  823. CreateDevice();
  824. }
  825. CreateAssetData();
  826. if (g_sOptions.bMultiSample)
  827. {
  828. CLogDisplay::Instance().AddEntry(
  829. "[OK] Changed MultiSampling mode to the maximum value for this device");
  830. }
  831. else
  832. {
  833. CLogDisplay::Instance().AddEntry(
  834. "[OK] MultiSampling has been disabled");
  835. }
  836. break;
  837. case 'L':
  838. case 'l':
  839. CheckDlgButton(g_hDlg,IDC_3LIGHTS,
  840. IsDlgButtonChecked(g_hDlg,IDC_3LIGHTS) == BST_CHECKED
  841. ? BST_UNCHECKED : BST_CHECKED);
  842. g_sOptions.b3Lights = !g_sOptions.b3Lights;
  843. break;
  844. case 'P':
  845. case 'p':
  846. CheckDlgButton(g_hDlg,IDC_LOWQUALITY,
  847. IsDlgButtonChecked(g_hDlg,IDC_LOWQUALITY) == BST_CHECKED
  848. ? BST_UNCHECKED : BST_CHECKED);
  849. g_sOptions.bLowQuality = !g_sOptions.bLowQuality;
  850. break;
  851. case 'D':
  852. case 'd':
  853. CheckDlgButton(g_hDlg,IDC_TOGGLEMAT,
  854. IsDlgButtonChecked(g_hDlg,IDC_TOGGLEMAT) == BST_CHECKED
  855. ? BST_UNCHECKED : BST_CHECKED);
  856. g_sOptions.bRenderMats = !g_sOptions.bRenderMats;
  857. break;
  858. case 'N':
  859. case 'n':
  860. CheckDlgButton(g_hDlg,IDC_TOGGLENORMALS,
  861. IsDlgButtonChecked(g_hDlg,IDC_TOGGLENORMALS) == BST_CHECKED
  862. ? BST_UNCHECKED : BST_CHECKED);
  863. g_sOptions.bRenderNormals = !g_sOptions.bRenderNormals;
  864. break;
  865. case 'S':
  866. case 's':
  867. CheckDlgButton(g_hDlg,IDC_NOSPECULAR,
  868. IsDlgButtonChecked(g_hDlg,IDC_NOSPECULAR) == BST_CHECKED
  869. ? BST_UNCHECKED : BST_CHECKED);
  870. g_sOptions.bNoSpecular = !g_sOptions.bNoSpecular;
  871. UpdateSpecularMaterials();
  872. break;
  873. case 'A':
  874. case 'a':
  875. CheckDlgButton(g_hDlg,IDC_AUTOROTATE,
  876. IsDlgButtonChecked(g_hDlg,IDC_AUTOROTATE) == BST_CHECKED
  877. ? BST_UNCHECKED : BST_CHECKED);
  878. g_sOptions.bRotate = !g_sOptions.bRotate;
  879. break;
  880. case 'R':
  881. case 'r':
  882. CheckDlgButton(g_hDlg,IDC_LIGHTROTATE,
  883. IsDlgButtonChecked(g_hDlg,IDC_LIGHTROTATE) == BST_CHECKED
  884. ? BST_UNCHECKED : BST_CHECKED);
  885. g_sOptions.bLightRotate = !g_sOptions.bLightRotate;
  886. break;
  887. case 'Z':
  888. case 'z':
  889. CheckDlgButton(g_hDlg,IDC_ZOOM,
  890. IsDlgButtonChecked(g_hDlg,IDC_ZOOM) == BST_CHECKED
  891. ? BST_UNCHECKED : BST_CHECKED);
  892. g_bFPSView = !g_bFPSView;
  893. SetupFPSView();
  894. break;
  895. case 'W':
  896. case 'w':
  897. CheckDlgButton(g_hDlg,IDC_TOGGLEWIRE,
  898. IsDlgButtonChecked(g_hDlg,IDC_TOGGLEWIRE) == BST_CHECKED
  899. ? BST_UNCHECKED : BST_CHECKED);
  900. if (g_sOptions.eDrawMode == RenderOptions::NORMAL)
  901. g_sOptions.eDrawMode = RenderOptions::WIREFRAME;
  902. else g_sOptions.eDrawMode = RenderOptions::NORMAL;
  903. break;
  904. }
  905. }
  906. }
  907. // render the scene
  908. Render();
  909. g_dCurTime = timeGetTime();
  910. g_fElpasedTime = (float)((g_dCurTime - g_dLastTime) * 0.001);
  911. g_dLastTime = g_dCurTime;
  912. adLast[iCurrent++] = 1.0f / g_fElpasedTime;
  913. double dFPS = 0.0;
  914. for (int i = 0;i < 30;++i)
  915. dFPS += adLast[i];
  916. dFPS /= 30.0;
  917. if (30 == iCurrent)
  918. {
  919. iCurrent = 0;
  920. if (dFPS != g_fFPS)
  921. {
  922. g_fFPS = dFPS;
  923. char szOut[256];
  924. sprintf(szOut,"%i",(int)floorf((float)dFPS+0.5f));
  925. SetDlgItemText(g_hDlg,IDC_EFPS,szOut);
  926. }
  927. }
  928. }
  929. DeleteAsset();
  930. ShutdownDevice();
  931. ShutdownD3D();
  932. return 0;
  933. }