MessageProc.cpp 94 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651
  1. /*
  2. ---------------------------------------------------------------------------
  3. Open Asset Import Library (assimp)
  4. ---------------------------------------------------------------------------
  5. Copyright (c) 2006-2015, assimp team
  6. All rights reserved.
  7. Redistribution and use of this software in source and binary forms,
  8. with or without modification, are permitted provided that the following
  9. conditions are met:
  10. * Redistributions of source code must retain the above
  11. copyright notice, this list of conditions and the
  12. following disclaimer.
  13. * Redistributions in binary form must reproduce the above
  14. copyright notice, this list of conditions and the
  15. following disclaimer in the documentation and/or other
  16. materials provided with the distribution.
  17. * Neither the name of the assimp team, nor the names of its
  18. contributors may be used to endorse or promote products
  19. derived from this software without specific prior
  20. written permission of the assimp team.
  21. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  24. A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  25. OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  26. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  27. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  28. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  29. THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  31. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. ---------------------------------------------------------------------------
  33. */
  34. #include "assimp_view.h"
  35. #include <assimp/Exporter.hpp>
  36. #include <algorithm>
  37. #include <windowsx.h>
  38. #include <commdlg.h>
  39. #ifdef __MINGW32__
  40. #include <mmsystem.h>
  41. #else
  42. #include <timeapi.h>
  43. #endif
  44. namespace AssimpView {
  45. using namespace Assimp;
  46. // Static array to keep custom color values
  47. COLORREF g_aclCustomColors[16] = {0};
  48. // Global registry key
  49. HKEY g_hRegistry = NULL;
  50. // list of previous files (always 5)
  51. std::vector<std::string> g_aPreviousFiles;
  52. // history menu item
  53. HMENU g_hHistoryMenu = NULL;
  54. float g_fACMR = 3.0f;
  55. #define AI_VIEW_NUM_RECENT_FILES 0x8
  56. #define AI_VIEW_RECENT_FILE_ID(_n_) (5678 + _n_)
  57. #define AI_VIEW_EXPORT_FMT_BASE 7912
  58. #define AI_VIEW_EXPORT_FMT_ID(_n_) (AI_VIEW_EXPORT_FMT_BASE + _n_)
  59. void UpdateHistory();
  60. void SaveHistory();
  61. //-------------------------------------------------------------------------------
  62. // Setup file associations for all formats supported by the library
  63. //
  64. // File associations are registered in HKCU\Software\Classes. They might
  65. // be overwritten by global file associations.
  66. //-------------------------------------------------------------------------------
  67. void MakeFileAssociations()
  68. {
  69. char szTemp2[MAX_PATH];
  70. char szTemp[MAX_PATH + 10];
  71. GetModuleFileName(NULL,szTemp2,MAX_PATH);
  72. sprintf(szTemp,"%s %%1",szTemp2);
  73. HKEY g_hRegistry;
  74. aiString list, tmp;
  75. aiGetExtensionList(&list);
  76. tmp = list;
  77. const char* sz = strtok(list.data,";");
  78. do
  79. {
  80. char buf[256];
  81. ai_assert(sz[0] == '*');
  82. sprintf(buf,"Software\\Classes\\%s",sz+1);
  83. RegCreateKeyEx(HKEY_CURRENT_USER,buf,0,NULL,0,KEY_ALL_ACCESS, NULL, &g_hRegistry,NULL);
  84. RegSetValueEx(g_hRegistry,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1);
  85. RegCloseKey(g_hRegistry);
  86. }
  87. while ((sz = strtok(NULL,";")));
  88. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\ASSIMPVIEW_CLASS",0,NULL,0,KEY_ALL_ACCESS, NULL, &g_hRegistry,NULL);
  89. RegCloseKey(g_hRegistry);
  90. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\ASSIMPVIEW_CLASS\\shell\\open\\command",0,NULL,0,KEY_ALL_ACCESS, NULL, &g_hRegistry,NULL);
  91. RegSetValueEx(g_hRegistry,"",0,REG_SZ,(const BYTE*)szTemp,(DWORD)strlen(szTemp)+1);
  92. RegCloseKey(g_hRegistry);
  93. CLogDisplay::Instance().AddEntry("[OK] File assocations have been registered",
  94. D3DCOLOR_ARGB(0xFF,0,0xFF,0));
  95. CLogDisplay::Instance().AddEntry(tmp.data,D3DCOLOR_ARGB(0xFF,0,0xFF,0));
  96. }
  97. //-------------------------------------------------------------------------------
  98. // Handle command line parameters
  99. //
  100. // The function loads an asset specified on the command line as first argument
  101. // Other command line parameters are not handled
  102. //-------------------------------------------------------------------------------
  103. void HandleCommandLine(char* p_szCommand)
  104. {
  105. char* sz = p_szCommand;
  106. //bool bQuak = false;
  107. if (strlen(sz) < 2)return;
  108. if (*sz == '\"') {
  109. char* sz2 = strrchr(sz,'\"');
  110. if (sz2)*sz2 = 0;
  111. sz++; // skip the starting quote
  112. }
  113. strcpy( g_szFileName, sz );
  114. LoadAsset();
  115. // update the history
  116. UpdateHistory();
  117. // Save the list of previous files to the registry
  118. SaveHistory();
  119. }
  120. //-------------------------------------------------------------------------------
  121. // Load the light colors from the registry
  122. //-------------------------------------------------------------------------------
  123. void LoadLightColors()
  124. {
  125. DWORD dwTemp = 4;
  126. RegQueryValueEx(g_hRegistry,"LightColor0",NULL,NULL, (BYTE*)&g_avLightColors[0],&dwTemp);
  127. RegQueryValueEx(g_hRegistry,"LightColor1",NULL,NULL, (BYTE*)&g_avLightColors[1],&dwTemp);
  128. RegQueryValueEx(g_hRegistry,"LightColor2",NULL,NULL, (BYTE*)&g_avLightColors[2],&dwTemp);
  129. }
  130. //-------------------------------------------------------------------------------
  131. // Save the light colors to the registry
  132. //-------------------------------------------------------------------------------
  133. void SaveLightColors()
  134. {
  135. RegSetValueExA(g_hRegistry,"LightColor0",0,REG_DWORD,(const BYTE*)&g_avLightColors[0],4);
  136. RegSetValueExA(g_hRegistry,"LightColor1",0,REG_DWORD,(const BYTE*)&g_avLightColors[1],4);
  137. RegSetValueExA(g_hRegistry,"LightColor2",0,REG_DWORD,(const BYTE*)&g_avLightColors[2],4);
  138. }
  139. //-------------------------------------------------------------------------------
  140. // Save the checker pattern colors to the registry
  141. //-------------------------------------------------------------------------------
  142. void SaveCheckerPatternColors()
  143. {
  144. // we have it as float4. save it as binary value --.
  145. RegSetValueExA(g_hRegistry,"CheckerPattern0",0,REG_BINARY,
  146. (const BYTE*)CDisplay::Instance().GetFirstCheckerColor(),
  147. sizeof(D3DXVECTOR3));
  148. RegSetValueExA(g_hRegistry,"CheckerPattern1",0,REG_BINARY,
  149. (const BYTE*)CDisplay::Instance().GetSecondCheckerColor(),
  150. sizeof(D3DXVECTOR3));
  151. }
  152. //-------------------------------------------------------------------------------
  153. // Load the checker pattern colors from the registry
  154. //-------------------------------------------------------------------------------
  155. void LoadCheckerPatternColors()
  156. {
  157. DWORD dwTemp = sizeof(D3DXVECTOR3);
  158. RegQueryValueEx(g_hRegistry,"CheckerPattern0",NULL,NULL,
  159. (BYTE*) /* jep, this is evil */ CDisplay::Instance().GetFirstCheckerColor(),&dwTemp);
  160. RegQueryValueEx(g_hRegistry,"CheckerPattern1",NULL,NULL,
  161. (BYTE*) /* jep, this is evil */ CDisplay::Instance().GetSecondCheckerColor(),&dwTemp);
  162. }
  163. //-------------------------------------------------------------------------------
  164. // Changed pp setup
  165. //-------------------------------------------------------------------------------
  166. void UpdatePPSettings()
  167. {
  168. DWORD dwValue = ppsteps;
  169. RegSetValueExA(g_hRegistry,"PostProcessing",0,REG_DWORD,(const BYTE*)&dwValue,4);
  170. UpdateWindow(g_hDlg);
  171. }
  172. //-------------------------------------------------------------------------------
  173. // Toggle the "Display Normals" state
  174. //-------------------------------------------------------------------------------
  175. void ToggleNormals()
  176. {
  177. g_sOptions.bRenderNormals = !g_sOptions.bRenderNormals;
  178. // store this in the registry, too
  179. DWORD dwValue = 0;
  180. if (g_sOptions.bRenderNormals)dwValue = 1;
  181. RegSetValueExA(g_hRegistry,"RenderNormals",0,REG_DWORD,(const BYTE*)&dwValue,4);
  182. }
  183. //-------------------------------------------------------------------------------
  184. // Toggle the "AutoRotate" state
  185. //-------------------------------------------------------------------------------
  186. void ToggleAutoRotate()
  187. {
  188. g_sOptions.bRotate = !g_sOptions.bRotate;
  189. // store this in the registry, too
  190. DWORD dwValue = 0;
  191. if (g_sOptions.bRotate)dwValue = 1;
  192. RegSetValueExA(g_hRegistry,"AutoRotate",0,REG_DWORD,(const BYTE*)&dwValue,4);
  193. UpdateWindow(g_hDlg);
  194. }
  195. //-------------------------------------------------------------------------------
  196. // Toggle the "FPS" state
  197. //-------------------------------------------------------------------------------
  198. void ToggleFPSView()
  199. {
  200. g_bFPSView = !g_bFPSView;
  201. SetupFPSView();
  202. // store this in the registry, too
  203. DWORD dwValue = 0;
  204. if (g_bFPSView)dwValue = 1;
  205. RegSetValueExA(g_hRegistry,"FPSView",0,REG_DWORD,(const BYTE*)&dwValue,4);
  206. }
  207. //-------------------------------------------------------------------------------
  208. // Toggle the "2 Light sources" state
  209. //-------------------------------------------------------------------------------
  210. void ToggleMultipleLights()
  211. {
  212. g_sOptions.b3Lights = !g_sOptions.b3Lights;
  213. // store this in the registry, too
  214. DWORD dwValue = 0;
  215. if (g_sOptions.b3Lights)dwValue = 1;
  216. RegSetValueExA(g_hRegistry,"MultipleLights",0,REG_DWORD,(const BYTE*)&dwValue,4);
  217. }
  218. //-------------------------------------------------------------------------------
  219. // Toggle the "LightRotate" state
  220. //-------------------------------------------------------------------------------
  221. void ToggleLightRotate()
  222. {
  223. g_sOptions.bLightRotate = !g_sOptions.bLightRotate;
  224. // store this in the registry, too
  225. DWORD dwValue = 0;
  226. if (g_sOptions.bLightRotate)dwValue = 1;
  227. RegSetValueExA(g_hRegistry,"LightRotate",0,REG_DWORD,(const BYTE*)&dwValue,4);
  228. }
  229. //-------------------------------------------------------------------------------
  230. // Toggle the "NoTransparency" state
  231. //-------------------------------------------------------------------------------
  232. void ToggleTransparency()
  233. {
  234. g_sOptions.bNoAlphaBlending = !g_sOptions.bNoAlphaBlending;
  235. // store this in the registry, too
  236. DWORD dwValue = 0;
  237. if (g_sOptions.bNoAlphaBlending)dwValue = 1;
  238. RegSetValueExA(g_hRegistry,"NoTransparency",0,REG_DWORD,(const BYTE*)&dwValue,4);
  239. }
  240. //-------------------------------------------------------------------------------
  241. // Toggle the "LowQuality" state
  242. //-------------------------------------------------------------------------------
  243. void ToggleLowQuality()
  244. {
  245. g_sOptions.bLowQuality = !g_sOptions.bLowQuality;
  246. // store this in the registry, too
  247. DWORD dwValue = 0;
  248. if (g_sOptions.bLowQuality)dwValue = 1;
  249. RegSetValueExA(g_hRegistry,"LowQuality",0,REG_DWORD,(const BYTE*)&dwValue,4);
  250. }
  251. //-------------------------------------------------------------------------------
  252. // Toggle the "Specular" state
  253. //-------------------------------------------------------------------------------
  254. void ToggleSpecular()
  255. {
  256. g_sOptions.bNoSpecular = !g_sOptions.bNoSpecular;
  257. // store this in the registry, too
  258. DWORD dwValue = 0;
  259. if (g_sOptions.bNoSpecular)dwValue = 1;
  260. RegSetValueExA(g_hRegistry,"NoSpecular",0,REG_DWORD,(const BYTE*)&dwValue,4);
  261. // update all specular materials
  262. CMaterialManager::Instance().UpdateSpecularMaterials();
  263. }
  264. //-------------------------------------------------------------------------------
  265. // Toggle the "RenderMats" state
  266. //-------------------------------------------------------------------------------
  267. void ToggleMats()
  268. {
  269. g_sOptions.bRenderMats = !g_sOptions.bRenderMats;
  270. // store this in the registry, too
  271. DWORD dwValue = 0;
  272. if (g_sOptions.bRenderMats)dwValue = 1;
  273. RegSetValueExA(g_hRegistry,"RenderMats",0,REG_DWORD,(const BYTE*)&dwValue,4);
  274. // update all specular materials
  275. CMaterialManager::Instance().UpdateSpecularMaterials();
  276. }
  277. //-------------------------------------------------------------------------------
  278. // Toggle the "Culling" state
  279. //-------------------------------------------------------------------------------
  280. void ToggleCulling()
  281. {
  282. g_sOptions.bCulling = !g_sOptions.bCulling;
  283. // store this in the registry, too
  284. DWORD dwValue = 0;
  285. if (g_sOptions.bCulling)dwValue = 1;
  286. RegSetValueExA(g_hRegistry,"Culling",0,REG_DWORD,(const BYTE*)&dwValue,4);
  287. }
  288. //-------------------------------------------------------------------------------
  289. // Toggle the "Skeleton" state
  290. //-------------------------------------------------------------------------------
  291. void ToggleSkeleton()
  292. {
  293. g_sOptions.bSkeleton = !g_sOptions.bSkeleton;
  294. // store this in the registry, too
  295. DWORD dwValue = 0;
  296. if (g_sOptions.bCulling)dwValue = 1;
  297. RegSetValueExA(g_hRegistry,"Skeleton",0,REG_DWORD,(const BYTE*)&dwValue,4);
  298. }
  299. //-------------------------------------------------------------------------------
  300. // Toggle the "WireFrame" state
  301. //-------------------------------------------------------------------------------
  302. void ToggleWireFrame()
  303. {
  304. if (g_sOptions.eDrawMode == RenderOptions::WIREFRAME)
  305. g_sOptions.eDrawMode = RenderOptions::NORMAL;
  306. else g_sOptions.eDrawMode = RenderOptions::WIREFRAME;
  307. // store this in the registry, too
  308. DWORD dwValue = 0;
  309. if (RenderOptions::WIREFRAME == g_sOptions.eDrawMode)dwValue = 1;
  310. RegSetValueExA(g_hRegistry,"Wireframe",0,REG_DWORD,(const BYTE*)&dwValue,4);
  311. }
  312. //-------------------------------------------------------------------------------
  313. // Toggle the "MultiSample" state
  314. //-------------------------------------------------------------------------------
  315. void ToggleMS()
  316. {
  317. g_sOptions.bMultiSample = !g_sOptions.bMultiSample;
  318. DeleteAssetData();
  319. ShutdownDevice();
  320. if (0 == CreateDevice())
  321. {
  322. CLogDisplay::Instance().AddEntry(
  323. "[ERROR] Failed to toggle MultiSampling mode");
  324. g_sOptions.bMultiSample = !g_sOptions.bMultiSample;
  325. CreateDevice();
  326. }
  327. CreateAssetData();
  328. if (g_sOptions.bMultiSample)
  329. {
  330. CLogDisplay::Instance().AddEntry(
  331. "[OK] Changed MultiSampling mode to the maximum value for this device");
  332. }
  333. else
  334. {
  335. CLogDisplay::Instance().AddEntry(
  336. "[OK] MultiSampling has been disabled");
  337. }
  338. // store this in the registry, too
  339. DWORD dwValue = 0;
  340. if (g_sOptions.bMultiSample)dwValue = 1;
  341. RegSetValueExA(g_hRegistry,"MultiSampling",0,REG_DWORD,(const BYTE*)&dwValue,4);
  342. }
  343. //-------------------------------------------------------------------------------
  344. // Expand or collapse the UI
  345. //-------------------------------------------------------------------------------
  346. void ToggleUIState()
  347. {
  348. // adjust the size
  349. RECT sRect;
  350. GetWindowRect(g_hDlg,&sRect);
  351. sRect.right -= sRect.left;
  352. sRect.bottom -= sRect.top;
  353. RECT sRect2;
  354. GetWindowRect(GetDlgItem ( g_hDlg, IDC_BLUBB ),&sRect2);
  355. sRect2.left -= sRect.left;
  356. sRect2.top -= sRect.top;
  357. DWORD dwValue;
  358. if (BST_UNCHECKED == IsDlgButtonChecked(g_hDlg,IDC_BLUBB))
  359. {
  360. SetWindowPos(g_hDlg,NULL,0,0,sRect.right-214,sRect.bottom,
  361. SWP_NOMOVE | SWP_NOZORDER);
  362. dwValue = 0;
  363. SetWindowText(GetDlgItem(g_hDlg,IDC_BLUBB),">>");
  364. RegSetValueExA(g_hRegistry,"LastUIState",0,REG_DWORD,(const BYTE*)&dwValue,4);
  365. }
  366. else
  367. {
  368. SetWindowPos(g_hDlg,NULL,0,0,sRect.right+214,sRect.bottom,
  369. SWP_NOMOVE | SWP_NOZORDER);
  370. dwValue = 1;
  371. SetWindowText(GetDlgItem(g_hDlg,IDC_BLUBB),"<<");
  372. RegSetValueExA(g_hRegistry,"LastUIState",0,REG_DWORD,(const BYTE*)&dwValue,4);
  373. }
  374. UpdateWindow(g_hDlg);
  375. return;
  376. }
  377. //-------------------------------------------------------------------------------
  378. // Load the background texture for the cviewer
  379. //-------------------------------------------------------------------------------
  380. void LoadBGTexture()
  381. {
  382. char szFileName[MAX_PATH];
  383. DWORD dwTemp = MAX_PATH;
  384. if(ERROR_SUCCESS != RegQueryValueEx(g_hRegistry,"TextureSrc",NULL,NULL,
  385. (BYTE*)szFileName,&dwTemp))
  386. {
  387. // Key was not found. Use C:
  388. strcpy(szFileName,"");
  389. }
  390. else
  391. {
  392. // need to remove the file name
  393. char* sz = strrchr(szFileName,'\\');
  394. if (!sz)
  395. sz = strrchr(szFileName,'/');
  396. if (sz)
  397. *sz = 0;
  398. }
  399. OPENFILENAME sFilename1 = {
  400. sizeof(OPENFILENAME),
  401. g_hDlg,GetModuleHandle(NULL),
  402. "Textures\0*.png;*.dds;*.tga;*.bmp;*.tif;*.ppm;*.ppx;*.jpg;*.jpeg;*.exr\0*.*\0",
  403. NULL, 0, 1,
  404. szFileName, MAX_PATH, NULL, 0, NULL,
  405. "Open texture as background",
  406. OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_NOCHANGEDIR,
  407. 0, 1, ".jpg", 0, NULL, NULL
  408. };
  409. if(GetOpenFileName(&sFilename1) == 0) return;
  410. // Now store the file in the registry
  411. RegSetValueExA(g_hRegistry,"TextureSrc",0,REG_SZ,(const BYTE*)szFileName,MAX_PATH);
  412. RegSetValueExA(g_hRegistry,"LastTextureSrc",0,REG_SZ,(const BYTE*)szFileName,MAX_PATH);
  413. RegSetValueExA(g_hRegistry,"LastSkyBoxSrc",0,REG_SZ,(const BYTE*)"",MAX_PATH);
  414. CBackgroundPainter::Instance().SetTextureBG(szFileName);
  415. return;
  416. }
  417. //-------------------------------------------------------------------------------
  418. // Reset the background color to a smart and nice grey
  419. //-------------------------------------------------------------------------------
  420. void ClearBG()
  421. {
  422. D3DCOLOR clrColor = D3DCOLOR_ARGB(0xFF,100,100,100);
  423. CBackgroundPainter::Instance().SetColor(clrColor);
  424. RegSetValueExA(g_hRegistry,"LastSkyBoxSrc",0,REG_SZ,(const BYTE*)"",MAX_PATH);
  425. RegSetValueExA(g_hRegistry,"LastTextureSrc",0,REG_SZ,(const BYTE*)"",MAX_PATH);
  426. RegSetValueExA(g_hRegistry,"Color",0,REG_DWORD,(const BYTE*)&clrColor,4);
  427. return;
  428. }
  429. //-------------------------------------------------------------------------------
  430. // Let the user choose a color in a windows standard color dialog
  431. //-------------------------------------------------------------------------------
  432. void DisplayColorDialog(D3DCOLOR* pclrResult)
  433. {
  434. CHOOSECOLOR clr;
  435. clr.lStructSize = sizeof(CHOOSECOLOR);
  436. clr.hwndOwner = g_hDlg;
  437. clr.Flags = CC_RGBINIT | CC_FULLOPEN;
  438. clr.rgbResult = RGB((*pclrResult >> 16) & 0xff,(*pclrResult >> 8) & 0xff,*pclrResult & 0xff);
  439. clr.lpCustColors = g_aclCustomColors;
  440. clr.lpfnHook = NULL;
  441. clr.lpTemplateName = NULL;
  442. clr.lCustData = 0;
  443. ChooseColor(&clr);
  444. *pclrResult = D3DCOLOR_ARGB(0xFF,
  445. GetRValue(clr.rgbResult),
  446. GetGValue(clr.rgbResult),
  447. GetBValue(clr.rgbResult));
  448. return;
  449. }
  450. //-------------------------------------------------------------------------------
  451. // Let the user choose a color in a windows standard color dialog
  452. //-------------------------------------------------------------------------------
  453. void DisplayColorDialog(D3DXVECTOR4* pclrResult)
  454. {
  455. CHOOSECOLOR clr;
  456. clr.lStructSize = sizeof(CHOOSECOLOR);
  457. clr.hwndOwner = g_hDlg;
  458. clr.Flags = CC_RGBINIT | CC_FULLOPEN;
  459. clr.rgbResult = RGB(clamp<unsigned char>(pclrResult->x * 255.0f),
  460. clamp<unsigned char>(pclrResult->y * 255.0f),
  461. clamp<unsigned char>(pclrResult->z * 255.0f));
  462. clr.lpCustColors = g_aclCustomColors;
  463. clr.lpfnHook = NULL;
  464. clr.lpTemplateName = NULL;
  465. clr.lCustData = 0;
  466. ChooseColor(&clr);
  467. pclrResult->x = GetRValue(clr.rgbResult) / 255.0f;
  468. pclrResult->y = GetGValue(clr.rgbResult) / 255.0f;
  469. pclrResult->z = GetBValue(clr.rgbResult) / 255.0f;
  470. return;
  471. }
  472. //-------------------------------------------------------------------------------
  473. // Let the user choose the baclground color for the viewer
  474. //-------------------------------------------------------------------------------
  475. void ChooseBGColor()
  476. {
  477. RegSetValueExA(g_hRegistry,"LastSkyBoxSrc",0,REG_SZ,(const BYTE*)"",MAX_PATH);
  478. RegSetValueExA(g_hRegistry,"LastTextureSrc",0,REG_SZ,(const BYTE*)"",MAX_PATH);
  479. D3DCOLOR clrColor;
  480. DisplayColorDialog(&clrColor);
  481. CBackgroundPainter::Instance().SetColor(clrColor);
  482. RegSetValueExA(g_hRegistry,"Color",0,REG_DWORD,(const BYTE*)&clrColor,4);
  483. return;
  484. }
  485. //-------------------------------------------------------------------------------
  486. // Display the OpenFile dialog and let the user choose a new slybox as bg
  487. //-------------------------------------------------------------------------------
  488. void LoadSkybox()
  489. {
  490. char szFileName[MAX_PATH];
  491. DWORD dwTemp = MAX_PATH;
  492. if(ERROR_SUCCESS != RegQueryValueEx(g_hRegistry,"SkyBoxSrc",NULL,NULL,
  493. (BYTE*)szFileName,&dwTemp))
  494. {
  495. // Key was not found. Use C:
  496. strcpy(szFileName,"");
  497. }
  498. else
  499. {
  500. // need to remove the file name
  501. char* sz = strrchr(szFileName,'\\');
  502. if (!sz)
  503. sz = strrchr(szFileName,'/');
  504. if (sz)
  505. *sz = 0;
  506. }
  507. OPENFILENAME sFilename1 = {
  508. sizeof(OPENFILENAME),
  509. g_hDlg,GetModuleHandle(NULL),
  510. "Skyboxes\0*.dds\0*.*\0", NULL, 0, 1,
  511. szFileName, MAX_PATH, NULL, 0, NULL,
  512. "Open skybox as background",
  513. OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_NOCHANGEDIR,
  514. 0, 1, ".dds", 0, NULL, NULL
  515. };
  516. if(GetOpenFileName(&sFilename1) == 0) return;
  517. // Now store the file in the registry
  518. RegSetValueExA(g_hRegistry,"SkyBoxSrc",0,REG_SZ,(const BYTE*)szFileName,MAX_PATH);
  519. RegSetValueExA(g_hRegistry,"LastSkyBoxSrc",0,REG_SZ,(const BYTE*)szFileName,MAX_PATH);
  520. RegSetValueExA(g_hRegistry,"LastTextureSrc",0,REG_SZ,(const BYTE*)"",MAX_PATH);
  521. CBackgroundPainter::Instance().SetCubeMapBG(szFileName);
  522. return;
  523. }
  524. //-------------------------------------------------------------------------------
  525. // Sace a screenshot to an user-defined file
  526. //-------------------------------------------------------------------------------
  527. void SaveScreenshot()
  528. {
  529. char szFileName[MAX_PATH];
  530. DWORD dwTemp = MAX_PATH;
  531. if(ERROR_SUCCESS != RegQueryValueEx(g_hRegistry,"ScreenShot",NULL,NULL,
  532. (BYTE*)szFileName,&dwTemp))
  533. {
  534. // Key was not found. Use C:
  535. strcpy(szFileName,"");
  536. }
  537. else
  538. {
  539. // need to remove the file name
  540. char* sz = strrchr(szFileName,'\\');
  541. if (!sz)
  542. sz = strrchr(szFileName,'/');
  543. if (sz)
  544. *sz = 0;
  545. }
  546. OPENFILENAME sFilename1 = {
  547. sizeof(OPENFILENAME),
  548. g_hDlg,GetModuleHandle(NULL),
  549. "PNG Images\0*.png", NULL, 0, 1,
  550. szFileName, MAX_PATH, NULL, 0, NULL,
  551. "Save Screenshot to file",
  552. OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_NOCHANGEDIR,
  553. 0, 1, ".png", 0, NULL, NULL
  554. };
  555. if(GetSaveFileName(&sFilename1) == 0) return;
  556. // Now store the file in the registry
  557. RegSetValueExA(g_hRegistry,"ScreenShot",0,REG_SZ,(const BYTE*)szFileName,MAX_PATH);
  558. IDirect3DSurface9* pi = NULL;
  559. g_piDevice->GetRenderTarget(0,&pi);
  560. if(!pi || FAILED(D3DXSaveSurfaceToFile(szFileName,D3DXIFF_PNG,pi,NULL,NULL)))
  561. {
  562. CLogDisplay::Instance().AddEntry("[ERROR] Unable to save screenshot",
  563. D3DCOLOR_ARGB(0xFF,0xFF,0,0));
  564. }
  565. else
  566. {
  567. CLogDisplay::Instance().AddEntry("[INFO] The screenshot has been saved",
  568. D3DCOLOR_ARGB(0xFF,0xFF,0xFF,0));
  569. }
  570. if(pi)pi->Release();
  571. return;
  572. }
  573. //-------------------------------------------------------------------------------
  574. // Get the amount of memory required for textures
  575. //-------------------------------------------------------------------------------
  576. void AddTextureMem(IDirect3DTexture9* pcTex, unsigned int& out)
  577. {
  578. if (!pcTex)return;
  579. D3DSURFACE_DESC sDesc;
  580. pcTex->GetLevelDesc(0,&sDesc);
  581. out += (sDesc.Width * sDesc.Height) << 2;
  582. return;
  583. }
  584. //-------------------------------------------------------------------------------
  585. // Display memory statistics
  586. //-------------------------------------------------------------------------------
  587. void DisplayMemoryConsumption()
  588. {
  589. // first get the memory consumption for the aiScene
  590. if (! g_pcAsset ||!g_pcAsset->pcScene)
  591. {
  592. MessageBox(g_hDlg,"No asset is loaded. Can you guess how much memory I need to store nothing?",
  593. "Memory consumption",MB_OK);
  594. return;
  595. }
  596. unsigned int iScene = sizeof(aiScene);
  597. for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
  598. {
  599. iScene += sizeof(aiMesh);
  600. if (g_pcAsset->pcScene->mMeshes[i]->HasPositions())
  601. iScene += sizeof(aiVector3D) * g_pcAsset->pcScene->mMeshes[i]->mNumVertices;
  602. if (g_pcAsset->pcScene->mMeshes[i]->HasNormals())
  603. iScene += sizeof(aiVector3D) * g_pcAsset->pcScene->mMeshes[i]->mNumVertices;
  604. if (g_pcAsset->pcScene->mMeshes[i]->HasTangentsAndBitangents())
  605. iScene += sizeof(aiVector3D) * g_pcAsset->pcScene->mMeshes[i]->mNumVertices * 2;
  606. for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS;++a)
  607. {
  608. if (g_pcAsset->pcScene->mMeshes[i]->HasVertexColors(a))
  609. iScene += sizeof(aiColor4D) * g_pcAsset->pcScene->mMeshes[i]->mNumVertices;
  610. else break;
  611. }
  612. for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS;++a)
  613. {
  614. if (g_pcAsset->pcScene->mMeshes[i]->HasTextureCoords(a))
  615. iScene += sizeof(aiVector3D) * g_pcAsset->pcScene->mMeshes[i]->mNumVertices;
  616. else break;
  617. }
  618. if (g_pcAsset->pcScene->mMeshes[i]->HasBones())
  619. {
  620. for (unsigned int p = 0; p < g_pcAsset->pcScene->mMeshes[i]->mNumBones;++p)
  621. {
  622. iScene += sizeof(aiBone);
  623. iScene += g_pcAsset->pcScene->mMeshes[i]->mBones[p]->mNumWeights * sizeof(aiVertexWeight);
  624. }
  625. }
  626. iScene += (sizeof(aiFace) + 3 * sizeof(unsigned int))*g_pcAsset->pcScene->mMeshes[i]->mNumFaces;
  627. }
  628. // add all embedded textures
  629. for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumTextures;++i)
  630. {
  631. const aiTexture* pc = g_pcAsset->pcScene->mTextures[i];
  632. if (0 != pc->mHeight)
  633. {
  634. iScene += 4 * pc->mHeight * pc->mWidth;
  635. }
  636. else iScene += pc->mWidth;
  637. }
  638. // add 30k for each material ... a string has 4k for example
  639. iScene += g_pcAsset->pcScene->mNumMaterials * 30 * 1024;
  640. // now get the memory consumption required by D3D, first all textures
  641. unsigned int iTexture = 0;
  642. for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
  643. {
  644. AssetHelper::MeshHelper* pc = g_pcAsset->apcMeshes[i];
  645. AddTextureMem(pc->piDiffuseTexture,iTexture);
  646. AddTextureMem(pc->piSpecularTexture,iTexture);
  647. AddTextureMem(pc->piAmbientTexture,iTexture);
  648. AddTextureMem(pc->piEmissiveTexture,iTexture);
  649. AddTextureMem(pc->piOpacityTexture,iTexture);
  650. AddTextureMem(pc->piNormalTexture,iTexture);
  651. AddTextureMem(pc->piShininessTexture,iTexture);
  652. }
  653. unsigned int iVRAM = iTexture;
  654. // now get the memory consumption of all vertex/index buffers
  655. unsigned int iVB = 0;
  656. unsigned int iIB = 0;
  657. for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
  658. {
  659. AssetHelper:: MeshHelper* pc = g_pcAsset->apcMeshes[i];
  660. union{
  661. D3DVERTEXBUFFER_DESC sDesc;
  662. D3DINDEXBUFFER_DESC sDesc2;
  663. };
  664. if (pc->piVB)
  665. {
  666. pc->piVB->GetDesc(&sDesc);
  667. iVB += sDesc.Size;
  668. }
  669. if (pc->piVBNormals)
  670. {
  671. pc->piVBNormals->GetDesc(&sDesc);
  672. iVB += sDesc.Size;
  673. }
  674. if (pc->piIB)
  675. {
  676. pc->piIB->GetDesc(&sDesc2);
  677. iIB += sDesc2.Size;
  678. }
  679. }
  680. iVRAM += iVB + iIB;
  681. // add the memory for the back buffer and depth stencil buffer
  682. RECT sRect;
  683. GetWindowRect(GetDlgItem(g_hDlg,IDC_RT),&sRect);
  684. sRect.bottom -= sRect.top;
  685. sRect.right -= sRect.left;
  686. iVRAM += sRect.bottom * sRect.right * 8;
  687. char szOut[2048];
  688. sprintf(szOut,
  689. "(1 KiB = 1024 bytes)\n\n"
  690. "ASSIMP Import Data: \t%i KiB\n"
  691. "Texture data:\t\t%i KiB\n"
  692. "Vertex buffers:\t\t%i KiB\n"
  693. "Index buffers:\t\t%i KiB\n"
  694. "Video Memory:\t\t%i KiB\n\n"
  695. "Total: \t\t\t%i KiB",
  696. iScene / 1024,iTexture / 1024,iVB / 1024,iIB / 1024,iVRAM / 1024,
  697. (iScene + iTexture + iVB + iIB + iVRAM) / 1024);
  698. MessageBox(g_hDlg,szOut,"Memory consumption",MB_OK);
  699. return;
  700. }
  701. //-------------------------------------------------------------------------------
  702. // Save the list of recent files to the registry
  703. //-------------------------------------------------------------------------------
  704. void SaveHistory()
  705. {
  706. for (unsigned int i = 0; i < AI_VIEW_NUM_RECENT_FILES;++i)
  707. {
  708. char szName[66];
  709. sprintf(szName,"Recent%i",i+1);
  710. RegSetValueEx(g_hRegistry,szName,0,REG_SZ,
  711. (const BYTE*)g_aPreviousFiles[i].c_str(),(DWORD)g_aPreviousFiles[i].length());
  712. }
  713. return;
  714. }
  715. //-------------------------------------------------------------------------------
  716. // Recover the file history
  717. //-------------------------------------------------------------------------------
  718. void LoadHistory()
  719. {
  720. g_aPreviousFiles.resize(AI_VIEW_NUM_RECENT_FILES);
  721. char szFileName[MAX_PATH];
  722. for (unsigned int i = 0; i < AI_VIEW_NUM_RECENT_FILES;++i)
  723. {
  724. char szName[66];
  725. sprintf(szName,"Recent%i",i+1);
  726. DWORD dwTemp = MAX_PATH;
  727. szFileName[0] ='\0';
  728. if(ERROR_SUCCESS == RegQueryValueEx(g_hRegistry,szName,NULL,NULL,
  729. (BYTE*)szFileName,&dwTemp))
  730. {
  731. g_aPreviousFiles[i] = std::string(szFileName);
  732. }
  733. }
  734. // add sub items for all recent files
  735. g_hHistoryMenu = CreateMenu();
  736. for (int i = AI_VIEW_NUM_RECENT_FILES-1; i >= 0;--i)
  737. {
  738. const char* szText = g_aPreviousFiles[i].c_str();
  739. UINT iFlags = 0;
  740. if ('\0' == *szText)
  741. {
  742. szText = "<empty>";
  743. iFlags = MF_GRAYED | MF_DISABLED;
  744. }
  745. AppendMenu(g_hHistoryMenu,MF_STRING | iFlags,AI_VIEW_RECENT_FILE_ID(i),szText);
  746. }
  747. ModifyMenu(GetMenu(g_hDlg),ID_VIEWER_RECENTFILES,MF_BYCOMMAND | MF_POPUP,
  748. (UINT_PTR)g_hHistoryMenu,"Recent files");
  749. return;
  750. }
  751. //-------------------------------------------------------------------------------
  752. // Clear the file history
  753. //-------------------------------------------------------------------------------
  754. void ClearHistory()
  755. {
  756. for(unsigned int i = 0; i < AI_VIEW_NUM_RECENT_FILES;++i)
  757. g_aPreviousFiles[i] = std::string("");
  758. for (int i = AI_VIEW_NUM_RECENT_FILES-1; i >= 0;--i)
  759. {
  760. ModifyMenu(g_hHistoryMenu,AI_VIEW_RECENT_FILE_ID(i),
  761. MF_STRING | MF_BYCOMMAND | MF_GRAYED | MF_DISABLED,AI_VIEW_RECENT_FILE_ID(i),"<empty>");
  762. }
  763. SaveHistory();
  764. }
  765. //-------------------------------------------------------------------------------
  766. // Update the file history
  767. //-------------------------------------------------------------------------------
  768. void UpdateHistory()
  769. {
  770. if(!g_hHistoryMenu)return;
  771. std::string sz = std::string(g_szFileName);
  772. if (g_aPreviousFiles[AI_VIEW_NUM_RECENT_FILES-1] == sz)return;
  773. // add the new asset to the list of recent files
  774. for (unsigned int i = 0; i < AI_VIEW_NUM_RECENT_FILES-1;++i)
  775. {
  776. g_aPreviousFiles[i] = g_aPreviousFiles[i+1];
  777. }
  778. g_aPreviousFiles[AI_VIEW_NUM_RECENT_FILES-1] = sz;
  779. for (int i = AI_VIEW_NUM_RECENT_FILES-1; i >= 0;--i)
  780. {
  781. const char* szText = g_aPreviousFiles[i].c_str();
  782. UINT iFlags = 0;
  783. if ('\0' == *szText)
  784. {
  785. szText = "<empty>";
  786. iFlags = MF_GRAYED | MF_DISABLED;
  787. }
  788. ModifyMenu(g_hHistoryMenu,AI_VIEW_RECENT_FILE_ID(i),
  789. MF_STRING | MF_BYCOMMAND | iFlags,AI_VIEW_RECENT_FILE_ID(i),szText);
  790. }
  791. return;
  792. }
  793. //-------------------------------------------------------------------------------
  794. // Open a new asset
  795. //-------------------------------------------------------------------------------
  796. void OpenAsset()
  797. {
  798. char szFileName[MAX_PATH];
  799. DWORD dwTemp = MAX_PATH;
  800. if(ERROR_SUCCESS != RegQueryValueEx(g_hRegistry,"CurrentApp",NULL,NULL,
  801. (BYTE*)szFileName,&dwTemp))
  802. {
  803. // Key was not found. Use C:
  804. strcpy(szFileName,"");
  805. }
  806. else
  807. {
  808. // need to remove the file name
  809. char* sz = strrchr(szFileName,'\\');
  810. if (!sz)
  811. sz = strrchr(szFileName,'/');
  812. if (sz)
  813. *sz = 0;
  814. }
  815. // get a list of all file extensions supported by ASSIMP
  816. aiString sz;
  817. aiGetExtensionList(&sz);
  818. char szList[MAXLEN + 100];
  819. strcpy(szList,"ASSIMP assets");
  820. char* szCur = szList + 14;
  821. strcpy(szCur,sz.data);
  822. szCur += sz.length+1;
  823. strcpy(szCur,"All files");
  824. szCur += 10;
  825. strcpy(szCur,"*.*");
  826. szCur[4] = 0;
  827. OPENFILENAME sFilename1 = {
  828. sizeof(OPENFILENAME),
  829. g_hDlg,GetModuleHandle(NULL), szList, NULL, 0, 1,
  830. szFileName, MAX_PATH, NULL, 0, NULL,
  831. "Import Asset into ASSIMP",
  832. OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_NOCHANGEDIR,
  833. 0, 1, ".x", 0, NULL, NULL
  834. };
  835. if(GetOpenFileName(&sFilename1) == 0) return;
  836. // Now store the file in the registry
  837. RegSetValueExA(g_hRegistry,"CurrentApp",0,REG_SZ,(const BYTE*)szFileName,MAX_PATH);
  838. if (0 != strcmp(g_szFileName,szFileName))
  839. {
  840. strcpy(g_szFileName, szFileName);
  841. DeleteAssetData();
  842. DeleteAsset();
  843. LoadAsset();
  844. // update the history
  845. UpdateHistory();
  846. // Save the list of previous files to the registry
  847. SaveHistory();
  848. }
  849. return;
  850. }
  851. //-------------------------------------------------------------------------------
  852. void SetupPPUIState()
  853. {
  854. // that's ugly. anyone willing to rewrite me from scratch?
  855. HMENU hMenu = GetMenu(g_hDlg);
  856. CheckMenuItem(hMenu,ID_VIEWER_PP_JIV,ppsteps & aiProcess_JoinIdenticalVertices ? MF_CHECKED : MF_UNCHECKED);
  857. CheckMenuItem(hMenu,ID_VIEWER_PP_CTS,ppsteps & aiProcess_CalcTangentSpace ? MF_CHECKED : MF_UNCHECKED);
  858. CheckMenuItem(hMenu,ID_VIEWER_PP_FD,ppsteps & aiProcess_FindDegenerates ? MF_CHECKED : MF_UNCHECKED);
  859. CheckMenuItem(hMenu,ID_VIEWER_PP_FID,ppsteps & aiProcess_FindInvalidData ? MF_CHECKED : MF_UNCHECKED);
  860. CheckMenuItem(hMenu,ID_VIEWER_PP_FIM,ppsteps & aiProcess_FindInstances ? MF_CHECKED : MF_UNCHECKED);
  861. CheckMenuItem(hMenu,ID_VIEWER_PP_FIN,ppsteps & aiProcess_FixInfacingNormals ? MF_CHECKED : MF_UNCHECKED);
  862. CheckMenuItem(hMenu,ID_VIEWER_PP_GUV,ppsteps & aiProcess_GenUVCoords ? MF_CHECKED : MF_UNCHECKED);
  863. CheckMenuItem(hMenu,ID_VIEWER_PP_ICL,ppsteps & aiProcess_ImproveCacheLocality ? MF_CHECKED : MF_UNCHECKED);
  864. CheckMenuItem(hMenu,ID_VIEWER_PP_OG,ppsteps & aiProcess_OptimizeGraph ? MF_CHECKED : MF_UNCHECKED);
  865. CheckMenuItem(hMenu,ID_VIEWER_PP_OM,ppsteps & aiProcess_OptimizeMeshes ? MF_CHECKED : MF_UNCHECKED);
  866. CheckMenuItem(hMenu,ID_VIEWER_PP_PTV,ppsteps & aiProcess_PreTransformVertices ? MF_CHECKED : MF_UNCHECKED);
  867. CheckMenuItem(hMenu,ID_VIEWER_PP_RRM2,ppsteps & aiProcess_RemoveRedundantMaterials ? MF_CHECKED : MF_UNCHECKED);
  868. CheckMenuItem(hMenu,ID_VIEWER_PP_TUV,ppsteps & aiProcess_TransformUVCoords ? MF_CHECKED : MF_UNCHECKED);
  869. CheckMenuItem(hMenu,ID_VIEWER_PP_VDS,ppsteps & aiProcess_ValidateDataStructure ? MF_CHECKED : MF_UNCHECKED);
  870. CheckMenuItem(hMenu,ID_VIEWER_PP_DB,ppsteps & aiProcess_Debone ? MF_CHECKED : MF_UNCHECKED);
  871. }
  872. #ifndef ASSIMP_BUILD_NO_EXPORT
  873. //-------------------------------------------------------------------------------
  874. // Fill the 'export' top level menu with a list of all supported export formats
  875. //-------------------------------------------------------------------------------
  876. void PopulateExportMenu()
  877. {
  878. // add sub items for all recent files
  879. Exporter exp;
  880. HMENU hm = ::CreateMenu();
  881. for(size_t i = 0; i < exp.GetExportFormatCount(); ++i)
  882. {
  883. const aiExportFormatDesc* const e = exp.GetExportFormatDescription(i);
  884. char tmp[256];
  885. sprintf(tmp,"%s (%s)",e->description,e->id);
  886. AppendMenu(hm,MF_STRING,AI_VIEW_EXPORT_FMT_ID(i),tmp);
  887. }
  888. ModifyMenu(GetMenu(g_hDlg),ID_EXPORT,MF_BYCOMMAND | MF_POPUP,
  889. (UINT_PTR)hm,"Export");
  890. }
  891. //-------------------------------------------------------------------------------
  892. //-------------------------------------------------------------------------------
  893. void DoExport(size_t formatId)
  894. {
  895. if (!g_szFileName[0]) {
  896. MessageBox(g_hDlg, "No model loaded", "Export", MB_ICONERROR);
  897. return;
  898. }
  899. Exporter exp;
  900. const aiExportFormatDesc* const e = exp.GetExportFormatDescription(formatId);
  901. ai_assert(e);
  902. char szFileName[MAX_PATH*2];
  903. DWORD dwTemp = sizeof(szFileName);
  904. if(ERROR_SUCCESS == RegQueryValueEx(g_hRegistry,"ModelExportDest",NULL,NULL,(BYTE*)szFileName, &dwTemp)) {
  905. ai_assert(strlen(szFileName) <= MAX_PATH);
  906. // invent a nice default file name
  907. char* sz = std::max(strrchr(szFileName,'\\'),strrchr(szFileName,'/'));
  908. if (sz) {
  909. strncpy(sz,std::max(strrchr(g_szFileName,'\\'),strrchr(g_szFileName,'/')),MAX_PATH);
  910. }
  911. }
  912. else {
  913. // Key was not found. Use the folder where the asset comes from
  914. strncpy(szFileName,g_szFileName,MAX_PATH);
  915. }
  916. // fix file extension
  917. { char * const sz = strrchr(szFileName,'.');
  918. if(sz) {
  919. ai_assert((sz - &szFileName[0]) + strlen(e->fileExtension) + 1 <= MAX_PATH);
  920. strcpy(sz+1,e->fileExtension);
  921. }
  922. }
  923. // build the stupid info string for GetSaveFileName() - can't use sprintf() because the string must contain binary zeros.
  924. char desc[256] = {0};
  925. char* c = strcpy(desc,e->description) + strlen(e->description)+1;
  926. c += sprintf(c,"*.%s",e->fileExtension)+1;
  927. strcpy(c, "*.*\0"); c += 4;
  928. ai_assert(c - &desc[0] <= 256);
  929. const std::string ext = "."+std::string(e->fileExtension);
  930. OPENFILENAME sFilename1 = {
  931. sizeof(OPENFILENAME),
  932. g_hDlg,GetModuleHandle(NULL),
  933. desc, NULL, 0, 1,
  934. szFileName, MAX_PATH, NULL, 0, NULL,
  935. "Export asset",
  936. OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_NOCHANGEDIR,
  937. 0, 1, ext.c_str(), 0, NULL, NULL
  938. };
  939. if(::GetSaveFileName(&sFilename1) == 0) {
  940. return;
  941. }
  942. // Now store the file in the registry unless the user decided to stay in the model directory
  943. const std::string sFinal = szFileName, sub = sFinal.substr(0,sFinal.find_last_of("\\/"));
  944. if (strncmp(sub.c_str(),g_szFileName,sub.length())) {
  945. RegSetValueExA(g_hRegistry,"ModelExportDest",0,REG_SZ,(const BYTE*)szFileName,MAX_PATH);
  946. }
  947. // export the file
  948. const aiReturn res = exp.Export(g_pcAsset->pcScene,e->id,sFinal.c_str(),
  949. ppsteps | /* configurable pp steps */
  950. aiProcess_GenSmoothNormals | // generate smooth normal vectors if not existing
  951. aiProcess_SplitLargeMeshes | // split large, unrenderable meshes into submeshes
  952. aiProcess_Triangulate | // triangulate polygons with more than 3 edges
  953. aiProcess_ConvertToLeftHanded | // convert everything to D3D left handed space
  954. aiProcess_SortByPType | // make 'clean' meshes which consist of a single typ of primitives
  955. 0
  956. );
  957. if (res == aiReturn_SUCCESS) {
  958. CLogDisplay::Instance().AddEntry("[INFO] Exported file " + sFinal,D3DCOLOR_ARGB(0xFF,0x00,0xFF,0x00));
  959. return;
  960. }
  961. CLogDisplay::Instance().AddEntry("[INFO] Failure exporting file " +
  962. sFinal,D3DCOLOR_ARGB(0xFF,0xFF,0x00,0x00));
  963. }
  964. #endif
  965. //-------------------------------------------------------------------------------
  966. // Initialize the user interface
  967. //-------------------------------------------------------------------------------
  968. void InitUI()
  969. {
  970. SetDlgItemText(g_hDlg,IDC_EVERT,"0");
  971. SetDlgItemText(g_hDlg,IDC_EFACE,"0");
  972. SetDlgItemText(g_hDlg,IDC_EMAT,"0");
  973. SetDlgItemText(g_hDlg,IDC_ESHADER,"0");
  974. SetDlgItemText(g_hDlg,IDC_ENODEWND,"0");
  975. SetDlgItemText(g_hDlg,IDC_ETEX,"0");
  976. SetDlgItemText(g_hDlg,IDC_EMESH,"0");
  977. #ifndef ASSIMP_BUILD_NO_EXPORT
  978. PopulateExportMenu();
  979. #endif
  980. // setup the default window title
  981. SetWindowText(g_hDlg,AI_VIEW_CAPTION_BASE);
  982. // read some UI properties from the registry and apply them
  983. DWORD dwValue;
  984. DWORD dwTemp = sizeof( DWORD );
  985. // store the key in a global variable for later use
  986. RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\ASSIMP\\Viewer",
  987. 0,NULL,0,KEY_ALL_ACCESS, NULL, &g_hRegistry,NULL);
  988. if(ERROR_SUCCESS != RegQueryValueEx(g_hRegistry,"LastUIState",NULL,NULL,
  989. (BYTE*)&dwValue,&dwTemp))
  990. {
  991. dwValue = 1;
  992. }
  993. if (0 == dwValue)
  994. {
  995. // collapse the viewer
  996. // adjust the size
  997. RECT sRect;
  998. GetWindowRect(g_hDlg,&sRect);
  999. sRect.right -= sRect.left;
  1000. sRect.bottom -= sRect.top;
  1001. RECT sRect2;
  1002. GetWindowRect(GetDlgItem ( g_hDlg, IDC_BLUBB ),&sRect2);
  1003. sRect2.left -= sRect.left;
  1004. sRect2.top -= sRect.top;
  1005. SetWindowPos(g_hDlg,NULL,0,0,sRect.right-214,sRect.bottom,
  1006. SWP_NOMOVE | SWP_NOZORDER);
  1007. SetWindowText(GetDlgItem(g_hDlg,IDC_BLUBB),">>");
  1008. }
  1009. else
  1010. {
  1011. CheckDlgButton(g_hDlg,IDC_BLUBB,BST_CHECKED);
  1012. }
  1013. // AutoRotate
  1014. if(ERROR_SUCCESS != RegQueryValueEx(g_hRegistry,"AutoRotate",NULL,NULL,
  1015. (BYTE*)&dwValue,&dwTemp))dwValue = 0;
  1016. if (0 == dwValue)
  1017. {
  1018. g_sOptions.bRotate = false;
  1019. CheckDlgButton(g_hDlg,IDC_AUTOROTATE,BST_UNCHECKED);
  1020. }
  1021. else
  1022. {
  1023. g_sOptions.bRotate = true;
  1024. CheckDlgButton(g_hDlg,IDC_AUTOROTATE,BST_CHECKED);
  1025. }
  1026. // MultipleLights
  1027. if(ERROR_SUCCESS != RegQueryValueEx(g_hRegistry,"MultipleLights",NULL,NULL,
  1028. (BYTE*)&dwValue,&dwTemp))dwValue = 0;
  1029. if (0 == dwValue)
  1030. {
  1031. g_sOptions.b3Lights = false;
  1032. CheckDlgButton(g_hDlg,IDC_3LIGHTS,BST_UNCHECKED);
  1033. }
  1034. else
  1035. {
  1036. g_sOptions.b3Lights = true;
  1037. CheckDlgButton(g_hDlg,IDC_3LIGHTS,BST_CHECKED);
  1038. }
  1039. // Light rotate
  1040. if(ERROR_SUCCESS != RegQueryValueEx(g_hRegistry,"LightRotate",NULL,NULL,
  1041. (BYTE*)&dwValue,&dwTemp))dwValue = 0;
  1042. if (0 == dwValue)
  1043. {
  1044. g_sOptions.bLightRotate = false;
  1045. CheckDlgButton(g_hDlg,IDC_LIGHTROTATE,BST_UNCHECKED);
  1046. }
  1047. else
  1048. {
  1049. g_sOptions.bLightRotate = true;
  1050. CheckDlgButton(g_hDlg,IDC_LIGHTROTATE,BST_CHECKED);
  1051. }
  1052. // NoSpecular
  1053. if(ERROR_SUCCESS != RegQueryValueEx(g_hRegistry,"NoSpecular",NULL,NULL,
  1054. (BYTE*)&dwValue,&dwTemp))dwValue = 0;
  1055. if (0 == dwValue)
  1056. {
  1057. g_sOptions.bNoSpecular = false;
  1058. CheckDlgButton(g_hDlg,IDC_NOSPECULAR,BST_UNCHECKED);
  1059. }
  1060. else
  1061. {
  1062. g_sOptions.bNoSpecular = true;
  1063. CheckDlgButton(g_hDlg,IDC_NOSPECULAR,BST_CHECKED);
  1064. }
  1065. // LowQuality
  1066. if(ERROR_SUCCESS != RegQueryValueEx(g_hRegistry,"LowQuality",NULL,NULL,
  1067. (BYTE*)&dwValue,&dwTemp))dwValue = 0;
  1068. if (0 == dwValue)
  1069. {
  1070. g_sOptions.bLowQuality = false;
  1071. CheckDlgButton(g_hDlg,IDC_LOWQUALITY,BST_UNCHECKED);
  1072. }
  1073. else
  1074. {
  1075. g_sOptions.bLowQuality = true;
  1076. CheckDlgButton(g_hDlg,IDC_LOWQUALITY,BST_CHECKED);
  1077. }
  1078. // LowQuality
  1079. if(ERROR_SUCCESS != RegQueryValueEx(g_hRegistry,"NoTransparency",NULL,NULL,
  1080. (BYTE*)&dwValue,&dwTemp))dwValue = 0;
  1081. if (0 == dwValue)
  1082. {
  1083. g_sOptions.bNoAlphaBlending = false;
  1084. CheckDlgButton(g_hDlg,IDC_NOAB,BST_UNCHECKED);
  1085. }
  1086. else
  1087. {
  1088. g_sOptions.bNoAlphaBlending = true;
  1089. CheckDlgButton(g_hDlg,IDC_NOAB,BST_CHECKED);
  1090. }
  1091. // DisplayNormals
  1092. if(ERROR_SUCCESS != RegQueryValueEx(g_hRegistry,"RenderNormals",NULL,NULL,
  1093. (BYTE*)&dwValue,&dwTemp))dwValue = 0;
  1094. if (0 == dwValue)
  1095. {
  1096. g_sOptions.bRenderNormals = false;
  1097. CheckDlgButton(g_hDlg,IDC_TOGGLENORMALS,BST_UNCHECKED);
  1098. }
  1099. else
  1100. {
  1101. g_sOptions.bRenderNormals = true;
  1102. CheckDlgButton(g_hDlg,IDC_TOGGLENORMALS,BST_CHECKED);
  1103. }
  1104. // NoMaterials
  1105. if(ERROR_SUCCESS != RegQueryValueEx(g_hRegistry,"RenderMats",NULL,NULL,
  1106. (BYTE*)&dwValue,&dwTemp))dwValue = 1;
  1107. if (0 == dwValue)
  1108. {
  1109. g_sOptions.bRenderMats = false;
  1110. CheckDlgButton(g_hDlg,IDC_TOGGLEMAT,BST_CHECKED);
  1111. }
  1112. else
  1113. {
  1114. g_sOptions.bRenderMats = true;
  1115. CheckDlgButton(g_hDlg,IDC_TOGGLEMAT,BST_UNCHECKED);
  1116. }
  1117. // MultiSampling
  1118. if(ERROR_SUCCESS != RegQueryValueEx(g_hRegistry,"MultiSampling",NULL,NULL,
  1119. (BYTE*)&dwValue,&dwTemp))dwValue = 1;
  1120. if (0 == dwValue)
  1121. {
  1122. g_sOptions.bMultiSample = false;
  1123. CheckDlgButton(g_hDlg,IDC_TOGGLEMS,BST_UNCHECKED);
  1124. }
  1125. else
  1126. {
  1127. g_sOptions.bMultiSample = true;
  1128. CheckDlgButton(g_hDlg,IDC_TOGGLEMS,BST_CHECKED);
  1129. }
  1130. // FPS Mode
  1131. if(ERROR_SUCCESS != RegQueryValueEx(g_hRegistry,"FPSView",NULL,NULL,
  1132. (BYTE*)&dwValue,&dwTemp))dwValue = 0;
  1133. if (0 == dwValue)
  1134. {
  1135. g_bFPSView = false;
  1136. CheckDlgButton(g_hDlg,IDC_ZOOM,BST_CHECKED);
  1137. }
  1138. else
  1139. {
  1140. g_bFPSView = true;
  1141. CheckDlgButton(g_hDlg,IDC_ZOOM,BST_UNCHECKED);
  1142. }
  1143. // WireFrame
  1144. if(ERROR_SUCCESS != RegQueryValueEx(g_hRegistry,"Wireframe",NULL,NULL,
  1145. (BYTE*)&dwValue,&dwTemp))dwValue = 0;
  1146. if (0 == dwValue)
  1147. {
  1148. g_sOptions.eDrawMode = RenderOptions::NORMAL;
  1149. CheckDlgButton(g_hDlg,IDC_TOGGLEWIRE,BST_UNCHECKED);
  1150. }
  1151. else
  1152. {
  1153. g_sOptions.eDrawMode = RenderOptions::WIREFRAME;
  1154. CheckDlgButton(g_hDlg,IDC_TOGGLEWIRE,BST_CHECKED);
  1155. }
  1156. if(ERROR_SUCCESS != RegQueryValueEx(g_hRegistry,"PostProcessing",NULL,NULL,(BYTE*)&dwValue,&dwTemp))
  1157. ppsteps = ppstepsdefault;
  1158. else ppsteps = dwValue;
  1159. SetupPPUIState();
  1160. LoadCheckerPatternColors();
  1161. SendDlgItemMessage(g_hDlg,IDC_SLIDERANIM,TBM_SETRANGEMIN,TRUE,0);
  1162. SendDlgItemMessage(g_hDlg,IDC_SLIDERANIM,TBM_SETRANGEMAX,TRUE,10000);
  1163. return;
  1164. }
  1165. //-------------------------------------------------------------------------------
  1166. // Message prcoedure for the smooth normals dialog
  1167. //-------------------------------------------------------------------------------
  1168. INT_PTR CALLBACK SMMessageProc(HWND hwndDlg,UINT uMsg,
  1169. WPARAM wParam,LPARAM lParam)
  1170. {
  1171. UNREFERENCED_PARAMETER(lParam);
  1172. switch (uMsg)
  1173. {
  1174. case WM_INITDIALOG:
  1175. char s[30];
  1176. ::sprintf(s,"%.2f",g_smoothAngle);
  1177. SetDlgItemText(hwndDlg,IDC_EDITSM,s);
  1178. return TRUE;
  1179. case WM_CLOSE:
  1180. EndDialog(hwndDlg,0);
  1181. return TRUE;
  1182. case WM_COMMAND:
  1183. if (IDOK == LOWORD(wParam)) {
  1184. char s[30];
  1185. GetDlgItemText(hwndDlg,IDC_EDITSM,s,30);
  1186. g_smoothAngle = (float)atof(s);
  1187. EndDialog(hwndDlg,0);
  1188. }
  1189. else if (IDCANCEL == LOWORD(wParam)) {
  1190. EndDialog(hwndDlg,1);
  1191. }
  1192. return TRUE;
  1193. }
  1194. return FALSE;
  1195. }
  1196. //-------------------------------------------------------------------------------
  1197. // Main message procedure of the application
  1198. //
  1199. // The function handles all incoming messages for the main window.
  1200. // However, if does not directly process input commands.
  1201. // NOTE: Due to the impossibility to process WM_CHAR messages in dialogs
  1202. // properly the code for all hotkeys has been moved to the WndMain
  1203. //-------------------------------------------------------------------------------
  1204. INT_PTR CALLBACK MessageProc(HWND hwndDlg,UINT uMsg,
  1205. WPARAM wParam,LPARAM lParam)
  1206. {
  1207. UNREFERENCED_PARAMETER(lParam);
  1208. UNREFERENCED_PARAMETER(wParam);
  1209. int xPos,yPos;
  1210. int xPos2,yPos2;
  1211. int fHalfX;
  1212. int fHalfY;
  1213. TRACKMOUSEEVENT sEvent;
  1214. switch (uMsg)
  1215. {
  1216. case WM_INITDIALOG:
  1217. g_hDlg = hwndDlg;
  1218. // load the state of the usr interface
  1219. InitUI();
  1220. // load the file history
  1221. LoadHistory();
  1222. // load the current color of the lights
  1223. LoadLightColors();
  1224. return TRUE;
  1225. case WM_HSCROLL:
  1226. // XXX quick and dirty fix for #3029892
  1227. if (GetDlgItem(g_hDlg, IDC_SLIDERANIM) == (HWND)lParam && g_pcAsset && g_pcAsset->pcScene->mAnimations)
  1228. {
  1229. double num = (double)SendDlgItemMessage(g_hDlg,IDC_SLIDERANIM,TBM_GETPOS,0,0);
  1230. const aiAnimation* anim = g_pcAsset->pcScene->mAnimations[ g_pcAsset->mAnimator->CurrentAnimIndex() ];
  1231. g_dCurrent = (anim->mDuration/anim->mTicksPerSecond) * num/10000;
  1232. g_pcAsset->mAnimator->Calculate(g_dCurrent);
  1233. }
  1234. break;
  1235. case WM_MOUSEWHEEL:
  1236. if (CDisplay::VIEWMODE_TEXTURE == CDisplay::Instance().GetViewMode())
  1237. {
  1238. CDisplay::Instance().SetTextureViewZoom ( GET_WHEEL_DELTA_WPARAM(wParam) / 50.0f );
  1239. }
  1240. else
  1241. {
  1242. if (!g_bFPSView)
  1243. {
  1244. g_sCamera.vPos.z += GET_WHEEL_DELTA_WPARAM(wParam) / 50.0f;
  1245. }
  1246. else
  1247. {
  1248. g_sCamera.vPos += (GET_WHEEL_DELTA_WPARAM(wParam) / 50.0f) *
  1249. g_sCamera.vLookAt.Normalize();
  1250. }
  1251. }
  1252. return TRUE;
  1253. case WM_MOUSELEAVE:
  1254. g_bMousePressed = false;
  1255. g_bMousePressedR = false;
  1256. g_bMousePressedM = false;
  1257. g_bMousePressedBoth = false;
  1258. return TRUE;
  1259. case WM_LBUTTONDBLCLK:
  1260. CheckDlgButton(hwndDlg,IDC_AUTOROTATE,
  1261. IsDlgButtonChecked(hwndDlg,IDC_AUTOROTATE) == BST_CHECKED
  1262. ? BST_UNCHECKED : BST_CHECKED);
  1263. ToggleAutoRotate();
  1264. return TRUE;
  1265. case WM_CLOSE:
  1266. PostQuitMessage(0);
  1267. DestroyWindow(hwndDlg);
  1268. return TRUE;
  1269. case WM_NOTIFY:
  1270. if (IDC_TREE1 == wParam)
  1271. {
  1272. NMTREEVIEW* pnmtv = (LPNMTREEVIEW) lParam;
  1273. if (TVN_SELCHANGED == pnmtv->hdr.code)
  1274. CDisplay::Instance().OnSetup( pnmtv->itemNew.hItem );
  1275. else if (NM_RCLICK == pnmtv->hdr.code)
  1276. {
  1277. // determine in which item the click was ...
  1278. POINT sPoint;
  1279. GetCursorPos(&sPoint);
  1280. ScreenToClient(GetDlgItem(g_hDlg,IDC_TREE1),&sPoint);
  1281. TVHITTESTINFO sHit;
  1282. sHit.pt = sPoint;
  1283. TreeView_HitTest(GetDlgItem(g_hDlg,IDC_TREE1),&sHit);
  1284. CDisplay::Instance().ShowTreeViewContextMenu(sHit.hItem);
  1285. }
  1286. }
  1287. return TRUE;
  1288. case WM_DRAWITEM:
  1289. {
  1290. // draw the two light colors
  1291. DRAWITEMSTRUCT* pcStruct = (DRAWITEMSTRUCT*)lParam;
  1292. RECT sRect;
  1293. GetWindowRect(GetDlgItem(g_hDlg,IDC_LCOLOR1),&sRect);
  1294. sRect.right -= sRect.left;
  1295. sRect.bottom -= sRect.top;
  1296. sRect.left = sRect.top = 0;
  1297. bool bDraw = false;
  1298. if(IDC_LCOLOR1 == pcStruct->CtlID)
  1299. {
  1300. unsigned char r,g,b;
  1301. const char* szText;
  1302. if (CDisplay::VIEWMODE_TEXTURE == CDisplay::Instance().GetViewMode() ||
  1303. CDisplay::VIEWMODE_MATERIAL == CDisplay::Instance().GetViewMode())
  1304. {
  1305. r = (unsigned char)(CDisplay::Instance().GetFirstCheckerColor()->x * 255.0f);
  1306. g = (unsigned char)(CDisplay::Instance().GetFirstCheckerColor()->y * 255.0f);
  1307. b = (unsigned char)(CDisplay::Instance().GetFirstCheckerColor()->z * 255.0f);
  1308. szText = "Background #0";
  1309. }
  1310. else if (!g_pcAsset)
  1311. {
  1312. r = g = b = 150;szText = "";
  1313. }
  1314. else
  1315. {
  1316. r = (unsigned char)((g_avLightColors[0] >> 16) & 0xFF);
  1317. g = (unsigned char)((g_avLightColors[0] >> 8) & 0xFF);
  1318. b = (unsigned char)((g_avLightColors[0]) & 0xFF);
  1319. szText = "Light #0";
  1320. }
  1321. HBRUSH hbr = CreateSolidBrush(RGB(r,g,b));
  1322. FillRect(pcStruct->hDC,&sRect,hbr);
  1323. SetTextColor(pcStruct->hDC,RGB(0xFF-r,0xFF-g,0xFF-b));
  1324. SetBkMode(pcStruct->hDC,TRANSPARENT);
  1325. TextOut(pcStruct->hDC,4,1,szText, static_cast<int>(strlen(szText)));
  1326. bDraw = true;
  1327. }
  1328. else if(IDC_LCOLOR2 == pcStruct->CtlID)
  1329. {
  1330. unsigned char r,g,b;
  1331. const char* szText;
  1332. if (CDisplay::VIEWMODE_TEXTURE == CDisplay::Instance().GetViewMode() ||
  1333. CDisplay::VIEWMODE_MATERIAL == CDisplay::Instance().GetViewMode())
  1334. {
  1335. r = (unsigned char)(CDisplay::Instance().GetSecondCheckerColor()->x * 255.0f);
  1336. g = (unsigned char)(CDisplay::Instance().GetSecondCheckerColor()->y * 255.0f);
  1337. b = (unsigned char)(CDisplay::Instance().GetSecondCheckerColor()->z * 255.0f);
  1338. szText = "Background #1";
  1339. }
  1340. else if (!g_pcAsset)
  1341. {
  1342. r = g = b = 150;szText = "";
  1343. }
  1344. else
  1345. {
  1346. r = (unsigned char)((g_avLightColors[1] >> 16) & 0xFF);
  1347. g = (unsigned char)((g_avLightColors[1] >> 8) & 0xFF);
  1348. b = (unsigned char)((g_avLightColors[1]) & 0xFF);
  1349. szText = "Light #1";
  1350. }
  1351. HBRUSH hbr = CreateSolidBrush(RGB(r,g,b));
  1352. FillRect(pcStruct->hDC,&sRect,hbr);
  1353. SetTextColor(pcStruct->hDC,RGB(0xFF-r,0xFF-g,0xFF-b));
  1354. SetBkMode(pcStruct->hDC,TRANSPARENT);
  1355. TextOut(pcStruct->hDC,4,1,szText, static_cast<int>(strlen(szText)));
  1356. bDraw = true;
  1357. }
  1358. else if(IDC_LCOLOR3 == pcStruct->CtlID)
  1359. {
  1360. unsigned char r,g,b;
  1361. const char* szText;
  1362. if (CDisplay::VIEWMODE_TEXTURE == CDisplay::Instance().GetViewMode() ||
  1363. CDisplay::VIEWMODE_MATERIAL == CDisplay::Instance().GetViewMode())
  1364. {
  1365. r = g = b = 0;
  1366. szText = "";
  1367. }
  1368. else if (!g_pcAsset)
  1369. {
  1370. r = g = b = 150;szText = "";
  1371. }
  1372. else
  1373. {
  1374. r = (unsigned char)((g_avLightColors[2] >> 16) & 0xFF);
  1375. g = (unsigned char)((g_avLightColors[2] >> 8) & 0xFF);
  1376. b = (unsigned char)((g_avLightColors[2]) & 0xFF);
  1377. szText = "Ambient";
  1378. }
  1379. HBRUSH hbr = CreateSolidBrush(RGB(r,g,b));
  1380. FillRect(pcStruct->hDC,&sRect,hbr);
  1381. SetTextColor(pcStruct->hDC,RGB(0xFF-r,0xFF-g,0xFF-b));
  1382. SetBkMode(pcStruct->hDC,TRANSPARENT);
  1383. TextOut(pcStruct->hDC,4,1,szText,static_cast<int>(strlen(szText)));
  1384. bDraw = true;
  1385. }
  1386. // draw the black border around the rects
  1387. if (bDraw)
  1388. {
  1389. SetBkColor(pcStruct->hDC,RGB(0,0,0));
  1390. MoveToEx(pcStruct->hDC,0,0,NULL);
  1391. LineTo(pcStruct->hDC,sRect.right-1,0);
  1392. LineTo(pcStruct->hDC,sRect.right-1,sRect.bottom-1);
  1393. LineTo(pcStruct->hDC,0,sRect.bottom-1);
  1394. LineTo(pcStruct->hDC,0,0);
  1395. }
  1396. }
  1397. return TRUE;
  1398. case WM_DESTROY:
  1399. // close the open registry key
  1400. RegCloseKey(g_hRegistry);
  1401. return TRUE;
  1402. case WM_LBUTTONDOWN:
  1403. g_bMousePressed = true;
  1404. // register a mouse track handler to be sure we'll know
  1405. // when the mouse leaves the display view again
  1406. sEvent.cbSize = sizeof(TRACKMOUSEEVENT);
  1407. sEvent.dwFlags = TME_LEAVE;
  1408. sEvent.hwndTrack = g_hDlg;
  1409. sEvent.dwHoverTime = HOVER_DEFAULT;
  1410. TrackMouseEvent(&sEvent);
  1411. if (g_bMousePressedR)
  1412. {
  1413. g_bMousePressed = false;
  1414. g_bMousePressedR = false;
  1415. g_bMousePressedBoth = true;
  1416. return TRUE;
  1417. }
  1418. // need to determine the position of the mouse and the
  1419. // distance from the center
  1420. //xPos = (int)(short)LOWORD(lParam);
  1421. //yPos = (int)(short)HIWORD(lParam);
  1422. POINT sPoint;
  1423. GetCursorPos(&sPoint);
  1424. ScreenToClient(GetDlgItem(g_hDlg,IDC_RT),&sPoint);
  1425. xPos = xPos2 = sPoint.x;
  1426. yPos = yPos2 = sPoint.y;
  1427. /* xPos -= 10;
  1428. yPos -= 10;
  1429. xPos2 = xPos-3;
  1430. yPos2 = yPos-5;*/
  1431. RECT sRect;
  1432. GetWindowRect(GetDlgItem(g_hDlg,IDC_RT),&sRect);
  1433. sRect.right -= sRect.left;
  1434. sRect.bottom -= sRect.top;
  1435. // if the mouse klick was inside the viewer panel
  1436. // give the focus to it
  1437. if (xPos > 0 && xPos < sRect.right && yPos > 0 && yPos < sRect.bottom)
  1438. {
  1439. SetFocus(GetDlgItem(g_hDlg,IDC_RT));
  1440. }
  1441. // g_bInvert stores whether the mouse has started on the negative
  1442. // x or on the positive x axis of the imaginary coordinate system
  1443. // with origin p at the center of the HUD texture
  1444. xPos -= sRect.right/2;
  1445. yPos -= sRect.bottom/2;
  1446. if (xPos > 0)g_bInvert = true;
  1447. else g_bInvert = false;
  1448. D3DSURFACE_DESC sDesc;
  1449. g_pcTexture->GetLevelDesc(0,&sDesc);
  1450. fHalfX = (int)(((float)sRect.right-(float)sDesc.Width) / 2.0f);
  1451. fHalfY = (int)(((float)sRect.bottom-(float)sDesc.Height) / 2.0f);
  1452. // Determine the input operation to perform for this position
  1453. g_eClick = EClickPos_Outside;
  1454. if (xPos2 >= fHalfX && xPos2 < fHalfX + (int)sDesc.Width &&
  1455. yPos2 >= fHalfY && yPos2 < fHalfY + (int)sDesc.Height &&
  1456. NULL != g_szImageMask)
  1457. {
  1458. // inside the texture. Lookup the grayscale value from it
  1459. xPos2 -= fHalfX;
  1460. yPos2 -= fHalfY;
  1461. unsigned char chValue = g_szImageMask[xPos2 + yPos2 * sDesc.Width];
  1462. if (chValue > 0xFF-20)
  1463. {
  1464. g_eClick = EClickPos_Circle;
  1465. }
  1466. else if (chValue < 0xFF-20 && chValue > 185)
  1467. {
  1468. g_eClick = EClickPos_CircleHor;
  1469. }
  1470. else if (chValue > 0x10 && chValue < 185)
  1471. {
  1472. g_eClick = EClickPos_CircleVert;
  1473. }
  1474. }
  1475. return TRUE;
  1476. case WM_RBUTTONDOWN:
  1477. g_bMousePressedR = true;
  1478. sEvent.cbSize = sizeof(TRACKMOUSEEVENT);
  1479. sEvent.dwFlags = TME_LEAVE;
  1480. sEvent.hwndTrack = g_hDlg;
  1481. sEvent.dwHoverTime = HOVER_DEFAULT;
  1482. TrackMouseEvent(&sEvent);
  1483. if (g_bMousePressed)
  1484. {
  1485. g_bMousePressedR = false;
  1486. g_bMousePressed = false;
  1487. g_bMousePressedBoth = true;
  1488. }
  1489. return TRUE;
  1490. case WM_MBUTTONDOWN:
  1491. g_bMousePressedM = true;
  1492. sEvent.cbSize = sizeof(TRACKMOUSEEVENT);
  1493. sEvent.dwFlags = TME_LEAVE;
  1494. sEvent.hwndTrack = g_hDlg;
  1495. sEvent.dwHoverTime = HOVER_DEFAULT;
  1496. TrackMouseEvent(&sEvent);
  1497. return TRUE;
  1498. case WM_LBUTTONUP:
  1499. g_bMousePressed = false;
  1500. g_bMousePressedBoth = false;
  1501. return TRUE;
  1502. case WM_RBUTTONUP:
  1503. g_bMousePressedR = false;
  1504. g_bMousePressedBoth = false;
  1505. return TRUE;
  1506. case WM_MBUTTONUP:
  1507. g_bMousePressedM = false;
  1508. return TRUE;
  1509. case WM_DROPFILES:
  1510. {
  1511. HDROP hDrop = (HDROP)wParam;
  1512. char szFile[MAX_PATH];
  1513. DragQueryFile(hDrop,0,szFile,sizeof(szFile));
  1514. const char* sz = strrchr(szFile,'.');
  1515. if (!sz)
  1516. sz = szFile;
  1517. if (CDisplay::VIEWMODE_TEXTURE == CDisplay::Instance().GetViewMode())
  1518. {
  1519. // replace the selected texture with the new one ...
  1520. CDisplay::Instance().ReplaceCurrentTexture(szFile);
  1521. }
  1522. else
  1523. {
  1524. // check whether it is a typical texture file format ...
  1525. ++sz;
  1526. if (0 == ASSIMP_stricmp(sz,"png") ||
  1527. 0 == ASSIMP_stricmp(sz,"bmp") ||
  1528. 0 == ASSIMP_stricmp(sz,"jpg") ||
  1529. 0 == ASSIMP_stricmp(sz,"tga") ||
  1530. 0 == ASSIMP_stricmp(sz,"tif") ||
  1531. 0 == ASSIMP_stricmp(sz,"hdr") ||
  1532. 0 == ASSIMP_stricmp(sz,"ppm") ||
  1533. 0 == ASSIMP_stricmp(sz,"pfm"))
  1534. {
  1535. CBackgroundPainter::Instance().SetTextureBG(szFile);
  1536. }
  1537. else if (0 == Assimp::ASSIMP_stricmp(sz,"dds"))
  1538. {
  1539. // DDS files could contain skyboxes, but they could also
  1540. // contain normal 2D textures. The easiest way to find this
  1541. // out is to open the file and check the header ...
  1542. FILE* pFile = fopen(szFile,"rb");
  1543. if (!pFile)
  1544. return TRUE;
  1545. // header of a dds file (begin)
  1546. /*
  1547. DWORD dwMagic
  1548. DWORD dwSize
  1549. DWORD dwFlags
  1550. DWORD dwHeight
  1551. DWORD dwWidth
  1552. DWORD dwPitchOrLinearSize
  1553. DWORD dwDepth
  1554. DWORD dwMipMapCount -> total with this: 32
  1555. DWORD dwReserved1[11] -> total with this: 76
  1556. DDPIXELFORMAT ddpfPixelFormat -> total with this: 108
  1557. DWORD dwCaps1; -> total with this: 112
  1558. DWORD dwCaps2; ---< here we are!
  1559. */
  1560. DWORD dwCaps = 0;
  1561. fseek(pFile,112,SEEK_SET);
  1562. fread(&dwCaps,4,1,pFile);
  1563. if (dwCaps & 0x00000400L /* DDSCAPS2_CUBEMAP_POSITIVEX */)
  1564. {
  1565. CLogDisplay::Instance().AddEntry(
  1566. "[INFO] Assuming this dds file is a skybox ...",
  1567. D3DCOLOR_ARGB(0xFF,0xFF,0xFF,0));
  1568. CBackgroundPainter::Instance().SetCubeMapBG(szFile);
  1569. }
  1570. else CBackgroundPainter::Instance().SetTextureBG(szFile);
  1571. fclose(pFile);
  1572. }
  1573. else
  1574. {
  1575. strcpy(g_szFileName,szFile);
  1576. DeleteAsset();
  1577. LoadAsset();
  1578. UpdateHistory();
  1579. SaveHistory();
  1580. }
  1581. }
  1582. DragFinish(hDrop);
  1583. }
  1584. return TRUE;
  1585. case WM_COMMAND:
  1586. HMENU hMenu = GetMenu(g_hDlg);
  1587. if (ID_VIEWER_QUIT == LOWORD(wParam))
  1588. {
  1589. PostQuitMessage(0);
  1590. DestroyWindow(hwndDlg);
  1591. }
  1592. else if (IDC_COMBO1 == LOWORD(wParam))
  1593. {
  1594. if(HIWORD(wParam) == CBN_SELCHANGE) {
  1595. const size_t sel = static_cast<size_t>(ComboBox_GetCurSel(GetDlgItem(hwndDlg,IDC_COMBO1)));
  1596. if(g_pcAsset) {
  1597. g_pcAsset->mAnimator->SetAnimIndex(sel);
  1598. SendDlgItemMessage(hwndDlg,IDC_SLIDERANIM,TBM_SETPOS,TRUE,0);
  1599. }
  1600. }
  1601. }
  1602. else if (ID_VIEWER_RESETVIEW == LOWORD(wParam))
  1603. {
  1604. g_sCamera.vPos = aiVector3D(0.0f,0.0f,-10.0f);
  1605. g_sCamera.vLookAt = aiVector3D(0.0f,0.0f,1.0f);
  1606. g_sCamera.vUp = aiVector3D(0.0f,1.0f,0.0f);
  1607. g_sCamera.vRight = aiVector3D(0.0f,1.0f,0.0f);
  1608. g_mWorldRotate = aiMatrix4x4();
  1609. g_mWorld = aiMatrix4x4();
  1610. // don't forget to reset the st
  1611. CBackgroundPainter::Instance().ResetSB();
  1612. }
  1613. else if (ID__HELP == LOWORD(wParam))
  1614. {
  1615. DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_AVHELP),
  1616. hwndDlg,&HelpDialogProc);
  1617. }
  1618. else if (ID__ABOUT == LOWORD(wParam))
  1619. {
  1620. DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_ABOUTBOX),
  1621. hwndDlg,&AboutMessageProc);
  1622. }
  1623. else if (ID_TOOLS_LOGWINDOW == LOWORD(wParam))
  1624. {
  1625. CLogWindow::Instance().Show();
  1626. }
  1627. else if (ID__WEBSITE == LOWORD(wParam))
  1628. {
  1629. ShellExecute(NULL,"open","http://assimp.sourceforge.net","","",SW_SHOW);
  1630. }
  1631. else if (ID__WEBSITESF == LOWORD(wParam))
  1632. {
  1633. ShellExecute(NULL,"open","https://sourceforge.net/projects/assimp","","",SW_SHOW);
  1634. }
  1635. else if (ID_REPORTBUG == LOWORD(wParam))
  1636. {
  1637. ShellExecute(NULL,"open","https://sourceforge.net/tracker/?func=add&group_id=226462&atid=1067632","","",SW_SHOW);
  1638. }
  1639. else if (ID_FR == LOWORD(wParam))
  1640. {
  1641. ShellExecute(NULL,"open","https://sourceforge.net/forum/forum.php?forum_id=817653","","",SW_SHOW);
  1642. }
  1643. else if (ID_TOOLS_CLEARLOG == LOWORD(wParam))
  1644. {
  1645. CLogWindow::Instance().Clear();
  1646. }
  1647. else if (ID_TOOLS_SAVELOGTOFILE == LOWORD(wParam))
  1648. {
  1649. CLogWindow::Instance().Save();
  1650. }
  1651. else if (ID_VIEWER_MEMORYCONSUMATION == LOWORD(wParam))
  1652. {
  1653. DisplayMemoryConsumption();
  1654. }
  1655. else if (ID_VIEWER_H == LOWORD(wParam))
  1656. {
  1657. MakeFileAssociations();
  1658. }
  1659. else if (ID_BACKGROUND_CLEAR == LOWORD(wParam))
  1660. {
  1661. ClearBG();
  1662. }
  1663. else if (ID_BACKGROUND_SETCOLOR == LOWORD(wParam))
  1664. {
  1665. ChooseBGColor();
  1666. }
  1667. else if (ID_BACKGROUND_LOADTEXTURE == LOWORD(wParam))
  1668. {
  1669. LoadBGTexture();
  1670. }
  1671. else if (ID_BACKGROUND_LOADSKYBOX == LOWORD(wParam))
  1672. {
  1673. LoadSkybox();
  1674. }
  1675. else if (ID_VIEWER_SAVESCREENSHOTTOFILE == LOWORD(wParam))
  1676. {
  1677. SaveScreenshot();
  1678. }
  1679. else if (ID_VIEWER_OPEN == LOWORD(wParam))
  1680. {
  1681. OpenAsset();
  1682. }
  1683. else if (ID_TOOLS_FLIPNORMALS == LOWORD(wParam))
  1684. {
  1685. if (g_pcAsset && g_pcAsset->pcScene)
  1686. {
  1687. g_pcAsset->FlipNormals();
  1688. }
  1689. }
  1690. // this is ugly. anyone willing to rewrite it from scratch using wxwidgets or similar?
  1691. else if (ID_VIEWER_PP_JIV == LOWORD(wParam)) {
  1692. ppsteps ^= aiProcess_JoinIdenticalVertices;
  1693. CheckMenuItem(hMenu,ID_VIEWER_PP_JIV,ppsteps & aiProcess_JoinIdenticalVertices ? MF_CHECKED : MF_UNCHECKED);
  1694. UpdatePPSettings();
  1695. }
  1696. else if (ID_VIEWER_PP_CTS == LOWORD(wParam)) {
  1697. ppsteps ^= aiProcess_CalcTangentSpace;
  1698. CheckMenuItem(hMenu,ID_VIEWER_PP_CTS,ppsteps & aiProcess_CalcTangentSpace ? MF_CHECKED : MF_UNCHECKED);
  1699. UpdatePPSettings();
  1700. }
  1701. else if (ID_VIEWER_PP_FD == LOWORD(wParam)) {
  1702. ppsteps ^= aiProcess_FindDegenerates;
  1703. CheckMenuItem(hMenu,ID_VIEWER_PP_FD,ppsteps & aiProcess_FindDegenerates ? MF_CHECKED : MF_UNCHECKED);
  1704. UpdatePPSettings();
  1705. }
  1706. else if (ID_VIEWER_PP_FID == LOWORD(wParam)) {
  1707. ppsteps ^= aiProcess_FindInvalidData;
  1708. CheckMenuItem(hMenu,ID_VIEWER_PP_FID,ppsteps & aiProcess_FindInvalidData ? MF_CHECKED : MF_UNCHECKED);
  1709. UpdatePPSettings();
  1710. }
  1711. else if (ID_VIEWER_PP_FIM == LOWORD(wParam)) {
  1712. ppsteps ^= aiProcess_FindInstances;
  1713. CheckMenuItem(hMenu,ID_VIEWER_PP_FIM,ppsteps & aiProcess_FindInstances ? MF_CHECKED : MF_UNCHECKED);
  1714. UpdatePPSettings();
  1715. }
  1716. else if (ID_VIEWER_PP_FIN == LOWORD(wParam)) {
  1717. ppsteps ^= aiProcess_FixInfacingNormals;
  1718. CheckMenuItem(hMenu,ID_VIEWER_PP_FIN,ppsteps & aiProcess_FixInfacingNormals ? MF_CHECKED : MF_UNCHECKED);
  1719. UpdatePPSettings();
  1720. }
  1721. else if (ID_VIEWER_PP_GUV == LOWORD(wParam)) {
  1722. ppsteps ^= aiProcess_GenUVCoords;
  1723. CheckMenuItem(hMenu,ID_VIEWER_PP_GUV,ppsteps & aiProcess_GenUVCoords ? MF_CHECKED : MF_UNCHECKED);
  1724. UpdatePPSettings();
  1725. }
  1726. else if (ID_VIEWER_PP_ICL == LOWORD(wParam)) {
  1727. ppsteps ^= aiProcess_ImproveCacheLocality;
  1728. CheckMenuItem(hMenu,ID_VIEWER_PP_ICL,ppsteps & aiProcess_ImproveCacheLocality ? MF_CHECKED : MF_UNCHECKED);
  1729. UpdatePPSettings();
  1730. }
  1731. else if (ID_VIEWER_PP_OG == LOWORD(wParam)) {
  1732. if (ppsteps & aiProcess_PreTransformVertices) {
  1733. CLogDisplay::Instance().AddEntry("[ERROR] This setting is incompatible with \'Pretransform Vertices\'");
  1734. }
  1735. else {
  1736. ppsteps ^= aiProcess_OptimizeGraph;
  1737. CheckMenuItem(hMenu,ID_VIEWER_PP_OG,ppsteps & aiProcess_OptimizeGraph ? MF_CHECKED : MF_UNCHECKED);
  1738. UpdatePPSettings();
  1739. }
  1740. }
  1741. else if (ID_VIEWER_PP_OM == LOWORD(wParam)) {
  1742. ppsteps ^= aiProcess_OptimizeMeshes;
  1743. CheckMenuItem(hMenu,ID_VIEWER_PP_OM,ppsteps & aiProcess_OptimizeMeshes ? MF_CHECKED : MF_UNCHECKED);
  1744. UpdatePPSettings();
  1745. }
  1746. else if (ID_VIEWER_PP_PTV == LOWORD(wParam)) {
  1747. if (ppsteps & aiProcess_OptimizeGraph) {
  1748. CLogDisplay::Instance().AddEntry("[ERROR] This setting is incompatible with \'Optimize Scenegraph\'");
  1749. }
  1750. else {
  1751. ppsteps ^= aiProcess_PreTransformVertices;
  1752. CheckMenuItem(hMenu,ID_VIEWER_PP_PTV,ppsteps & aiProcess_PreTransformVertices ? MF_CHECKED : MF_UNCHECKED);
  1753. UpdatePPSettings();
  1754. }
  1755. }
  1756. else if (ID_VIEWER_PP_RRM2 == LOWORD(wParam)) {
  1757. ppsteps ^= aiProcess_RemoveRedundantMaterials;
  1758. CheckMenuItem(hMenu,ID_VIEWER_PP_RRM2,ppsteps & aiProcess_RemoveRedundantMaterials ? MF_CHECKED : MF_UNCHECKED);
  1759. UpdatePPSettings();
  1760. }
  1761. else if (ID_VIEWER_PP_TUV == LOWORD(wParam)) {
  1762. ppsteps ^= aiProcess_TransformUVCoords;
  1763. CheckMenuItem(hMenu,ID_VIEWER_PP_TUV,ppsteps & aiProcess_TransformUVCoords ? MF_CHECKED : MF_UNCHECKED);
  1764. UpdatePPSettings();
  1765. }
  1766. else if (ID_VIEWER_PP_DB == LOWORD(wParam)) {
  1767. ppsteps ^= aiProcess_Debone;
  1768. CheckMenuItem(hMenu,ID_VIEWER_PP_DB,ppsteps & aiProcess_Debone ? MF_CHECKED : MF_UNCHECKED);
  1769. UpdatePPSettings();
  1770. }
  1771. else if (ID_VIEWER_PP_VDS == LOWORD(wParam)) {
  1772. ppsteps ^= aiProcess_ValidateDataStructure;
  1773. CheckMenuItem(hMenu,ID_VIEWER_PP_VDS,ppsteps & aiProcess_ValidateDataStructure ? MF_CHECKED : MF_UNCHECKED);
  1774. UpdatePPSettings();
  1775. }
  1776. else if (ID_VIEWER_RELOAD == LOWORD(wParam))
  1777. {
  1778. DeleteAsset();
  1779. LoadAsset();
  1780. }
  1781. else if (ID_IMPORTSETTINGS_RESETTODEFAULT == LOWORD(wParam))
  1782. {
  1783. ppsteps = ppstepsdefault;
  1784. UpdatePPSettings();
  1785. SetupPPUIState();
  1786. }
  1787. else if (ID_IMPORTSETTINGS_OPENPOST == LOWORD(wParam))
  1788. {
  1789. ShellExecute(NULL,"open","http://assimp.sourceforge.net/lib_html/ai_post_process_8h.html","","",SW_SHOW);
  1790. }
  1791. else if (ID_TOOLS_ORIGINALNORMALS == LOWORD(wParam))
  1792. {
  1793. if (g_pcAsset && g_pcAsset->pcScene)
  1794. {
  1795. g_pcAsset->SetNormalSet(AssimpView::AssetHelper::ORIGINAL);
  1796. CheckMenuItem(hMenu,ID_TOOLS_ORIGINALNORMALS,MF_BYCOMMAND | MF_CHECKED);
  1797. CheckMenuItem(hMenu,ID_TOOLS_HARDNORMALS,MF_BYCOMMAND | MF_UNCHECKED);
  1798. CheckMenuItem(hMenu,ID_TOOLS_SMOOTHNORMALS,MF_BYCOMMAND | MF_UNCHECKED);
  1799. }
  1800. }
  1801. else if (ID_TOOLS_SMOOTHNORMALS == LOWORD(wParam))
  1802. {
  1803. if (g_pcAsset && g_pcAsset->pcScene)
  1804. {
  1805. g_pcAsset->SetNormalSet(AssimpView::AssetHelper::SMOOTH);
  1806. CheckMenuItem(hMenu,ID_TOOLS_ORIGINALNORMALS,MF_BYCOMMAND | MF_UNCHECKED);
  1807. CheckMenuItem(hMenu,ID_TOOLS_HARDNORMALS,MF_BYCOMMAND | MF_UNCHECKED);
  1808. CheckMenuItem(hMenu,ID_TOOLS_SMOOTHNORMALS,MF_BYCOMMAND | MF_CHECKED);
  1809. }
  1810. }
  1811. else if (ID_TOOLS_HARDNORMALS == LOWORD(wParam))
  1812. {
  1813. if (g_pcAsset && g_pcAsset->pcScene)
  1814. {
  1815. g_pcAsset->SetNormalSet(AssimpView::AssetHelper::HARD);
  1816. CheckMenuItem(hMenu,ID_TOOLS_ORIGINALNORMALS,MF_BYCOMMAND | MF_UNCHECKED);
  1817. CheckMenuItem(hMenu,ID_TOOLS_HARDNORMALS,MF_BYCOMMAND | MF_CHECKED);
  1818. CheckMenuItem(hMenu,ID_TOOLS_SMOOTHNORMALS,MF_BYCOMMAND | MF_UNCHECKED);
  1819. }
  1820. }
  1821. else if (ID_TOOLS_STEREOVIEW == LOWORD(wParam))
  1822. {
  1823. g_sOptions.bStereoView =! g_sOptions.bStereoView;
  1824. HMENU hMenu = GetMenu(g_hDlg);
  1825. if (g_sOptions.bStereoView)
  1826. {
  1827. ModifyMenu(hMenu,ID_TOOLS_STEREOVIEW,
  1828. MF_BYCOMMAND | MF_CHECKED | MF_STRING,ID_TOOLS_STEREOVIEW,"Stereo view");
  1829. CLogDisplay::Instance().AddEntry("[INFO] Switched to stereo mode",
  1830. D3DCOLOR_ARGB(0xFF,0xFF,0xFF,0));
  1831. }
  1832. else
  1833. {
  1834. ModifyMenu(hMenu,ID_TOOLS_STEREOVIEW,
  1835. MF_BYCOMMAND | MF_UNCHECKED | MF_STRING,ID_TOOLS_STEREOVIEW,"Stereo view");
  1836. CLogDisplay::Instance().AddEntry("[INFO] Switched to mono mode",
  1837. D3DCOLOR_ARGB(0xFF,0xFF,0xFF,0));
  1838. }
  1839. }
  1840. else if (ID_TOOLS_SETANGLELIMIT == LOWORD(wParam))
  1841. {
  1842. DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_DIALOGSMOOTH),g_hDlg,&SMMessageProc);
  1843. }
  1844. else if (ID_VIEWER_CLEARHISTORY == LOWORD(wParam))
  1845. {
  1846. ClearHistory();
  1847. }
  1848. else if (ID_VIEWER_CLOSEASSET == LOWORD(wParam))
  1849. {
  1850. DeleteAssetData();
  1851. DeleteAsset();
  1852. }
  1853. else if (BN_CLICKED == HIWORD(wParam))
  1854. {
  1855. if (IDC_TOGGLEMS == LOWORD(wParam))
  1856. {
  1857. ToggleMS();
  1858. }
  1859. else if (IDC_TOGGLEMAT == LOWORD(wParam))
  1860. {
  1861. ToggleMats();
  1862. }
  1863. else if (IDC_LCOLOR1 == LOWORD(wParam))
  1864. {
  1865. if (CDisplay::VIEWMODE_TEXTURE == CDisplay::Instance().GetViewMode() ||
  1866. CDisplay::VIEWMODE_MATERIAL == CDisplay::Instance().GetViewMode())
  1867. {
  1868. // hey, I'm tired and yes, I KNOW IT IS EVIL!
  1869. DisplayColorDialog(const_cast<D3DXVECTOR4*>(CDisplay::Instance().GetFirstCheckerColor()));
  1870. SaveCheckerPatternColors();
  1871. }
  1872. else
  1873. {
  1874. DisplayColorDialog(&g_avLightColors[0]);
  1875. SaveLightColors();
  1876. }
  1877. InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR1),NULL,TRUE);
  1878. UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR1));
  1879. }
  1880. else if (IDC_LCOLOR2 == LOWORD(wParam))
  1881. {
  1882. if (CDisplay::VIEWMODE_TEXTURE == CDisplay::Instance().GetViewMode() ||
  1883. CDisplay::VIEWMODE_MATERIAL == CDisplay::Instance().GetViewMode())
  1884. {
  1885. // hey, I'm tired and yes, I KNOW IT IS EVIL!
  1886. DisplayColorDialog(const_cast<D3DXVECTOR4*>(CDisplay::Instance().GetSecondCheckerColor()));
  1887. SaveCheckerPatternColors();
  1888. }
  1889. else
  1890. {
  1891. DisplayColorDialog(&g_avLightColors[1]);
  1892. SaveLightColors();
  1893. }
  1894. InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR2),NULL,TRUE);
  1895. UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR2));
  1896. }
  1897. else if (IDC_LCOLOR3 == LOWORD(wParam))
  1898. {
  1899. DisplayColorDialog(&g_avLightColors[2]);
  1900. InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR3),NULL,TRUE);
  1901. UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR3));
  1902. SaveLightColors();
  1903. }
  1904. else if (IDC_LRESET == LOWORD(wParam))
  1905. {
  1906. if (CDisplay::VIEWMODE_TEXTURE == CDisplay::Instance().GetViewMode() ||
  1907. CDisplay::VIEWMODE_MATERIAL == CDisplay::Instance().GetViewMode())
  1908. {
  1909. CDisplay::Instance().SetFirstCheckerColor(D3DXVECTOR4(0.4f,0.4f,0.4f,1.0f));
  1910. CDisplay::Instance().SetSecondCheckerColor(D3DXVECTOR4(0.6f,0.6f,0.6f,1.0f));
  1911. SaveCheckerPatternColors();
  1912. }
  1913. else
  1914. {
  1915. g_avLightColors[0] = D3DCOLOR_ARGB(0xFF,0xFF,0xFF,0xFF);
  1916. g_avLightColors[1] = D3DCOLOR_ARGB(0xFF,0xFF,0x00,0x00);
  1917. g_avLightColors[2] = D3DCOLOR_ARGB(0xFF,0x05,0x05,0x05);
  1918. SaveLightColors();
  1919. }
  1920. InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR1),NULL,TRUE);
  1921. UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR1));
  1922. InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR2),NULL,TRUE);
  1923. UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR2));
  1924. InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR3),NULL,TRUE);
  1925. UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR3));
  1926. }
  1927. else if (IDC_NOSPECULAR == LOWORD(wParam))
  1928. {
  1929. ToggleSpecular();
  1930. }
  1931. else if (IDC_NOAB == LOWORD(wParam))
  1932. {
  1933. ToggleTransparency();
  1934. }
  1935. else if (IDC_ZOOM == LOWORD(wParam))
  1936. {
  1937. ToggleFPSView();
  1938. }
  1939. else if (IDC_BLUBB == LOWORD(wParam))
  1940. {
  1941. ToggleUIState();
  1942. }
  1943. else if (IDC_TOGGLENORMALS == LOWORD(wParam))
  1944. {
  1945. ToggleNormals();
  1946. }
  1947. else if (IDC_LOWQUALITY == LOWORD(wParam))
  1948. {
  1949. ToggleLowQuality();
  1950. }
  1951. else if (IDC_3LIGHTS == LOWORD(wParam))
  1952. {
  1953. ToggleMultipleLights();
  1954. }
  1955. else if (IDC_LIGHTROTATE == LOWORD(wParam))
  1956. {
  1957. ToggleLightRotate();
  1958. }
  1959. else if (IDC_AUTOROTATE == LOWORD(wParam))
  1960. {
  1961. ToggleAutoRotate();
  1962. }
  1963. else if (IDC_TOGGLEWIRE == LOWORD(wParam))
  1964. {
  1965. ToggleWireFrame();
  1966. }
  1967. else if (IDC_SHOWSKELETON == LOWORD(wParam))
  1968. {
  1969. ToggleSkeleton();
  1970. }
  1971. else if (IDC_BFCULL == LOWORD(wParam))
  1972. {
  1973. ToggleCulling();
  1974. }
  1975. else if (IDC_PLAY == LOWORD(wParam))
  1976. {
  1977. g_bPlay = !g_bPlay;
  1978. SetDlgItemText(g_hDlg,IDC_PLAY,(g_bPlay ? "Stop" : "Play"));
  1979. if (g_bPlay)
  1980. EnableWindow(GetDlgItem(g_hDlg,IDC_SLIDERANIM),FALSE);
  1981. else EnableWindow(GetDlgItem(g_hDlg,IDC_SLIDERANIM),TRUE);
  1982. }
  1983. }
  1984. // check the file history
  1985. for (unsigned int i = 0; i < AI_VIEW_NUM_RECENT_FILES;++i)
  1986. {
  1987. if (AI_VIEW_RECENT_FILE_ID(i) == LOWORD(wParam))
  1988. {
  1989. strcpy(g_szFileName,g_aPreviousFiles[i].c_str());
  1990. DeleteAssetData();
  1991. DeleteAsset();
  1992. LoadAsset();
  1993. // update and safe the history
  1994. UpdateHistory();
  1995. SaveHistory();
  1996. }
  1997. }
  1998. #ifndef ASSIMP_BUILD_NO_EXPORT
  1999. if (LOWORD(wParam) >= AI_VIEW_EXPORT_FMT_BASE && LOWORD(wParam) < AI_VIEW_EXPORT_FMT_BASE+Assimp::Exporter().GetExportFormatCount()) {
  2000. DoExport(LOWORD(wParam) - AI_VIEW_EXPORT_FMT_BASE);
  2001. }
  2002. #endif
  2003. // handle popup menus for the tree window
  2004. CDisplay::Instance().HandleTreeViewPopup(wParam,lParam);
  2005. return TRUE;
  2006. };
  2007. return FALSE;
  2008. }
  2009. //-------------------------------------------------------------------------------
  2010. // Message prcoedure for the progress dialog
  2011. //-------------------------------------------------------------------------------
  2012. INT_PTR CALLBACK ProgressMessageProc(HWND hwndDlg,UINT uMsg,
  2013. WPARAM wParam,LPARAM lParam)
  2014. {
  2015. UNREFERENCED_PARAMETER(lParam);
  2016. switch (uMsg)
  2017. {
  2018. case WM_INITDIALOG:
  2019. SendDlgItemMessage(hwndDlg,IDC_PROGRESS,PBM_SETRANGE,0,
  2020. MAKELPARAM(0,500));
  2021. SetTimer(hwndDlg,0,40,NULL);
  2022. return TRUE;
  2023. case WM_CLOSE:
  2024. EndDialog(hwndDlg,0);
  2025. return TRUE;
  2026. case WM_COMMAND:
  2027. if (IDOK == LOWORD(wParam))
  2028. {
  2029. #if 0
  2030. g_bLoadingCanceled = true;
  2031. TerminateThread(g_hThreadHandle,5);
  2032. g_pcAsset = NULL;
  2033. EndDialog(hwndDlg,0);
  2034. #endif
  2035. // PROBLEM: If we terminate the loader thread, ASSIMP's state
  2036. // is undefined. Any further attempts to load assets will
  2037. // fail.
  2038. exit(5);
  2039. // return TRUE;
  2040. }
  2041. case WM_TIMER:
  2042. UINT iPos = (UINT)SendDlgItemMessage(hwndDlg,IDC_PROGRESS,PBM_GETPOS,0,0);
  2043. iPos += 10;
  2044. if (iPos > 490)iPos = 0;
  2045. SendDlgItemMessage(hwndDlg,IDC_PROGRESS,PBM_SETPOS,iPos,0);
  2046. if (g_bLoadingFinished)
  2047. {
  2048. EndDialog(hwndDlg,0);
  2049. return TRUE;
  2050. }
  2051. return TRUE;
  2052. }
  2053. return FALSE;
  2054. }
  2055. //-------------------------------------------------------------------------------
  2056. // Message procedure for the about dialog
  2057. //-------------------------------------------------------------------------------
  2058. INT_PTR CALLBACK AboutMessageProc(HWND hwndDlg,UINT uMsg,
  2059. WPARAM wParam,LPARAM lParam)
  2060. {
  2061. UNREFERENCED_PARAMETER(lParam);
  2062. switch (uMsg)
  2063. {
  2064. case WM_CLOSE:
  2065. EndDialog(hwndDlg,0);
  2066. return TRUE;
  2067. case WM_COMMAND:
  2068. if (IDOK == LOWORD(wParam))
  2069. {
  2070. EndDialog(hwndDlg,0);
  2071. return TRUE;
  2072. }
  2073. }
  2074. return FALSE;
  2075. }
  2076. };
  2077. using namespace AssimpView;
  2078. //-------------------------------------------------------------------------------
  2079. // Entry point to the application
  2080. //-------------------------------------------------------------------------------
  2081. int APIENTRY _tWinMain(HINSTANCE hInstance,
  2082. HINSTANCE hPrevInstance,
  2083. LPTSTR lpCmdLine,
  2084. int nCmdShow)
  2085. {
  2086. UNREFERENCED_PARAMETER(hPrevInstance);
  2087. UNREFERENCED_PARAMETER(lpCmdLine);
  2088. // needed for the RichEdit control in the about/help dialog
  2089. LoadLibrary( "riched20.dll" );
  2090. // load windows common controls library to get XP style
  2091. InitCommonControls();
  2092. // intiailize the IDirect3D9 interface
  2093. g_hInstance = hInstance;
  2094. if (0 == InitD3D())
  2095. {
  2096. MessageBox(NULL,"Failed to initialize Direct3D 9",
  2097. "ASSIMP ModelViewer",MB_OK);
  2098. return -6;
  2099. }
  2100. // create the main dialog
  2101. HWND hDlg = CreateDialog(hInstance,MAKEINTRESOURCE(IDD_DIALOGMAIN),
  2102. NULL,&MessageProc);
  2103. // ensure we get high priority
  2104. ::SetPriorityClass(GetCurrentProcess(),HIGH_PRIORITY_CLASS);
  2105. // initialize the default logger if necessary
  2106. Assimp::DefaultLogger::create("",Assimp::Logger::VERBOSE);
  2107. CLogWindow::Instance().pcStream = new CMyLogStream();
  2108. Assimp::DefaultLogger::get()->attachStream(CLogWindow::Instance().pcStream,
  2109. Assimp::DefaultLogger::Debugging | Assimp::DefaultLogger::Info |
  2110. Assimp::DefaultLogger::Err | Assimp::DefaultLogger::Warn);
  2111. if (NULL == hDlg)
  2112. {
  2113. MessageBox(NULL,"Failed to create dialog from resource",
  2114. "ASSIMP ModelViewer",MB_OK);
  2115. return -5;
  2116. }
  2117. // display the window
  2118. g_hDlg = hDlg;
  2119. MSG uMsg;
  2120. memset(&uMsg,0,sizeof( MSG));
  2121. ShowWindow( hDlg, nCmdShow );
  2122. UpdateWindow( hDlg );
  2123. // create the D3D device object
  2124. if (0 == CreateDevice(g_sOptions.bMultiSample,false,true))
  2125. {
  2126. MessageBox(NULL,"Failed to initialize Direct3D 9 (2)",
  2127. "ASSIMP ModelViewer",MB_OK);
  2128. return -4;
  2129. }
  2130. CLogDisplay::Instance().AddEntry("[OK] Here we go!");
  2131. // create the log window
  2132. CLogWindow::Instance().Init();
  2133. // set the focus to the main window
  2134. SetFocus(g_hDlg);
  2135. // recover background skyboxes/textures from the last session
  2136. HKEY g_hRegistry;
  2137. union
  2138. {
  2139. char szFileName[MAX_PATH];
  2140. D3DCOLOR clrColor;
  2141. };
  2142. DWORD dwTemp = MAX_PATH;
  2143. RegCreateKeyEx(HKEY_CURRENT_USER,
  2144. "Software\\ASSIMP\\Viewer",0,NULL,0,KEY_ALL_ACCESS, NULL, &g_hRegistry,NULL);
  2145. if(ERROR_SUCCESS == RegQueryValueEx(g_hRegistry,"LastSkyBoxSrc",NULL,NULL,
  2146. (BYTE*)szFileName,&dwTemp) && '\0' != szFileName[0])
  2147. {
  2148. CBackgroundPainter::Instance().SetCubeMapBG(szFileName);
  2149. }
  2150. else if(ERROR_SUCCESS == RegQueryValueEx(g_hRegistry,"LastTextureSrc",NULL,NULL,
  2151. (BYTE*)szFileName,&dwTemp) && '\0' != szFileName[0])
  2152. {
  2153. CBackgroundPainter::Instance().SetTextureBG(szFileName);
  2154. }
  2155. else if(ERROR_SUCCESS == RegQueryValueEx(g_hRegistry,"Color",NULL,NULL,
  2156. (BYTE*)&clrColor,&dwTemp))
  2157. {
  2158. CBackgroundPainter::Instance().SetColor(clrColor);
  2159. }
  2160. RegCloseKey(g_hRegistry);
  2161. // now handle command line arguments
  2162. HandleCommandLine(lpCmdLine);
  2163. double adLast[30];
  2164. for (int i = 0; i < 30;++i)adLast[i] = 0.0f;
  2165. int iCurrent = 0;
  2166. double g_dCurTime = 0;
  2167. double g_dLastTime = 0;
  2168. while( uMsg.message != WM_QUIT )
  2169. {
  2170. if( PeekMessage( &uMsg, NULL, 0, 0, PM_REMOVE ) )
  2171. {
  2172. TranslateMessage( &uMsg );
  2173. DispatchMessage( &uMsg );
  2174. if (WM_CHAR == uMsg.message)
  2175. {
  2176. switch ((char)uMsg.wParam)
  2177. {
  2178. case 'M':
  2179. case 'm':
  2180. CheckDlgButton(g_hDlg,IDC_TOGGLEMS,
  2181. IsDlgButtonChecked(g_hDlg,IDC_TOGGLEMS) == BST_CHECKED
  2182. ? BST_UNCHECKED : BST_CHECKED);
  2183. ToggleMS();
  2184. break;
  2185. case 'L':
  2186. case 'l':
  2187. CheckDlgButton(g_hDlg,IDC_3LIGHTS,
  2188. IsDlgButtonChecked(g_hDlg,IDC_3LIGHTS) == BST_CHECKED
  2189. ? BST_UNCHECKED : BST_CHECKED);
  2190. ToggleMultipleLights();
  2191. break;
  2192. case 'P':
  2193. case 'p':
  2194. CheckDlgButton(g_hDlg,IDC_LOWQUALITY,
  2195. IsDlgButtonChecked(g_hDlg,IDC_LOWQUALITY) == BST_CHECKED
  2196. ? BST_UNCHECKED : BST_CHECKED);
  2197. ToggleLowQuality();
  2198. break;
  2199. case 'D':
  2200. case 'd':
  2201. CheckDlgButton(g_hDlg,IDC_TOGGLEMAT,
  2202. IsDlgButtonChecked(g_hDlg,IDC_TOGGLEMAT) == BST_CHECKED
  2203. ? BST_UNCHECKED : BST_CHECKED);
  2204. ToggleMats();
  2205. break;
  2206. case 'N':
  2207. case 'n':
  2208. CheckDlgButton(g_hDlg,IDC_TOGGLENORMALS,
  2209. IsDlgButtonChecked(g_hDlg,IDC_TOGGLENORMALS) == BST_CHECKED
  2210. ? BST_UNCHECKED : BST_CHECKED);
  2211. ToggleNormals();
  2212. break;
  2213. case 'S':
  2214. case 's':
  2215. CheckDlgButton(g_hDlg,IDC_NOSPECULAR,
  2216. IsDlgButtonChecked(g_hDlg,IDC_NOSPECULAR) == BST_CHECKED
  2217. ? BST_UNCHECKED : BST_CHECKED);
  2218. ToggleSpecular();
  2219. break;
  2220. case 'A':
  2221. case 'a':
  2222. CheckDlgButton(g_hDlg,IDC_AUTOROTATE,
  2223. IsDlgButtonChecked(g_hDlg,IDC_AUTOROTATE) == BST_CHECKED
  2224. ? BST_UNCHECKED : BST_CHECKED);
  2225. ToggleAutoRotate();
  2226. break;
  2227. case 'R':
  2228. case 'r':
  2229. CheckDlgButton(g_hDlg,IDC_LIGHTROTATE,
  2230. IsDlgButtonChecked(g_hDlg,IDC_LIGHTROTATE) == BST_CHECKED
  2231. ? BST_UNCHECKED : BST_CHECKED);
  2232. ToggleLightRotate();
  2233. break;
  2234. case 'Z':
  2235. case 'z':
  2236. CheckDlgButton(g_hDlg,IDC_ZOOM,
  2237. IsDlgButtonChecked(g_hDlg,IDC_ZOOM) == BST_CHECKED
  2238. ? BST_UNCHECKED : BST_CHECKED);
  2239. ToggleFPSView();
  2240. break;
  2241. case 'W':
  2242. case 'w':
  2243. CheckDlgButton(g_hDlg,IDC_TOGGLEWIRE,
  2244. IsDlgButtonChecked(g_hDlg,IDC_TOGGLEWIRE) == BST_CHECKED
  2245. ? BST_UNCHECKED : BST_CHECKED);
  2246. ToggleWireFrame();
  2247. break;
  2248. case 'K':
  2249. case 'k':
  2250. CheckDlgButton(g_hDlg,IDC_SHOWSKELETON,
  2251. IsDlgButtonChecked(g_hDlg,IDC_SHOWSKELETON) == BST_CHECKED
  2252. ? BST_UNCHECKED : BST_CHECKED);
  2253. ToggleSkeleton();
  2254. break;
  2255. case 'C':
  2256. case 'c':
  2257. CheckDlgButton(g_hDlg,IDC_BFCULL,
  2258. IsDlgButtonChecked(g_hDlg,IDC_BFCULL) == BST_CHECKED
  2259. ? BST_UNCHECKED : BST_CHECKED);
  2260. ToggleCulling();
  2261. break;
  2262. case 'T':
  2263. case 't':
  2264. CheckDlgButton(g_hDlg,IDC_NOAB,
  2265. IsDlgButtonChecked(g_hDlg,IDC_NOAB) == BST_CHECKED
  2266. ? BST_UNCHECKED : BST_CHECKED);
  2267. ToggleTransparency();
  2268. break;
  2269. }
  2270. }
  2271. }
  2272. // render the scene
  2273. CDisplay::Instance().OnRender();
  2274. // measure FPS, average it out
  2275. g_dCurTime = timeGetTime();
  2276. g_fElpasedTime = (float)((g_dCurTime - g_dLastTime) * 0.001);
  2277. g_dLastTime = g_dCurTime;
  2278. adLast[iCurrent++] = 1.0f / g_fElpasedTime;
  2279. double dFPS = 0.0;
  2280. for (int i = 0;i < 30;++i)
  2281. dFPS += adLast[i];
  2282. dFPS /= 30.0;
  2283. if (30 == iCurrent)
  2284. {
  2285. iCurrent = 0;
  2286. if (dFPS != g_fFPS)
  2287. {
  2288. g_fFPS = dFPS;
  2289. char szOut[256];
  2290. sprintf(szOut,"%i",(int)floorf((float)dFPS+0.5f));
  2291. SetDlgItemText(g_hDlg,IDC_EFPS,szOut);
  2292. }
  2293. }
  2294. }
  2295. DeleteAsset();
  2296. Assimp::DefaultLogger::kill();
  2297. ShutdownDevice();
  2298. ShutdownD3D();
  2299. return 0;
  2300. }