Display.cpp 66 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203
  1. /*
  2. ---------------------------------------------------------------------------
  3. Open Asset Import Library (ASSIMP)
  4. ---------------------------------------------------------------------------
  5. Copyright (c) 2006-2008, ASSIMP Development 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 Development 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 "stdafx.h"
  35. #include "assimp_view.h"
  36. namespace AssimpView {
  37. CDisplay CDisplay::s_cInstance;
  38. extern COLORREF g_aclCustomColors[16] /*= {0}*/;
  39. extern HKEY g_hRegistry;
  40. extern float g_fLoadTime;
  41. //-------------------------------------------------------------------------------
  42. // Table of colors used for normal vectors.
  43. //-------------------------------------------------------------------------------
  44. D3DXVECTOR4 g_aclNormalColors[14] =
  45. {
  46. D3DXVECTOR4(0xFF / 255.0f,0xFF / 255.0f,0xFF / 255.0f, 1.0f), // white
  47. D3DXVECTOR4(0xFF / 255.0f,0x00 / 255.0f,0x00 / 255.0f,1.0f), // red
  48. D3DXVECTOR4(0x00 / 255.0f,0xFF / 255.0f,0x00 / 255.0f,1.0f), // green
  49. D3DXVECTOR4(0x00 / 255.0f,0x00 / 255.0f,0xFF / 255.0f,1.0f), // blue
  50. D3DXVECTOR4(0xFF / 255.0f,0xFF / 255.0f,0x00 / 255.0f,1.0f), // yellow
  51. D3DXVECTOR4(0xFF / 255.0f,0x00 / 255.0f,0xFF / 255.0f,1.0f), // magenta
  52. D3DXVECTOR4(0x00 / 255.0f,0xFF / 255.0f,0xFF / 255.0f,1.0f), // wtf
  53. D3DXVECTOR4(0xFF / 255.0f,0x60 / 255.0f,0x60 / 255.0f,1.0f), // light red
  54. D3DXVECTOR4(0x60 / 255.0f,0xFF / 255.0f,0x60 / 255.0f,1.0f), // light green
  55. D3DXVECTOR4(0x60 / 255.0f,0x60 / 255.0f,0xFF / 255.0f,1.0f), // light blue
  56. D3DXVECTOR4(0xA0 / 255.0f,0x00 / 255.0f,0x00 / 255.0f,1.0f), // dark red
  57. D3DXVECTOR4(0x00 / 255.0f,0xA0 / 255.0f,0x00 / 255.0f,1.0f), // dark green
  58. D3DXVECTOR4(0x00 / 255.0f,0x00 / 255.0f,0xA0 / 255.0f,1.0f), // dark blue
  59. D3DXVECTOR4(0x88 / 255.0f,0x88 / 255.0f,0x88 / 255.0f, 1.0f) // gray
  60. };
  61. //-------------------------------------------------------------------------------
  62. // Recursivly count the number of nodes in an asset's node graph
  63. // Used by LoadAsset()
  64. //-------------------------------------------------------------------------------
  65. void GetNodeCount(aiNode* pcNode, unsigned int* piCnt)
  66. {
  67. *piCnt = *piCnt+1;
  68. for (unsigned int i = 0; i < pcNode->mNumChildren;++i)
  69. GetNodeCount(pcNode->mChildren[i],piCnt);
  70. }
  71. //-------------------------------------------------------------------------------
  72. int CDisplay::FillAnimList(void)
  73. {
  74. if (0 == g_pcAsset->pcScene->mNumAnimations)
  75. {
  76. // disable all UI components related to animations
  77. EnableWindow(GetDlgItem(g_hDlg,IDC_PLAYANIM),FALSE);
  78. EnableWindow(GetDlgItem(g_hDlg,IDC_SPEED),FALSE);
  79. EnableWindow(GetDlgItem(g_hDlg,IDC_PINORDER),FALSE);
  80. EnableWindow(GetDlgItem(g_hDlg,IDC_SSPEED),FALSE);
  81. EnableWindow(GetDlgItem(g_hDlg,IDC_SANIMGB),FALSE);
  82. EnableWindow(GetDlgItem(g_hDlg,IDC_SANIM),FALSE);
  83. EnableWindow(GetDlgItem(g_hDlg,IDC_COMBO1),FALSE);
  84. }
  85. else
  86. {
  87. // reenable all animation components if they have been
  88. // disabled for a previous mesh
  89. EnableWindow(GetDlgItem(g_hDlg,IDC_PLAYANIM),TRUE);
  90. EnableWindow(GetDlgItem(g_hDlg,IDC_SPEED),TRUE);
  91. EnableWindow(GetDlgItem(g_hDlg,IDC_PINORDER),TRUE);
  92. EnableWindow(GetDlgItem(g_hDlg,IDC_SSPEED),TRUE);
  93. EnableWindow(GetDlgItem(g_hDlg,IDC_SANIMGB),TRUE);
  94. EnableWindow(GetDlgItem(g_hDlg,IDC_SANIM),TRUE);
  95. EnableWindow(GetDlgItem(g_hDlg,IDC_COMBO1),TRUE);
  96. // now fill in all animation names
  97. for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumAnimations;++i)
  98. {
  99. SendDlgItemMessage(g_hDlg,IDC_COMBO1,CB_ADDSTRING,0,
  100. ( LPARAM ) g_pcAsset->pcScene->mAnimations[i]->mName.data);
  101. }
  102. }
  103. return 1;
  104. }
  105. //-------------------------------------------------------------------------------
  106. int CDisplay::ClearAnimList(void)
  107. {
  108. // clear the combo box
  109. SendDlgItemMessage(g_hDlg,IDC_COMBO1,CB_RESETCONTENT,0,0);
  110. return 1;
  111. }
  112. //-------------------------------------------------------------------------------
  113. int CDisplay::ClearDisplayList(void)
  114. {
  115. // clear the combo box
  116. TreeView_DeleteAllItems(GetDlgItem(g_hDlg,IDC_TREE1));
  117. this->Reset();
  118. return 1;
  119. }
  120. //-------------------------------------------------------------------------------
  121. int CDisplay::AddNodeToDisplayList(
  122. unsigned int iIndex,
  123. unsigned int iDepth,
  124. aiNode* pcNode,
  125. HTREEITEM hRoot)
  126. {
  127. ai_assert(NULL != pcNode);
  128. ai_assert(NULL != hRoot);
  129. char chTemp[512];
  130. if(0 == pcNode->mName.length)
  131. {
  132. if (iIndex >= 100)
  133. {
  134. iIndex += iDepth * 1000;
  135. }
  136. else if (iIndex >= 10)
  137. {
  138. iIndex += iDepth * 100;
  139. }
  140. else iIndex += iDepth * 10;
  141. sprintf(chTemp,"Node %i",iIndex);
  142. }
  143. else strcpy(chTemp,pcNode->mName.data);
  144. TVITEMEX tvi;
  145. TVINSERTSTRUCT sNew;
  146. tvi.pszText = chTemp;
  147. tvi.cchTextMax = (int)strlen(chTemp);
  148. tvi.mask = TVIF_TEXT | TVIF_SELECTEDIMAGE | TVIF_IMAGE | TVIF_HANDLE | TVIF_PARAM;
  149. tvi.iImage = this->m_aiImageList[AI_VIEW_IMGLIST_NODE];
  150. tvi.iSelectedImage = this->m_aiImageList[AI_VIEW_IMGLIST_NODE];
  151. tvi.lParam = (LPARAM)5;
  152. sNew.itemex = tvi;
  153. sNew.hInsertAfter = TVI_LAST;
  154. sNew.hParent = hRoot;
  155. // add the item to the list
  156. HTREEITEM hTexture = (HTREEITEM)SendMessage(GetDlgItem(g_hDlg,IDC_TREE1),
  157. TVM_INSERTITEM,
  158. 0,
  159. (LPARAM)(LPTVINSERTSTRUCT)&sNew);
  160. // recursively add all child nodes
  161. ++iDepth;
  162. for (unsigned int i = 0; i< pcNode->mNumChildren;++i)
  163. {
  164. AddNodeToDisplayList(i,iDepth,pcNode->mChildren[i],hTexture);
  165. }
  166. // add the node to the list
  167. NodeInfo info;
  168. info.hTreeItem = hTexture;
  169. info.psNode = pcNode;
  170. this->AddNode(info);
  171. return 1;
  172. }
  173. //-------------------------------------------------------------------------------
  174. int CDisplay::ReplaceCurrentTexture(const char* szPath)
  175. {
  176. ai_assert(NULL != szPath);
  177. // well ... try to load it
  178. IDirect3DTexture9* piTexture = NULL;
  179. aiString szString;
  180. strcpy(szString.data,szPath);
  181. szString.length = strlen(szPath);
  182. CMaterialManager::Instance().LoadTexture(&piTexture,&szString);
  183. if (!piTexture)
  184. {
  185. CLogDisplay::Instance().AddEntry("[ERROR] Unable to load this texture",
  186. D3DCOLOR_ARGB(0xFF,0xFF,0x0,0x0));
  187. return 0;
  188. }
  189. // we must also change the icon of the corresponding tree
  190. // view item if the default texture was previously set
  191. TVITEMEX tvi;
  192. tvi.mask = TVIF_SELECTEDIMAGE | TVIF_IMAGE;
  193. tvi.iImage = this->m_aiImageList[AI_VIEW_IMGLIST_MATERIAL];
  194. tvi.iSelectedImage = this->m_aiImageList[AI_VIEW_IMGLIST_MATERIAL];
  195. TreeView_SetItem(GetDlgItem(g_hDlg,IDC_TREE1),
  196. this->m_pcCurrentTexture->hTreeItem);
  197. // change this in the old aiMaterial structure, too
  198. Assimp::MaterialHelper* pcMat = (Assimp::MaterialHelper*)
  199. g_pcAsset->pcScene->mMaterials[this->m_pcCurrentTexture->iMatIndex];
  200. // update all meshes referencing this material
  201. for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
  202. {
  203. if (this->m_pcCurrentTexture->iMatIndex != g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex)
  204. continue;
  205. AssetHelper::MeshHelper* pcMesh = g_pcAsset->apcMeshes[i];
  206. switch (this->m_pcCurrentTexture->iType)
  207. {
  208. case AI_TEXTYPE_DIFFUSE:
  209. if (pcMesh->piDiffuseTexture && pcMesh->piDiffuseTexture != piTexture)
  210. {
  211. pcMesh->piDiffuseTexture->Release();
  212. pcMesh->piDiffuseTexture = piTexture;
  213. this->m_pcCurrentTexture->piTexture = &pcMesh->piDiffuseTexture;
  214. if (!pcMesh->bSharedFX)
  215. {
  216. pcMesh->piEffect->SetTexture("DIFFUSE_TEXTURE",piTexture);
  217. }
  218. }
  219. break;
  220. case AI_TEXTYPE_AMBIENT:
  221. if (pcMesh->piAmbientTexture && pcMesh->piAmbientTexture != piTexture)
  222. {
  223. pcMesh->piAmbientTexture->Release();
  224. pcMesh->piAmbientTexture = piTexture;
  225. this->m_pcCurrentTexture->piTexture = &pcMesh->piAmbientTexture;
  226. if (!pcMesh->bSharedFX)
  227. {
  228. pcMesh->piEffect->SetTexture("AMBIENT_TEXTURE",piTexture);
  229. }
  230. }
  231. break;
  232. case AI_TEXTYPE_SPECULAR:
  233. if (pcMesh->piSpecularTexture && pcMesh->piSpecularTexture != piTexture)
  234. {
  235. pcMesh->piSpecularTexture->Release();
  236. pcMesh->piSpecularTexture = piTexture;
  237. this->m_pcCurrentTexture->piTexture = &pcMesh->piSpecularTexture;
  238. if (!pcMesh->bSharedFX)
  239. {
  240. pcMesh->piEffect->SetTexture("SPECULAR_TEXTURE",piTexture);
  241. }
  242. }
  243. break;
  244. case AI_TEXTYPE_EMISSIVE:
  245. if (pcMesh->piEmissiveTexture && pcMesh->piEmissiveTexture != piTexture)
  246. {
  247. pcMesh->piEmissiveTexture->Release();
  248. pcMesh->piEmissiveTexture = piTexture;
  249. this->m_pcCurrentTexture->piTexture = &pcMesh->piEmissiveTexture;
  250. if (!pcMesh->bSharedFX)
  251. {
  252. pcMesh->piEffect->SetTexture("EMISSIVE_TEXTURE",piTexture);
  253. }
  254. }
  255. break;
  256. case AI_TEXTYPE_SHININESS:
  257. if (pcMesh->piShininessTexture && pcMesh->piShininessTexture != piTexture)
  258. {
  259. pcMesh->piShininessTexture->Release();
  260. pcMesh->piShininessTexture = piTexture;
  261. this->m_pcCurrentTexture->piTexture = &pcMesh->piShininessTexture;
  262. if (!pcMesh->bSharedFX)
  263. {
  264. pcMesh->piEffect->SetTexture("SHININESS_TEXTURE",piTexture);
  265. }
  266. }
  267. break;
  268. case AI_TEXTYPE_NORMALS:
  269. case AI_TEXTYPE_HEIGHT:
  270. if (pcMesh->piNormalTexture && pcMesh->piNormalTexture != piTexture)
  271. {
  272. pcMesh->piNormalTexture->Release();
  273. pcMesh->piNormalTexture = piTexture;
  274. CMaterialManager::Instance().HMtoNMIfNecessary(pcMesh->piNormalTexture,
  275. &pcMesh->piNormalTexture,true);
  276. this->m_pcCurrentTexture->piTexture = &pcMesh->piNormalTexture;
  277. if (!pcMesh->bSharedFX)
  278. {
  279. pcMesh->piEffect->SetTexture("NORMAL_TEXTURE",piTexture);
  280. }
  281. }
  282. break;
  283. default: //case AI_TEXTYPE_OPACITY && case AI_TEXTYPE_OPACITY | 0x40000000:
  284. if (pcMesh->piOpacityTexture && pcMesh->piOpacityTexture != piTexture)
  285. {
  286. pcMesh->piOpacityTexture->Release();
  287. pcMesh->piOpacityTexture = piTexture;
  288. this->m_pcCurrentTexture->piTexture = &pcMesh->piOpacityTexture;
  289. if (!pcMesh->bSharedFX)
  290. {
  291. pcMesh->piEffect->SetTexture("OPACITY_TEXTURE",piTexture);
  292. }
  293. }
  294. break;
  295. };
  296. }
  297. // now update the material itself
  298. aiString szOld;
  299. const char* szKey = NULL;
  300. switch (this->m_pcCurrentTexture->iType)
  301. {
  302. case AI_TEXTYPE_DIFFUSE:
  303. szKey = AI_MATKEY_TEXTURE_DIFFUSE(0);
  304. break;
  305. case AI_TEXTYPE_AMBIENT:
  306. szKey = AI_MATKEY_TEXTURE_AMBIENT(0);
  307. break;
  308. case AI_TEXTYPE_SPECULAR:
  309. szKey = AI_MATKEY_TEXTURE_SPECULAR(0);
  310. break;
  311. case AI_TEXTYPE_EMISSIVE:
  312. szKey = AI_MATKEY_TEXTURE_EMISSIVE(0);
  313. break;
  314. case AI_TEXTYPE_NORMALS:
  315. szKey = AI_MATKEY_TEXTURE_NORMALS(0);
  316. break;
  317. case AI_TEXTYPE_HEIGHT:
  318. szKey = AI_MATKEY_TEXTURE_HEIGHT(0);
  319. break;
  320. case AI_TEXTYPE_SHININESS:
  321. szKey = AI_MATKEY_TEXTURE_SHININESS(0);
  322. break;
  323. default: //case AI_TEXTYPE_OPACITY && case AI_TEXTYPE_OPACITY | 0x40000000:
  324. szKey = AI_MATKEY_TEXTURE_OPACITY(0);
  325. break;
  326. };
  327. ai_assert(NULL != szKey);
  328. aiGetMaterialString(pcMat,szKey,&szOld);
  329. pcMat->AddProperty(&szString,szKey);
  330. char szBuffer[512];
  331. sprintf(szBuffer,"%s%s",szKey,"_old");
  332. if (AI_SUCCESS != aiGetMaterialString(pcMat, szBuffer, &szOld))
  333. {
  334. pcMat->AddProperty(&szOld,szBuffer );
  335. }
  336. else if (szString.length == szOld.length &&
  337. 0 == Assimp::ASSIMP_stricmp(szString.data,szOld.data))
  338. {
  339. pcMat->RemoveProperty(szBuffer);
  340. }
  341. return 1;
  342. }
  343. //-------------------------------------------------------------------------------
  344. int CDisplay::AddTextureToDisplayList(unsigned int iType,
  345. unsigned int iIndex,
  346. const aiString* szPath,
  347. HTREEITEM hFX,
  348. unsigned int iUVIndex /*= 0*/,
  349. const float fBlendFactor /*= 0.0f*/,
  350. aiTextureOp eTextureOp /*= aiTextureOp_Multiply*/,
  351. unsigned int iMesh /*= 0*/)
  352. {
  353. ai_assert(NULL != szPath);
  354. ai_assert(NULL != pcMat);
  355. char chTemp[512];
  356. char chTempEmb[256];
  357. const char* sz = strrchr(szPath->data,'\\');
  358. if (!sz)sz = strrchr(szPath->data,'/');
  359. if (!sz)
  360. {
  361. if ('*' == *szPath->data)
  362. {
  363. int iIndex = atoi(szPath->data+1);
  364. sprintf(chTempEmb,"Embedded #%i",iIndex);
  365. sz = chTempEmb;
  366. }
  367. else
  368. {
  369. sz = szPath->data;
  370. }
  371. }
  372. bool bIsExtraOpacity = 0 != (iType & 0x40000000);
  373. const char* szType;
  374. IDirect3DTexture9** piTexture;
  375. switch (iType)
  376. {
  377. case AI_TEXTYPE_DIFFUSE:
  378. piTexture = &g_pcAsset->apcMeshes[iMesh]->piDiffuseTexture;
  379. szType = "Diffuse";break;
  380. case AI_TEXTYPE_SPECULAR:
  381. piTexture = &g_pcAsset->apcMeshes[iMesh]->piSpecularTexture;
  382. szType = "Specular";break;
  383. case AI_TEXTYPE_AMBIENT:
  384. piTexture = &g_pcAsset->apcMeshes[iMesh]->piAmbientTexture;
  385. szType = "Ambient";break;
  386. case AI_TEXTYPE_EMISSIVE:
  387. piTexture = &g_pcAsset->apcMeshes[iMesh]->piEmissiveTexture;
  388. szType = "Emissive";break;
  389. case AI_TEXTYPE_HEIGHT:
  390. piTexture = &g_pcAsset->apcMeshes[iMesh]->piNormalTexture;
  391. szType = "HeightMap";break;
  392. case AI_TEXTYPE_NORMALS:
  393. piTexture = &g_pcAsset->apcMeshes[iMesh]->piNormalTexture;
  394. szType = "NormalMap";break;
  395. case AI_TEXTYPE_SHININESS:
  396. piTexture = &g_pcAsset->apcMeshes[iMesh]->piShininessTexture;
  397. szType = "Shininess";break;
  398. default: // opacity + opacity | mask
  399. piTexture = &g_pcAsset->apcMeshes[iMesh]->piOpacityTexture;
  400. szType = "Opacity";break;
  401. };
  402. if (bIsExtraOpacity)
  403. {
  404. sprintf(chTemp,"%s %i (<copy of diffuse #1>)",szType,iIndex+1);
  405. }
  406. else sprintf(chTemp,"%s %i (%s)",szType,iIndex+1,sz);
  407. TVITEMEX tvi;
  408. TVINSERTSTRUCT sNew;
  409. tvi.pszText = chTemp;
  410. tvi.cchTextMax = (int)strlen(chTemp);
  411. tvi.mask = TVIF_TEXT | TVIF_SELECTEDIMAGE | TVIF_IMAGE | TVIF_HANDLE | TVIF_HANDLE;
  412. tvi.lParam = (LPARAM)20;
  413. // find out whether this is the default texture or not
  414. if (piTexture)
  415. {
  416. // {9785DA94-1D96-426b-B3CB-BADC36347F5E}
  417. static const GUID guidPrivateData =
  418. { 0x9785da94, 0x1d96, 0x426b,
  419. { 0xb3, 0xcb, 0xba, 0xdc, 0x36, 0x34, 0x7f, 0x5e } };
  420. uint32_t iData = 0;
  421. DWORD dwSize = 4;
  422. (*piTexture)->GetPrivateData(guidPrivateData,&iData,&dwSize);
  423. if (0xFFFFFFFF == iData)
  424. {
  425. tvi.iImage = this->m_aiImageList[AI_VIEW_IMGLIST_TEXTURE_INVALID];
  426. tvi.iSelectedImage = this->m_aiImageList[AI_VIEW_IMGLIST_TEXTURE_INVALID];
  427. }
  428. else
  429. {
  430. tvi.iImage = this->m_aiImageList[AI_VIEW_IMGLIST_TEXTURE];
  431. tvi.iSelectedImage = this->m_aiImageList[AI_VIEW_IMGLIST_TEXTURE];
  432. }
  433. }
  434. else
  435. {
  436. tvi.iImage = this->m_aiImageList[AI_VIEW_IMGLIST_TEXTURE_INVALID];
  437. tvi.iSelectedImage = this->m_aiImageList[AI_VIEW_IMGLIST_TEXTURE_INVALID];
  438. }
  439. sNew.itemex = tvi;
  440. sNew.hInsertAfter = TVI_LAST;
  441. sNew.hParent = hFX;
  442. // add the item to the list
  443. HTREEITEM hTexture = (HTREEITEM)SendMessage(GetDlgItem(g_hDlg,IDC_TREE1),
  444. TVM_INSERTITEM,
  445. 0,
  446. (LPARAM)(LPTVINSERTSTRUCT)&sNew);
  447. // add it to the list
  448. CDisplay::TextureInfo sInfo;
  449. sInfo.iUV = iUVIndex;
  450. sInfo.fBlend = fBlendFactor;
  451. sInfo.eOp = eTextureOp;
  452. sInfo.szPath = szPath->data;
  453. sInfo.hTreeItem = hTexture;
  454. sInfo.piTexture = piTexture;
  455. sInfo.iType = iType;
  456. sInfo.iMatIndex = g_pcAsset->pcScene->mMeshes[iMesh]->mMaterialIndex;
  457. this->AddTexture(sInfo);
  458. return 1;
  459. }
  460. //-------------------------------------------------------------------------------
  461. int CDisplay::AddMaterialToDisplayList(HTREEITEM hRoot,
  462. unsigned int iIndex)
  463. {
  464. ai_assert(NULL != hRoot);
  465. aiMaterial* pcMat = g_pcAsset->pcScene->mMaterials[iIndex];
  466. // find the first mesh using this material index
  467. unsigned int iMesh = 0;
  468. for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
  469. {
  470. if (iIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex)
  471. {
  472. iMesh = i;
  473. break;
  474. }
  475. }
  476. // use the name of the material, if possible
  477. char chTemp[512];
  478. aiString szOut;
  479. if (AI_SUCCESS != aiGetMaterialString(pcMat,AI_MATKEY_NAME,&szOut))
  480. {
  481. sprintf(chTemp,"Material %i",iIndex+1);
  482. }
  483. else
  484. {
  485. sprintf(chTemp,"%s (%i)",szOut.data,iIndex+1);
  486. }
  487. TVITEMEX tvi;
  488. TVINSERTSTRUCT sNew;
  489. tvi.pszText = chTemp;
  490. tvi.cchTextMax = (int)strlen(chTemp);
  491. tvi.mask = TVIF_TEXT | TVIF_SELECTEDIMAGE | TVIF_IMAGE | TVIF_HANDLE | TVIF_PARAM ;
  492. tvi.iImage = this->m_aiImageList[AI_VIEW_IMGLIST_MATERIAL];
  493. tvi.iSelectedImage = this->m_aiImageList[AI_VIEW_IMGLIST_MATERIAL];
  494. tvi.lParam = (LPARAM)10;
  495. //tvi.state = TVIS_EXPANDED | TVIS_EXPANDEDONCE ;
  496. sNew.itemex = tvi;
  497. sNew.hInsertAfter = TVI_LAST;
  498. sNew.hParent = hRoot;
  499. // add the item to the list
  500. HTREEITEM hTexture = (HTREEITEM)SendMessage(GetDlgItem(g_hDlg,IDC_TREE1),
  501. TVM_INSERTITEM,
  502. 0,
  503. (LPARAM)(LPTVINSERTSTRUCT)&sNew);
  504. // for each texture in the list ... add it
  505. // NOTE: This expects that AI_TEXTYPE_DIFFUSE is 7
  506. ai_assert(7 == AI_TEXTYPE_DIFFUSE);
  507. unsigned int iUV;
  508. float fBlend;
  509. aiTextureOp eOp;
  510. aiString szPath;
  511. bool bNoOpacity = true;
  512. for (unsigned int i = 0; i < 8;++i)
  513. {
  514. unsigned int iNum = 0;
  515. while (true)
  516. {
  517. if (AI_SUCCESS != aiGetMaterialTexture(pcMat,iNum,i,
  518. &szPath,&iUV,&fBlend,&eOp))
  519. {
  520. break;
  521. }
  522. if (AI_TEXTYPE_OPACITY == i)bNoOpacity = false;
  523. AddTextureToDisplayList(i,iNum,&szPath,hTexture,iUV,fBlend,eOp,iMesh);
  524. ++iNum;
  525. }
  526. }
  527. AssetHelper::MeshHelper* pcMesh = g_pcAsset->apcMeshes[iMesh];
  528. if (pcMesh->piDiffuseTexture && pcMesh->piDiffuseTexture == pcMesh->piOpacityTexture && bNoOpacity)
  529. {
  530. // check whether the diffuse texture is not a default texture
  531. // {9785DA94-1D96-426b-B3CB-BADC36347F5E}
  532. static const GUID guidPrivateData =
  533. { 0x9785da94, 0x1d96, 0x426b,
  534. { 0xb3, 0xcb, 0xba, 0xdc, 0x36, 0x34, 0x7f, 0x5e } };
  535. uint32_t iData = 0;
  536. DWORD dwSize = 4;
  537. if(FAILED( pcMesh->piDiffuseTexture->GetPrivateData(guidPrivateData,&iData,&dwSize) ||
  538. 0xffffffff == iData))
  539. {
  540. // seems the diffuse texture contains alpha, therefore it has been
  541. // added to the opacity channel, too. Add a special value ...
  542. AddTextureToDisplayList(AI_TEXTYPE_OPACITY | 0x40000000,
  543. 0,&szPath,hTexture,iUV,fBlend,eOp,iMesh);
  544. }
  545. }
  546. // add the material to the list
  547. MaterialInfo info;
  548. info.hTreeItem = hTexture;
  549. info.psMaterial = pcMat;
  550. info.iIndex = iIndex;
  551. info.piEffect = g_pcAsset->apcMeshes[iMesh]->piEffect;
  552. this->AddMaterial(info);
  553. return 1;
  554. }
  555. //-------------------------------------------------------------------------------
  556. int CDisplay::ExpandTree()
  557. {
  558. // expand all materials
  559. for (std::vector< MaterialInfo >::iterator
  560. i = this->m_asMaterials.begin();
  561. i != this->m_asMaterials.end();++i)
  562. {
  563. TreeView_Expand(GetDlgItem(g_hDlg,IDC_TREE1),(*i).hTreeItem,TVE_EXPAND);
  564. }
  565. // expand all nodes
  566. for (std::vector< NodeInfo >::iterator
  567. i = this->m_asNodes.begin();
  568. i != this->m_asNodes.end();++i)
  569. {
  570. TreeView_Expand(GetDlgItem(g_hDlg,IDC_TREE1),(*i).hTreeItem,TVE_EXPAND);
  571. }
  572. TreeView_Expand(GetDlgItem(g_hDlg,IDC_TREE1),this->m_hRoot,TVE_EXPAND);
  573. return 1;
  574. }
  575. //-------------------------------------------------------------------------------
  576. int CDisplay::LoadImageList(void)
  577. {
  578. if (!this->m_hImageList)
  579. {
  580. // First, create the image list we will need.
  581. // FIX: Need RGB888 color space to display all colors correctly
  582. HIMAGELIST hIml = ImageList_Create( 16,16,ILC_COLOR24, 5, 0 );
  583. // Load the bitmaps and add them to the image lists.
  584. HBITMAP hBmp = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BFX));
  585. this->m_aiImageList[AI_VIEW_IMGLIST_MATERIAL] = ImageList_Add(hIml, hBmp, NULL);
  586. DeleteObject(hBmp);
  587. hBmp = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BNODE));
  588. this->m_aiImageList[AI_VIEW_IMGLIST_NODE] = ImageList_Add(hIml, hBmp, NULL);
  589. DeleteObject(hBmp);
  590. hBmp = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BTX));
  591. this->m_aiImageList[AI_VIEW_IMGLIST_TEXTURE] = ImageList_Add(hIml, hBmp, NULL);
  592. DeleteObject(hBmp);
  593. hBmp = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BTXI));
  594. this->m_aiImageList[AI_VIEW_IMGLIST_TEXTURE_INVALID] = ImageList_Add(hIml, hBmp, NULL);
  595. DeleteObject(hBmp);
  596. hBmp = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BROOT));
  597. this->m_aiImageList[AI_VIEW_IMGLIST_MODEL] = ImageList_Add(hIml, hBmp, NULL);
  598. DeleteObject(hBmp);
  599. // Associate the image list with the tree.
  600. TreeView_SetImageList(GetDlgItem(g_hDlg,IDC_TREE1), hIml, TVSIL_NORMAL);
  601. this->m_hImageList = hIml;
  602. }
  603. return 1;
  604. }
  605. //-------------------------------------------------------------------------------
  606. int CDisplay::FillDisplayList(void)
  607. {
  608. this->LoadImageList();
  609. // Initialize the tree view window.
  610. // fill in the first entry
  611. TVITEMEX tvi;
  612. TVINSERTSTRUCT sNew;
  613. tvi.pszText = "Model";
  614. tvi.cchTextMax = (int)strlen(tvi.pszText);
  615. tvi.mask = TVIF_TEXT | TVIF_SELECTEDIMAGE | TVIF_IMAGE | TVIF_HANDLE | TVIF_STATE;
  616. tvi.state = TVIS_EXPANDED;
  617. tvi.iImage = this->m_aiImageList[AI_VIEW_IMGLIST_MODEL];
  618. tvi.iSelectedImage = this->m_aiImageList[AI_VIEW_IMGLIST_MODEL];
  619. tvi.lParam = (LPARAM)0;
  620. sNew.itemex = tvi;
  621. sNew.hInsertAfter = TVI_ROOT;
  622. sNew.hParent = 0;
  623. // add the root item to the tree
  624. this->m_hRoot = (HTREEITEM)SendMessage(GetDlgItem(g_hDlg,IDC_TREE1),
  625. TVM_INSERTITEM,
  626. 0,
  627. (LPARAM)(LPTVINSERTSTRUCT)&sNew);
  628. // add each loaded material to the tree
  629. for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMaterials;++i)
  630. {
  631. AddMaterialToDisplayList(this->m_hRoot,i);
  632. }
  633. // now add all loaded nodes recursively
  634. AddNodeToDisplayList(0,0,g_pcAsset->pcScene->mRootNode,this->m_hRoot);
  635. // now expand all parent nodes in the tree
  636. this->ExpandTree();
  637. // everything reacts a little bit slowly if D3D is rendering,
  638. // so give GDI a small hint to leave the couch and work ;-)
  639. UpdateWindow(g_hDlg);
  640. return 1;
  641. }
  642. //-------------------------------------------------------------------------------
  643. int CDisplay::OnRender()
  644. {
  645. // begin the frame
  646. g_piDevice->BeginScene();
  647. switch (this->m_iViewMode)
  648. {
  649. case VIEWMODE_FULL:
  650. case VIEWMODE_NODE:
  651. this->RenderFullScene();
  652. break;
  653. case VIEWMODE_MATERIAL:
  654. this->RenderMaterialView();
  655. break;
  656. case VIEWMODE_TEXTURE:
  657. this->RenderTextureView();
  658. break;
  659. };
  660. // Now render the log display in the upper right corner of the window
  661. CLogDisplay::Instance().OnRender();
  662. // present the backbuffer
  663. g_piDevice->EndScene();
  664. g_piDevice->Present(NULL,NULL,NULL,NULL);
  665. // don't remove this, problems on some older machines (AMD timing bug)
  666. Sleep(10);
  667. return 1;
  668. }
  669. //-------------------------------------------------------------------------------
  670. void UpdateColorFieldsInUI()
  671. {
  672. InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR1),NULL,TRUE);
  673. InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR2),NULL,TRUE);
  674. InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR3),NULL,TRUE);
  675. UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR1));
  676. UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR2));
  677. UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR3));
  678. }
  679. //-------------------------------------------------------------------------------
  680. int CDisplay::FillDefaultStatistics(void)
  681. {
  682. if (!g_pcAsset)
  683. {
  684. // clear all stats edit controls
  685. SetDlgItemText(g_hDlg,IDC_EVERT,"0");
  686. SetDlgItemText(g_hDlg,IDC_EFACE,"0");
  687. SetDlgItemText(g_hDlg,IDC_EMAT,"0");
  688. SetDlgItemText(g_hDlg,IDC_ENODE,"0");
  689. SetDlgItemText(g_hDlg,IDC_ESHADER,"0");
  690. SetDlgItemText(g_hDlg,IDC_ETEX,"0");
  691. return 1;
  692. }
  693. // get the number of vertices/faces in the model
  694. unsigned int iNumVert = 0;
  695. unsigned int iNumFaces = 0;
  696. for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
  697. {
  698. iNumVert += g_pcAsset->pcScene->mMeshes[i]->mNumVertices;
  699. iNumFaces += g_pcAsset->pcScene->mMeshes[i]->mNumFaces;
  700. }
  701. // and fill the statistic edit controls
  702. char szOut[1024];
  703. sprintf(szOut,"%i",(int)iNumVert);
  704. SetDlgItemText(g_hDlg,IDC_EVERT,szOut);
  705. sprintf(szOut,"%i",(int)iNumFaces);
  706. SetDlgItemText(g_hDlg,IDC_EFACE,szOut);
  707. sprintf(szOut,"%i",(int)g_pcAsset->pcScene->mNumMaterials);
  708. SetDlgItemText(g_hDlg,IDC_EMAT,szOut);
  709. sprintf(szOut,"%i",(int)g_pcAsset->pcScene->mNumMeshes);
  710. SetDlgItemText(g_hDlg,IDC_EMESH,szOut);
  711. // need to get the number of nodes
  712. iNumVert = 0;
  713. GetNodeCount(g_pcAsset->pcScene->mRootNode,&iNumVert);
  714. sprintf(szOut,"%i",(int)iNumVert);
  715. SetDlgItemText(g_hDlg,IDC_ENODEWND,szOut);
  716. // now get the number of unique shaders generated for the asset
  717. // (even if the environment changes this number won't change)
  718. sprintf(szOut,"%i", CMaterialManager::Instance().GetShaderCount());
  719. SetDlgItemText(g_hDlg,IDC_ESHADER,szOut);
  720. sprintf(szOut,"%.5f",(float)g_fLoadTime);
  721. SetDlgItemText(g_hDlg,IDC_ELOAD,szOut);
  722. UpdateColorFieldsInUI();
  723. UpdateWindow(g_hDlg);
  724. return 1;
  725. }
  726. //-------------------------------------------------------------------------------
  727. int CDisplay::Reset(void)
  728. {
  729. // clear all lists
  730. this->m_asMaterials.clear();
  731. this->m_asTextures.clear();
  732. this->m_asNodes.clear();
  733. this->m_hRoot = NULL;
  734. return this->OnSetupNormalView();
  735. }
  736. //-------------------------------------------------------------------------------
  737. void ShowNormalUIComponents()
  738. {
  739. ShowWindow(GetDlgItem(g_hDlg,IDC_NUMNODES),SW_SHOW);
  740. ShowWindow(GetDlgItem(g_hDlg,IDC_ENODEWND),SW_SHOW);
  741. ShowWindow(GetDlgItem(g_hDlg,IDC_NUMSHADERS),SW_SHOW);
  742. ShowWindow(GetDlgItem(g_hDlg,IDC_LOADTIME),SW_SHOW);
  743. ShowWindow(GetDlgItem(g_hDlg,IDC_ESHADER),SW_SHOW);
  744. ShowWindow(GetDlgItem(g_hDlg,IDC_ELOAD),SW_SHOW);
  745. ShowWindow(GetDlgItem(g_hDlg,IDC_VIEWMATRIX),SW_HIDE);
  746. }
  747. //-------------------------------------------------------------------------------
  748. int CDisplay::OnSetupNormalView()
  749. {
  750. if (VIEWMODE_NODE == this->m_iViewMode)
  751. {
  752. ShowNormalUIComponents();
  753. }
  754. // now ... change the meaning of the statistics fields back
  755. SetWindowText(GetDlgItem(g_hDlg,IDC_NUMVERTS),"Verts:");
  756. SetWindowText(GetDlgItem(g_hDlg,IDC_NUMNODES),"Nodes:");
  757. SetWindowText(GetDlgItem(g_hDlg,IDC_NUMFACES),"Faces:");
  758. SetWindowText(GetDlgItem(g_hDlg,IDC_NUMSHADERS),"Shd:");
  759. SetWindowText(GetDlgItem(g_hDlg,IDC_NUMMATS),"Mats:");
  760. SetWindowText(GetDlgItem(g_hDlg,IDC_NUMMESHES),"Mesh:");
  761. SetWindowText(GetDlgItem(g_hDlg,IDC_LOADTIME),"Time:");
  762. this->FillDefaultStatistics();
  763. this->SetViewMode(VIEWMODE_FULL);
  764. // for debugging
  765. this->m_pcCurrentMaterial = NULL;
  766. this->m_pcCurrentTexture = NULL;
  767. this->m_pcCurrentNode = NULL;
  768. // redraw the color fields in the UI --- their purpose has possibly changed
  769. UpdateColorFieldsInUI();
  770. UpdateWindow(g_hDlg);
  771. return 1;
  772. }
  773. //-------------------------------------------------------------------------------
  774. int CDisplay::OnSetupNodeView(NodeInfo* pcNew)
  775. {
  776. ai_assert(NULL != pcNew);
  777. if (this->m_pcCurrentNode == pcNew)return 2;
  778. // now ... change the meaning of the statistics fields back
  779. SetWindowText(GetDlgItem(g_hDlg,IDC_NUMVERTS),"Verts:");
  780. SetWindowText(GetDlgItem(g_hDlg,IDC_NUMFACES),"Faces:");
  781. SetWindowText(GetDlgItem(g_hDlg,IDC_NUMMATS),"Mats:");
  782. SetWindowText(GetDlgItem(g_hDlg,IDC_NUMMESHES),"Mesh:");
  783. ShowWindow(GetDlgItem(g_hDlg,IDC_NUMNODES),SW_HIDE);
  784. ShowWindow(GetDlgItem(g_hDlg,IDC_ENODEWND),SW_HIDE);
  785. ShowWindow(GetDlgItem(g_hDlg,IDC_NUMSHADERS),SW_HIDE);
  786. ShowWindow(GetDlgItem(g_hDlg,IDC_LOADTIME),SW_HIDE);
  787. ShowWindow(GetDlgItem(g_hDlg,IDC_ESHADER),SW_HIDE);
  788. ShowWindow(GetDlgItem(g_hDlg,IDC_ELOAD),SW_HIDE);
  789. ShowWindow(GetDlgItem(g_hDlg,IDC_VIEWMATRIX),SW_SHOW);
  790. char szTemp[1024];
  791. sprintf(szTemp,
  792. "%.2f %.2f %.2f\r\n"
  793. "%.2f %.2f %.2f\r\n"
  794. "%.2f %.2f %.2f\r\n"
  795. "%.2f %.2f %.2f\r\n",
  796. pcNew->psNode->mTransformation.a1,
  797. pcNew->psNode->mTransformation.b1,
  798. pcNew->psNode->mTransformation.c1,
  799. pcNew->psNode->mTransformation.a2,
  800. pcNew->psNode->mTransformation.b2,
  801. pcNew->psNode->mTransformation.c2,
  802. pcNew->psNode->mTransformation.a3,
  803. pcNew->psNode->mTransformation.b3,
  804. pcNew->psNode->mTransformation.c3,
  805. pcNew->psNode->mTransformation.a4,
  806. pcNew->psNode->mTransformation.b4,
  807. pcNew->psNode->mTransformation.c4);
  808. SetWindowText(GetDlgItem(g_hDlg,IDC_VIEWMATRIX),szTemp);
  809. this->m_pcCurrentNode = pcNew;
  810. this->SetViewMode(VIEWMODE_NODE);
  811. return 1;
  812. }
  813. //-------------------------------------------------------------------------------
  814. int CDisplay::OnSetupMaterialView(MaterialInfo* pcNew)
  815. {
  816. ai_assert(NULL != pcNew);
  817. if (this->m_pcCurrentMaterial == pcNew)return 2;
  818. if (VIEWMODE_NODE == this->m_iViewMode)
  819. {
  820. ShowNormalUIComponents();
  821. }
  822. this->m_pcCurrentMaterial = pcNew;
  823. this->SetViewMode(VIEWMODE_MATERIAL);
  824. // redraw the color fields in the UI --- their purpose has possibly changed
  825. UpdateColorFieldsInUI();
  826. UpdateWindow(g_hDlg);
  827. return 1;
  828. }
  829. //-------------------------------------------------------------------------------
  830. int CDisplay::OnSetupTextureView(TextureInfo* pcNew)
  831. {
  832. ai_assert(NULL != pcNew);
  833. if (this->m_pcCurrentTexture == pcNew)return 2;
  834. if (VIEWMODE_NODE == this->m_iViewMode)
  835. {
  836. ShowNormalUIComponents();
  837. }
  838. if ((AI_TEXTYPE_OPACITY | 0x40000000) == pcNew->iType)
  839. {
  840. // for opacity textures display a warn message
  841. CLogDisplay::Instance().AddEntry("[INFO] This texture is not existing in the "
  842. "original mesh",D3DCOLOR_ARGB(0xFF,0xFF,0xFF,0));
  843. CLogDisplay::Instance().AddEntry("It is a copy of the alpha channel of the first "
  844. "diffuse texture",D3DCOLOR_ARGB(0xFF,0xFF,0xFF,0));
  845. }
  846. // check whether the pattern background effect is supported
  847. if (g_sCaps.PixelShaderVersion < D3DPS_VERSION(3,0))
  848. {
  849. CLogDisplay::Instance().AddEntry("[WARN] The background shader won't work "
  850. "on your system, it required PS 3.0 hardware. A default color is used ...",
  851. D3DCOLOR_ARGB(0xFF,0xFF,0x00,0));
  852. }
  853. this->m_fTextureZoom = 1000.0f;
  854. this->m_vTextureOffset.x = this->m_vTextureOffset.y = 0.0f;
  855. this->m_pcCurrentTexture = pcNew;
  856. this->SetViewMode(VIEWMODE_TEXTURE);
  857. // now ... change the meaning of the statistics fields
  858. SetWindowText(GetDlgItem(g_hDlg,IDC_NUMVERTS),"Width:");
  859. SetWindowText(GetDlgItem(g_hDlg,IDC_NUMNODES),"Height:");
  860. SetWindowText(GetDlgItem(g_hDlg,IDC_NUMFACES),"Format:");
  861. SetWindowText(GetDlgItem(g_hDlg,IDC_NUMSHADERS),"MIPs:");
  862. SetWindowText(GetDlgItem(g_hDlg,IDC_NUMMATS),"UV:");
  863. SetWindowText(GetDlgItem(g_hDlg,IDC_NUMMESHES),"Blend:");
  864. SetWindowText(GetDlgItem(g_hDlg,IDC_LOADTIME),"Op:");
  865. // and fill them with data
  866. D3DSURFACE_DESC sDesc;
  867. (*pcNew->piTexture)->GetLevelDesc(0,&sDesc);
  868. char szTemp[128];
  869. sprintf(szTemp,"%i",sDesc.Width);
  870. SetWindowText(GetDlgItem(g_hDlg,IDC_EVERT),szTemp);
  871. sprintf(szTemp,"%i",sDesc.Height);
  872. SetWindowText(GetDlgItem(g_hDlg,IDC_ENODEWND),szTemp);
  873. sprintf(szTemp,"%i",(*pcNew->piTexture)->GetLevelCount());
  874. SetWindowText(GetDlgItem(g_hDlg,IDC_ESHADER),szTemp);
  875. sprintf(szTemp,"%i",pcNew->iUV);
  876. SetWindowText(GetDlgItem(g_hDlg,IDC_EMAT),szTemp);
  877. sprintf(szTemp,"%f",pcNew->fBlend);
  878. SetWindowText(GetDlgItem(g_hDlg,IDC_EMESH),szTemp);
  879. const char* szOp;
  880. switch (pcNew->eOp)
  881. {
  882. case aiTextureOp_Add:
  883. szOp = "add";break;
  884. case aiTextureOp_Subtract:
  885. szOp = "sub";break;
  886. case aiTextureOp_Divide:
  887. szOp = "div";break;
  888. case aiTextureOp_SignedAdd:
  889. szOp = "addsign";break;
  890. case aiTextureOp_SmoothAdd:
  891. szOp = "addsmooth";break;
  892. default: szOp = "mul";
  893. };
  894. SetWindowText(GetDlgItem(g_hDlg,IDC_ELOAD),szOp);
  895. // NOTE: Format is always ARGB8888 since other formats are
  896. // converted to this format ...
  897. SetWindowText(GetDlgItem(g_hDlg,IDC_EFACE),"ARGB8");
  898. // check whether this is the default texture
  899. if (pcNew->piTexture)
  900. {
  901. // {9785DA94-1D96-426b-B3CB-BADC36347F5E}
  902. static const GUID guidPrivateData =
  903. { 0x9785da94, 0x1d96, 0x426b,
  904. { 0xb3, 0xcb, 0xba, 0xdc, 0x36, 0x34, 0x7f, 0x5e } };
  905. uint32_t iData = 0;
  906. DWORD dwSize = 4;
  907. (*pcNew->piTexture)->GetPrivateData(guidPrivateData,&iData,&dwSize);
  908. if (0xFFFFFFFF == iData)
  909. {
  910. CLogDisplay::Instance().AddEntry("[ERROR] Texture could not be loaded. "
  911. "The displayed texture is a default texture",
  912. D3DCOLOR_ARGB(0xFF,0xFF,0,0));
  913. return 0;
  914. }
  915. }
  916. // redraw the color fields in the UI --- their purpose has possibly changed
  917. UpdateColorFieldsInUI();
  918. UpdateWindow(g_hDlg);
  919. return 1;
  920. }
  921. //-------------------------------------------------------------------------------
  922. int CDisplay::OnSetup(HTREEITEM p_hTreeItem)
  923. {
  924. // search in our list for the item
  925. union {
  926. TextureInfo* pcNew;
  927. NodeInfo* pcNew2;
  928. MaterialInfo* pcNew3; };
  929. pcNew = NULL;
  930. for (std::vector<TextureInfo>::iterator
  931. i = this->m_asTextures.begin();
  932. i != this->m_asTextures.end();++i)
  933. {
  934. if (p_hTreeItem == (*i).hTreeItem)
  935. {
  936. pcNew = &(*i);
  937. break;
  938. }
  939. }
  940. if (pcNew)
  941. {
  942. return this->OnSetupTextureView(pcNew);
  943. }
  944. // seach the node list
  945. for (std::vector<NodeInfo>::iterator
  946. i = this->m_asNodes.begin();
  947. i != this->m_asNodes.end();++i)
  948. {
  949. if (p_hTreeItem == (*i).hTreeItem)
  950. {
  951. pcNew2 = &(*i);
  952. break;
  953. }
  954. }
  955. if (pcNew2)
  956. {
  957. return this->OnSetupNodeView(pcNew2);
  958. }
  959. // seach the material list
  960. for (std::vector<MaterialInfo>::iterator
  961. i = this->m_asMaterials.begin();
  962. i != this->m_asMaterials.end();++i)
  963. {
  964. if (p_hTreeItem == (*i).hTreeItem)
  965. {
  966. pcNew3 = &(*i);
  967. break;
  968. }
  969. }
  970. if (pcNew3)
  971. {
  972. return this->OnSetupMaterialView(pcNew3);
  973. }
  974. return this->OnSetupNormalView();
  975. }
  976. //-------------------------------------------------------------------------------
  977. int CDisplay::ShowTreeViewContextMenu(HTREEITEM hItem)
  978. {
  979. ai_assert(NULL != hItem);
  980. HMENU hDisplay = NULL;
  981. // search in our list for the item
  982. TextureInfo* pcNew = NULL;
  983. for (std::vector<TextureInfo>::iterator
  984. i = this->m_asTextures.begin();
  985. i != this->m_asTextures.end();++i)
  986. {
  987. if (hItem == (*i).hTreeItem)
  988. {
  989. pcNew = &(*i);
  990. break;
  991. }
  992. }
  993. if (pcNew)
  994. {
  995. HMENU hMenu = LoadMenu(g_hInstance,MAKEINTRESOURCE(IDR_TXPOPUP));
  996. hDisplay = GetSubMenu(hMenu,0);
  997. //this->OnSetupTextureView(pcNew);
  998. }
  999. // search in the material list for the item
  1000. MaterialInfo* pcNew2 = NULL;
  1001. for (std::vector<MaterialInfo>::iterator
  1002. i = this->m_asMaterials.begin();
  1003. i != this->m_asMaterials.end();++i)
  1004. {
  1005. if (hItem == (*i).hTreeItem)
  1006. {
  1007. pcNew2 = &(*i);
  1008. break;
  1009. }
  1010. }
  1011. if (pcNew2)
  1012. {
  1013. HMENU hMenu = LoadMenu(g_hInstance,MAKEINTRESOURCE(IDR_MATPOPUP));
  1014. hDisplay = GetSubMenu(hMenu,0);
  1015. //this->OnSetupMaterialView(pcNew2);
  1016. }
  1017. if (NULL != hDisplay)
  1018. {
  1019. // select this entry (this should all OnSetup())
  1020. TreeView_Select(GetDlgItem(g_hDlg,IDC_TREE1),hItem,TVGN_CARET);
  1021. // FIX: Render the scene once that the correct texture/material
  1022. // is displayed while the context menu is active
  1023. this->OnRender();
  1024. POINT sPoint;
  1025. GetCursorPos(&sPoint);
  1026. TrackPopupMenu(hDisplay, TPM_LEFTALIGN, sPoint.x, sPoint.y, 0,
  1027. g_hDlg,NULL);
  1028. }
  1029. return 1;
  1030. }
  1031. //-------------------------------------------------------------------------------
  1032. int CDisplay::HandleTreeViewPopup(WPARAM wParam,LPARAM lParam)
  1033. {
  1034. // get the current selected material
  1035. std::vector<Info> apclrOut;
  1036. const char* szMatKey;
  1037. switch (LOWORD(wParam))
  1038. {
  1039. case ID_SOLONG_CLEARDIFFUSECOLOR:
  1040. for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
  1041. {
  1042. if (this->m_pcCurrentMaterial->iIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex)
  1043. {
  1044. apclrOut.push_back( Info( &g_pcAsset->apcMeshes[i]->vDiffuseColor,
  1045. g_pcAsset->apcMeshes[i],"DIFFUSE_COLOR"));
  1046. }
  1047. }
  1048. szMatKey = AI_MATKEY_COLOR_DIFFUSE;
  1049. break;
  1050. case ID_SOLONG_CLEARSPECULARCOLOR:
  1051. for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
  1052. {
  1053. if (this->m_pcCurrentMaterial->iIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex)
  1054. {
  1055. apclrOut.push_back( Info( &g_pcAsset->apcMeshes[i]->vSpecularColor,
  1056. g_pcAsset->apcMeshes[i],"SPECULAR_COLOR"));
  1057. }
  1058. }
  1059. szMatKey = AI_MATKEY_COLOR_SPECULAR;
  1060. break;
  1061. case ID_SOLONG_CLEARAMBIENTCOLOR:
  1062. for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
  1063. {
  1064. if (this->m_pcCurrentMaterial->iIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex)
  1065. {
  1066. apclrOut.push_back( Info( &g_pcAsset->apcMeshes[i]->vAmbientColor,
  1067. g_pcAsset->apcMeshes[i],"AMBIENT_COLOR"));
  1068. }
  1069. }
  1070. szMatKey = AI_MATKEY_COLOR_AMBIENT;
  1071. break;
  1072. case ID_SOLONG_CLEAREMISSIVECOLOR:
  1073. for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
  1074. {
  1075. if (this->m_pcCurrentMaterial->iIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex)
  1076. {
  1077. apclrOut.push_back( Info( &g_pcAsset->apcMeshes[i]->vEmissiveColor,
  1078. g_pcAsset->apcMeshes[i],"EMISSIVE_COLOR"));
  1079. }
  1080. }
  1081. szMatKey = AI_MATKEY_COLOR_EMISSIVE;
  1082. break;
  1083. default:
  1084. // let the next function do this ... no spaghetti code ;-)
  1085. this->HandleTreeViewPopup2(wParam,lParam);
  1086. };
  1087. if (!apclrOut.empty())
  1088. {
  1089. aiColor4D clrOld = *((aiColor4D*)(apclrOut.front().pclrColor));
  1090. CHOOSECOLOR clr;
  1091. clr.lStructSize = sizeof(CHOOSECOLOR);
  1092. clr.hwndOwner = g_hDlg;
  1093. clr.Flags = CC_RGBINIT | CC_FULLOPEN;
  1094. clr.rgbResult = RGB(
  1095. clamp<unsigned char>(clrOld.r * 255.0f),
  1096. clamp<unsigned char>(clrOld.g * 255.0f),
  1097. clamp<unsigned char>(clrOld.b * 255.0f));
  1098. clr.lpCustColors = g_aclCustomColors;
  1099. clr.lpfnHook = NULL;
  1100. clr.lpTemplateName = NULL;
  1101. clr.lCustData = NULL;
  1102. ChooseColor(&clr);
  1103. clrOld.r = (float)(((unsigned int)clr.rgbResult) & 0xFF) / 255.0f;
  1104. clrOld.g = (float)(((unsigned int)clr.rgbResult >> 8) & 0xFF) / 255.0f;
  1105. clrOld.b = (float)(((unsigned int)clr.rgbResult >> 16) & 0xFF) / 255.0f;
  1106. // update the color values in the mesh instances and
  1107. // update all shaders ...
  1108. for (std::vector<Info>::iterator
  1109. i = apclrOut.begin();
  1110. i != apclrOut.end();++i)
  1111. {
  1112. *((*i).pclrColor) = *((D3DXVECTOR4*)&clrOld);
  1113. if (!(*i).pMesh->bSharedFX)
  1114. {
  1115. (*i).pMesh->piEffect->SetVector((*i).szShaderParam,(*i).pclrColor);
  1116. }
  1117. }
  1118. // change the material key ...
  1119. Assimp::MaterialHelper* pcMat = (Assimp::MaterialHelper*)g_pcAsset->pcScene->mMaterials[
  1120. this->m_pcCurrentMaterial->iIndex];
  1121. pcMat->AddProperty<aiColor4D>(&clrOld,1,szMatKey);
  1122. if (ID_SOLONG_CLEARSPECULARCOLOR == LOWORD(wParam) &&
  1123. aiShadingMode_Gouraud == apclrOut.front().pMesh->eShadingMode)
  1124. {
  1125. CLogDisplay::Instance().AddEntry("[INFO] You have just changed the specular "
  1126. "material color",D3DCOLOR_ARGB(0xFF,0xFF,0xFF,0));
  1127. CLogDisplay::Instance().AddEntry(
  1128. "This is great, especially since there is currently no specular shading",
  1129. D3DCOLOR_ARGB(0xFF,0xFF,0xFF,0));
  1130. }
  1131. }
  1132. return 1;
  1133. }
  1134. //-------------------------------------------------------------------------------
  1135. int CALLBACK TreeViewCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
  1136. {
  1137. if (lParamSort == lParam1)return -1;
  1138. if (lParamSort == lParam2)return 1;
  1139. return 0;
  1140. }
  1141. //-------------------------------------------------------------------------------
  1142. int CDisplay::HandleTreeViewPopup2(WPARAM wParam,LPARAM lParam)
  1143. {
  1144. char szFileName[MAX_PATH];
  1145. DWORD dwTemp = MAX_PATH;
  1146. switch (LOWORD(wParam))
  1147. {
  1148. case ID_HEY_REPLACE:
  1149. {
  1150. // get a path to a new texture
  1151. if(ERROR_SUCCESS != RegQueryValueEx(g_hRegistry,"ReplaceTextureSrc",NULL,NULL,
  1152. (BYTE*)szFileName,&dwTemp))
  1153. {
  1154. // Key was not found. Use C:
  1155. strcpy(szFileName,"");
  1156. }
  1157. else
  1158. {
  1159. // need to remove the file name
  1160. char* sz = strrchr(szFileName,'\\');
  1161. if (!sz)sz = strrchr(szFileName,'/');
  1162. if (!sz)*sz = 0;
  1163. }
  1164. OPENFILENAME sFilename1 = {
  1165. sizeof(OPENFILENAME),
  1166. g_hDlg,GetModuleHandle(NULL),
  1167. "Textures\0*.png;*.dds;*.tga;*.bmp;*.tif;*.ppm;*.ppx;*.jpg;*.jpeg;*.exr\0*.*\0",
  1168. NULL, 0, 1,
  1169. szFileName, MAX_PATH, NULL, 0, NULL,
  1170. "Replace this texture",
  1171. OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_NOCHANGEDIR,
  1172. 0, 1, ".jpg", 0, NULL, NULL
  1173. };
  1174. if(GetOpenFileName(&sFilename1) == 0) return 0;
  1175. // Now store the file in the registry
  1176. RegSetValueExA(g_hRegistry,"ReplaceTextureSrc",0,REG_SZ,(const BYTE*)szFileName,MAX_PATH);
  1177. this->ReplaceCurrentTexture(szFileName);
  1178. }
  1179. return 1;
  1180. case ID_HEY_EXPORT:
  1181. {
  1182. if(ERROR_SUCCESS != RegQueryValueEx(g_hRegistry,"TextureExportDest",NULL,NULL,
  1183. (BYTE*)szFileName,&dwTemp))
  1184. {
  1185. // Key was not found. Use C:
  1186. strcpy(szFileName,"");
  1187. }
  1188. else
  1189. {
  1190. // need to remove the file name
  1191. char* sz = strrchr(szFileName,'\\');
  1192. if (!sz)sz = strrchr(szFileName,'/');
  1193. if (!sz)*sz = 0;
  1194. }
  1195. OPENFILENAME sFilename1 = {
  1196. sizeof(OPENFILENAME),
  1197. g_hDlg,GetModuleHandle(NULL),
  1198. "Textures\0*.png;*.dds;*.bmp;*.tif;*.pfm;*.jpg;*.jpeg;*.hdr\0*.*\0", NULL, 0, 1,
  1199. szFileName, MAX_PATH, NULL, 0, NULL,
  1200. "Export texture to file",
  1201. OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_NOCHANGEDIR,
  1202. 0, 1, ".png", 0, NULL, NULL
  1203. };
  1204. if(GetSaveFileName(&sFilename1) == 0) return 0;
  1205. // Now store the file in the registry
  1206. RegSetValueExA(g_hRegistry,"TextureExportDest",0,REG_SZ,(const BYTE*)szFileName,MAX_PATH);
  1207. // determine the file format ...
  1208. D3DXIMAGE_FILEFORMAT eFormat = D3DXIFF_PNG;
  1209. const char* sz = strrchr(szFileName,'.');
  1210. if (sz)
  1211. {
  1212. ++sz;
  1213. if (0 == Assimp::ASSIMP_stricmp(sz,"pfm"))eFormat = D3DXIFF_PFM;
  1214. else if (0 == Assimp::ASSIMP_stricmp(sz,"dds"))eFormat = D3DXIFF_DDS;
  1215. else if (0 == Assimp::ASSIMP_stricmp(sz,"jpg"))eFormat = D3DXIFF_JPG;
  1216. else if (0 == Assimp::ASSIMP_stricmp(sz,"jpeg"))eFormat = D3DXIFF_JPG;
  1217. else if (0 == Assimp::ASSIMP_stricmp(sz,"hdr"))eFormat = D3DXIFF_HDR;
  1218. else if (0 == Assimp::ASSIMP_stricmp(sz,"bmp"))eFormat = D3DXIFF_BMP;
  1219. }
  1220. // get a pointer to the first surface of the current texture
  1221. IDirect3DSurface9* pi = NULL;
  1222. (*this->m_pcCurrentTexture->piTexture)->GetSurfaceLevel(0,&pi);
  1223. if(!pi || FAILED(D3DXSaveSurfaceToFile(szFileName,eFormat,pi,NULL,NULL)))
  1224. {
  1225. CLogDisplay::Instance().AddEntry("[ERROR] Unable to export texture",
  1226. D3DCOLOR_ARGB(0xFF,0xFF,0,0));
  1227. }
  1228. else
  1229. {
  1230. CLogDisplay::Instance().AddEntry("[INFO] The texture has been exported",
  1231. D3DCOLOR_ARGB(0xFF,0xFF,0xFF,0));
  1232. }
  1233. if(pi)pi->Release();
  1234. }
  1235. return 1;
  1236. case ID_HEY_REMOVE:
  1237. {
  1238. if(IDYES != MessageBox(g_hDlg,"To recover the texture you need to reload the model. Do you wish to continue?",
  1239. "Remove texture",MB_YESNO))
  1240. {
  1241. return 1;
  1242. }
  1243. Assimp::MaterialHelper* pcMat = (Assimp::MaterialHelper*)g_pcAsset->pcScene->mMaterials[
  1244. this->m_pcCurrentTexture->iMatIndex];
  1245. switch (this->m_pcCurrentTexture->iType)
  1246. {
  1247. case AI_TEXTYPE_DIFFUSE:
  1248. pcMat->RemoveProperty(AI_MATKEY_TEXTURE_DIFFUSE(0));
  1249. break;
  1250. case AI_TEXTYPE_SPECULAR:
  1251. pcMat->RemoveProperty(AI_MATKEY_TEXTURE_SPECULAR(0));
  1252. break;
  1253. case AI_TEXTYPE_AMBIENT:
  1254. pcMat->RemoveProperty(AI_MATKEY_TEXTURE_AMBIENT(0));
  1255. break;
  1256. case AI_TEXTYPE_EMISSIVE:
  1257. pcMat->RemoveProperty(AI_MATKEY_TEXTURE_EMISSIVE(0));
  1258. break;
  1259. case AI_TEXTYPE_NORMALS:
  1260. pcMat->RemoveProperty(AI_MATKEY_TEXTURE_NORMALS(0));
  1261. break;
  1262. case AI_TEXTYPE_HEIGHT:
  1263. pcMat->RemoveProperty(AI_MATKEY_TEXTURE_HEIGHT(0));
  1264. break;
  1265. case AI_TEXTYPE_SHININESS:
  1266. pcMat->RemoveProperty(AI_MATKEY_TEXTURE_SHININESS(0));
  1267. break;
  1268. case (AI_TEXTYPE_OPACITY | 0x40000000):
  1269. // set a special property to indicate that no alpha channel is required
  1270. {int iVal = 1;
  1271. pcMat->AddProperty<int>(&iVal,1,"no_a_from_d");}
  1272. break;
  1273. default: //case AI_TEXTYPE_OPACITY
  1274. pcMat->RemoveProperty(AI_MATKEY_TEXTURE_OPACITY(0));
  1275. };
  1276. // need to update all meshes associated with this material
  1277. for (unsigned int i = 0;i < g_pcAsset->pcScene->mNumMeshes;++i)
  1278. {
  1279. if (this->m_pcCurrentTexture->iMatIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex)
  1280. {
  1281. CMaterialManager::Instance().DeleteMaterial(g_pcAsset->apcMeshes[i]);
  1282. CMaterialManager::Instance().CreateMaterial(g_pcAsset->apcMeshes[i],g_pcAsset->pcScene->mMeshes[i]);
  1283. }
  1284. }
  1285. // find the corresponding MaterialInfo structure
  1286. const unsigned int iMatIndex = this->m_pcCurrentTexture->iMatIndex;
  1287. for (std::vector<MaterialInfo>::iterator
  1288. a = this->m_asMaterials.begin();
  1289. a != this->m_asMaterials.end();++a)
  1290. {
  1291. if (iMatIndex == (*a).iIndex)
  1292. {
  1293. // good news. we will also need to find all other textures
  1294. // associated with this item ...
  1295. for (std::vector<TextureInfo>::iterator
  1296. n = this->m_asTextures.begin();
  1297. n != this->m_asTextures.end();++n)
  1298. {
  1299. if ((*n).iMatIndex == iMatIndex)
  1300. {
  1301. n = this->m_asTextures.erase(n);
  1302. if (this->m_asTextures.end() == n)break;
  1303. }
  1304. }
  1305. // delete this material from all lists ...
  1306. TreeView_DeleteItem(GetDlgItem(g_hDlg,IDC_TREE1),(*a).hTreeItem);
  1307. this->m_asMaterials.erase(a);
  1308. break;
  1309. }
  1310. }
  1311. // add the new material to the list and make sure it will be fully expanded
  1312. AddMaterialToDisplayList(this->m_hRoot,iMatIndex);
  1313. HTREEITEM hNewItem = this->m_asMaterials.back().hTreeItem;
  1314. TreeView_Expand(GetDlgItem(g_hDlg,IDC_TREE1),hNewItem,TVE_EXPAND);
  1315. // we need to sort the list, materials come first, then nodes
  1316. TVSORTCB sSort;
  1317. sSort.hParent = this->m_hRoot;
  1318. sSort.lParam = 10;
  1319. sSort.lpfnCompare = &TreeViewCompareFunc;
  1320. TreeView_SortChildrenCB(GetDlgItem(g_hDlg,IDC_TREE1),&sSort,0);
  1321. // the texture was selected, but the silly user has just deleted it
  1322. // ... go back to normal viewing mode
  1323. TreeView_Select(GetDlgItem(g_hDlg,IDC_TREE1),this->m_hRoot,TVGN_CARET);
  1324. return 1;
  1325. }
  1326. case ID_HEY_RESETTEXTURE:
  1327. {
  1328. aiString szOld;
  1329. aiMaterial* pcMat = g_pcAsset->pcScene->mMaterials[this->m_pcCurrentTexture->iMatIndex];
  1330. switch (this->m_pcCurrentTexture->iType)
  1331. {
  1332. case AI_TEXTYPE_DIFFUSE:
  1333. aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_DIFFUSE(0) "_old",&szOld);
  1334. break;
  1335. case AI_TEXTYPE_SPECULAR:
  1336. aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_SPECULAR(0) "_old",&szOld);
  1337. break;
  1338. case AI_TEXTYPE_AMBIENT:
  1339. aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_AMBIENT(0) "_old",&szOld);
  1340. break;
  1341. case AI_TEXTYPE_EMISSIVE:
  1342. aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_EMISSIVE(0) "_old",&szOld);
  1343. break;
  1344. case AI_TEXTYPE_NORMALS:
  1345. aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_NORMALS(0) "_old",&szOld);
  1346. break;
  1347. case AI_TEXTYPE_HEIGHT:
  1348. aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_HEIGHT(0) "_old",&szOld);
  1349. break;
  1350. case AI_TEXTYPE_SHININESS:
  1351. aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_SHININESS(0) "_old",&szOld);
  1352. break;
  1353. default : //case AI_TEXTYPE_OPACITY && case AI_TEXTYPE_OPACITY | 0x40000000:
  1354. aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_OPACITY(0) "_old",&szOld);
  1355. break;
  1356. };
  1357. if (0 != szOld.length)this->ReplaceCurrentTexture(szOld.data);
  1358. return 1;
  1359. }
  1360. }
  1361. return 0;
  1362. }
  1363. //-------------------------------------------------------------------------------
  1364. int CDisplay::SetupStereoView()
  1365. {
  1366. if (NULL != g_pcAsset && NULL != g_pcAsset->pcScene->mRootNode)
  1367. {
  1368. // enable the RED, GREEN and ALPHA channels
  1369. g_piDevice->SetRenderState(D3DRS_COLORWRITEENABLE,
  1370. D3DCOLORWRITEENABLE_RED |
  1371. D3DCOLORWRITEENABLE_ALPHA |
  1372. D3DCOLORWRITEENABLE_GREEN);
  1373. // move the camera a little bit to the left
  1374. g_sCamera.vPos -= g_sCamera.vRight * 0.03f;
  1375. }
  1376. return 1;
  1377. }
  1378. //-------------------------------------------------------------------------------
  1379. int CDisplay::RenderStereoView(const aiMatrix4x4& m)
  1380. {
  1381. // and rerender the scene
  1382. if (NULL != g_pcAsset && NULL != g_pcAsset->pcScene->mRootNode)
  1383. {
  1384. // enable the BLUE, GREEN and ALPHA channels
  1385. g_piDevice->SetRenderState(D3DRS_COLORWRITEENABLE,
  1386. D3DCOLORWRITEENABLE_GREEN |
  1387. D3DCOLORWRITEENABLE_ALPHA |
  1388. D3DCOLORWRITEENABLE_BLUE);
  1389. // clear the z-buffer
  1390. g_piDevice->Clear(0,NULL,D3DCLEAR_ZBUFFER,0,1.0f,0);
  1391. // move the camera a little bit to the right
  1392. g_sCamera.vPos += g_sCamera.vRight * 0.06f;
  1393. RenderNode(g_pcAsset->pcScene->mRootNode,m,false);
  1394. g_piDevice->SetRenderState(D3DRS_ZWRITEENABLE,FALSE);
  1395. RenderNode(g_pcAsset->pcScene->mRootNode,m,true);
  1396. g_piDevice->SetRenderState(D3DRS_ZWRITEENABLE,TRUE);
  1397. // (move back to the original position)
  1398. g_sCamera.vPos -= g_sCamera.vRight * 0.03f;
  1399. // reenable all channels
  1400. g_piDevice->SetRenderState(D3DRS_COLORWRITEENABLE,
  1401. D3DCOLORWRITEENABLE_RED |
  1402. D3DCOLORWRITEENABLE_GREEN |
  1403. D3DCOLORWRITEENABLE_ALPHA |
  1404. D3DCOLORWRITEENABLE_BLUE);
  1405. }
  1406. return 1;
  1407. }
  1408. //-------------------------------------------------------------------------------
  1409. int CDisplay::HandleInputTextureView()
  1410. {
  1411. HandleMouseInputTextureView();
  1412. HandleKeyboardInputTextureView();
  1413. return 1;
  1414. }
  1415. //-------------------------------------------------------------------------------
  1416. int CDisplay::HandleInput()
  1417. {
  1418. if(CBackgroundPainter::TEXTURE_CUBE == CBackgroundPainter::Instance().GetMode())
  1419. HandleMouseInputSkyBox();
  1420. // handle input commands
  1421. HandleMouseInputLightRotate();
  1422. HandleMouseInputLightIntensityAndColor();
  1423. if(g_bFPSView)
  1424. {
  1425. HandleMouseInputFPS();
  1426. HandleKeyboardInputFPS();
  1427. }
  1428. else HandleMouseInputLocal();
  1429. // compute auto rotation depending on the time which has passed
  1430. if (g_sOptions.bRotate)
  1431. {
  1432. aiMatrix4x4 mMat;
  1433. D3DXMatrixRotationYawPitchRoll((D3DXMATRIX*)&mMat,
  1434. g_vRotateSpeed.x * g_fElpasedTime,
  1435. g_vRotateSpeed.y * g_fElpasedTime,
  1436. g_vRotateSpeed.z * g_fElpasedTime);
  1437. g_mWorldRotate = g_mWorldRotate * mMat;
  1438. }
  1439. // Handle rotations of light source(s)
  1440. if (g_sOptions.bLightRotate)
  1441. {
  1442. aiMatrix4x4 mMat;
  1443. D3DXMatrixRotationYawPitchRoll((D3DXMATRIX*)&mMat,
  1444. g_vRotateSpeed.x * g_fElpasedTime * 0.5f,
  1445. g_vRotateSpeed.y * g_fElpasedTime * 0.5f,
  1446. g_vRotateSpeed.z * g_fElpasedTime * 0.5f);
  1447. D3DXVec3TransformNormal((D3DXVECTOR3*)&g_avLightDirs[0],
  1448. (D3DXVECTOR3*)&g_avLightDirs[0],(D3DXMATRIX*)&mMat);
  1449. // 2 lights to rotate?
  1450. if (g_sOptions.b3Lights)
  1451. {
  1452. D3DXVec3TransformNormal((D3DXVECTOR3*)&g_avLightDirs[1],
  1453. (D3DXVECTOR3*)&g_avLightDirs[1],(D3DXMATRIX*)&mMat);
  1454. g_avLightDirs[1].Normalize();
  1455. }
  1456. g_avLightDirs[0].Normalize();
  1457. }
  1458. return 1;
  1459. }
  1460. //-------------------------------------------------------------------------------
  1461. int CDisplay::HandleInputEmptyScene()
  1462. {
  1463. if(CBackgroundPainter::TEXTURE_CUBE == CBackgroundPainter::Instance().GetMode())
  1464. {
  1465. if (g_bFPSView)
  1466. {
  1467. HandleMouseInputFPS();
  1468. HandleKeyboardInputFPS();
  1469. }
  1470. HandleMouseInputSkyBox();
  1471. // need to store the last mouse position in the global variable
  1472. // HandleMouseInputFPS() is doing this internally
  1473. if (!g_bFPSView)
  1474. {
  1475. g_LastmousePos.x = g_mousePos.x;
  1476. g_LastmousePos.y = g_mousePos.y;
  1477. }
  1478. }
  1479. return 1;
  1480. }
  1481. //-------------------------------------------------------------------------------
  1482. int CDisplay::DrawHUD()
  1483. {
  1484. // get the dimension of the back buffer
  1485. RECT sRect;
  1486. GetWindowRect(GetDlgItem(g_hDlg,IDC_RT),&sRect);
  1487. sRect.right -= sRect.left;
  1488. sRect.bottom -= sRect.top;
  1489. struct SVertex
  1490. {
  1491. float x,y,z,w,u,v;
  1492. };
  1493. // commit the texture to the shader
  1494. // FIX: Necessary because the texture view is also using this shader
  1495. g_piPassThroughEffect->SetTexture("TEXTURE_2D",g_pcTexture);
  1496. // NOTE: The shader might be used for other purposes, too.
  1497. // So ensure the right technique is there
  1498. g_piPassThroughEffect->SetTechnique("PassThrough");
  1499. // build vertices for drawing from system memory
  1500. UINT dw;
  1501. g_piPassThroughEffect->Begin(&dw,0);
  1502. g_piPassThroughEffect->BeginPass(0);
  1503. D3DSURFACE_DESC sDesc;
  1504. g_pcTexture->GetLevelDesc(0,&sDesc);
  1505. SVertex as[4];
  1506. float fHalfX = ((float)sRect.right-(float)sDesc.Width) / 2.0f;
  1507. float fHalfY = ((float)sRect.bottom-(float)sDesc.Height) / 2.0f;
  1508. as[1].x = fHalfX;
  1509. as[1].y = fHalfY;
  1510. as[1].z = 0.2f;
  1511. as[1].w = 1.0f;
  1512. as[1].u = 0.0f;
  1513. as[1].v = 0.0f;
  1514. as[3].x = (float)sRect.right-fHalfX;
  1515. as[3].y = fHalfY;
  1516. as[3].z = 0.2f;
  1517. as[3].w = 1.0f;
  1518. as[3].u = 1.0f;
  1519. as[3].v = 0.0f;
  1520. as[0].x = fHalfX;
  1521. as[0].y = (float)sRect.bottom-fHalfY;
  1522. as[0].z = 0.2f;
  1523. as[0].w = 1.0f;
  1524. as[0].u = 0.0f;
  1525. as[0].v = 1.0f;
  1526. as[2].x = (float)sRect.right-fHalfX;
  1527. as[2].y = (float)sRect.bottom-fHalfY;
  1528. as[2].z = 0.2f;
  1529. as[2].w = 1.0f;
  1530. as[2].u = 1.0f;
  1531. as[2].v = 1.0f;
  1532. as[0].x -= 0.5f;as[1].x -= 0.5f;as[2].x -= 0.5f;as[3].x -= 0.5f;
  1533. as[0].y -= 0.5f;as[1].y -= 0.5f;as[2].y -= 0.5f;as[3].y -= 0.5f;
  1534. // draw the screen-filling squad
  1535. DWORD dw2;g_piDevice->GetFVF(&dw2);
  1536. g_piDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
  1537. g_piDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,
  1538. &as,sizeof(SVertex));
  1539. // end the effect and recover the old vertex format
  1540. g_piPassThroughEffect->EndPass();
  1541. g_piPassThroughEffect->End();
  1542. g_piDevice->SetFVF(dw2);
  1543. return 1;
  1544. }
  1545. //-------------------------------------------------------------------------------
  1546. int CDisplay::RenderFullScene()
  1547. {
  1548. // reset the color index used for drawing normals
  1549. g_iCurrentColor = 0;
  1550. // reset frame counter and rotation tracker
  1551. CMeshRenderer::Instance().OnBeginFrame();
  1552. // setup wireframe/solid rendering mode
  1553. if (g_sOptions.eDrawMode == RenderOptions::WIREFRAME)
  1554. {
  1555. g_piDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);
  1556. }
  1557. else g_piDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID);
  1558. // draw the scene background (clear and texture 2d)
  1559. CBackgroundPainter::Instance().OnPreRender();
  1560. // setup the stereo view if necessary
  1561. if (g_sOptions.bStereoView)
  1562. {
  1563. this->SetupStereoView();
  1564. }
  1565. // draw all opaque objects in the scene
  1566. aiMatrix4x4 m;
  1567. if (NULL != g_pcAsset && NULL != g_pcAsset->pcScene->mRootNode)
  1568. {
  1569. this->HandleInput();
  1570. m = g_mWorld * g_mWorldRotate;
  1571. RenderNode(g_pcAsset->pcScene->mRootNode,m,false);
  1572. }
  1573. // if a cube texture is loaded as background image, the user
  1574. // should be able to rotate it even if no asset is loaded
  1575. this->HandleInputEmptyScene();
  1576. // draw the scene background
  1577. CBackgroundPainter::Instance().OnPostRender();
  1578. // draw all non-opaque objects in the scene
  1579. if (NULL != g_pcAsset && NULL != g_pcAsset->pcScene->mRootNode)
  1580. {
  1581. // disable the z-buffer
  1582. g_piDevice->SetRenderState(D3DRS_ZWRITEENABLE,FALSE);
  1583. RenderNode(g_pcAsset->pcScene->mRootNode,m,true);
  1584. g_piDevice->SetRenderState(D3DRS_ZWRITEENABLE,TRUE);
  1585. }
  1586. // setup the stereo view if necessary
  1587. if (g_sOptions.bStereoView)
  1588. {
  1589. this->RenderStereoView(m);
  1590. }
  1591. // draw the HUD texture on top of the rendered scene using
  1592. // pre-projected vertices
  1593. if (!g_bFPSView && g_pcAsset && g_pcTexture)
  1594. {
  1595. this->DrawHUD();
  1596. }
  1597. return 1;
  1598. }
  1599. //-------------------------------------------------------------------------------
  1600. int CDisplay::RenderMaterialView()
  1601. {
  1602. return 1;
  1603. }
  1604. //-------------------------------------------------------------------------------
  1605. int CDisplay::RenderNode (aiNode* piNode,const aiMatrix4x4& piMatrix,
  1606. bool bAlpha /*= false*/)
  1607. {
  1608. aiMatrix4x4 mTemp = piNode->mTransformation;
  1609. mTemp.Transpose();
  1610. aiMatrix4x4 aiMe = mTemp * piMatrix;
  1611. bool bChangedVM = false;
  1612. if (VIEWMODE_NODE == this->m_iViewMode && this->m_pcCurrentNode)
  1613. {
  1614. if (piNode != this->m_pcCurrentNode->psNode)
  1615. {
  1616. if (0 != piNode->mNumChildren)
  1617. {
  1618. // directly call our children
  1619. for (unsigned int i = 0; i < piNode->mNumChildren;++i)
  1620. {
  1621. RenderNode(piNode->mChildren[i],aiMe,bAlpha );
  1622. }
  1623. }
  1624. return 1;
  1625. }
  1626. this->m_iViewMode = VIEWMODE_FULL;
  1627. bChangedVM = true;
  1628. }
  1629. aiMatrix4x4 pcProj;
  1630. GetProjectionMatrix(pcProj);
  1631. aiMatrix4x4 pcCam;
  1632. aiVector3D vPos = GetCameraMatrix(pcCam);
  1633. pcProj = (aiMe * pcCam) * pcProj;
  1634. pcCam = aiMe;
  1635. pcCam.Inverse().Transpose();
  1636. // VERY UNOPTIMIZED, much stuff is redundant. Who cares?
  1637. if (!g_sOptions.bRenderMats && !bAlpha)
  1638. {
  1639. // this is very similar to the code in SetupMaterial()
  1640. ID3DXEffect* piEnd = g_piDefaultEffect;
  1641. // commit transformation matrices to the shader
  1642. piEnd->SetMatrix("WorldViewProjection",
  1643. (const D3DXMATRIX*)&pcProj);
  1644. piEnd->SetMatrix("World",(const D3DXMATRIX*)&aiMe);
  1645. piEnd->SetMatrix("WorldInverseTranspose",
  1646. (const D3DXMATRIX*)&pcCam);
  1647. if ( CBackgroundPainter::TEXTURE_CUBE == CBackgroundPainter::Instance().GetMode())
  1648. {
  1649. pcCam = pcCam * pcProj;
  1650. piEnd->SetMatrix("ViewProj",(const D3DXMATRIX*)&pcCam);
  1651. pcCam.Inverse();
  1652. piEnd->SetMatrix("InvViewProj",(const D3DXMATRIX*)&pcCam);
  1653. }
  1654. // commit light colors and direction to the shader
  1655. D3DXVECTOR4 apcVec[5];
  1656. apcVec[0].x = g_avLightDirs[0].x;
  1657. apcVec[0].y = g_avLightDirs[0].y;
  1658. apcVec[0].z = g_avLightDirs[0].z;
  1659. apcVec[1].x = g_avLightDirs[0].x * -1.0f;
  1660. apcVec[1].y = g_avLightDirs[0].y * -1.0f;
  1661. apcVec[1].z = g_avLightDirs[0].z * -1.0f;
  1662. D3DXVec4Normalize(&apcVec[0],&apcVec[0]);
  1663. D3DXVec4Normalize(&apcVec[1],&apcVec[1]);
  1664. piEnd->SetVectorArray("afLightDir",apcVec,5);
  1665. apcVec[0].x = ((g_avLightColors[0] >> 16) & 0xFF) / 255.0f;
  1666. apcVec[0].y = ((g_avLightColors[0] >> 8) & 0xFF) / 255.0f;
  1667. apcVec[0].z = ((g_avLightColors[0]) & 0xFF) / 255.0f;
  1668. apcVec[0].w = 1.0f;
  1669. apcVec[1].x = ((g_avLightColors[1] >> 16) & 0xFF) / 255.0f;
  1670. apcVec[1].y = ((g_avLightColors[1] >> 8) & 0xFF) / 255.0f;
  1671. apcVec[1].z = ((g_avLightColors[1]) & 0xFF) / 255.0f;
  1672. apcVec[1].w = 0.0f;
  1673. apcVec[0] *= g_fLightIntensity;
  1674. apcVec[1] *= g_fLightIntensity;
  1675. piEnd->SetVectorArray("afLightColor",apcVec,5);
  1676. apcVec[0].x = vPos.x;
  1677. apcVec[0].y = vPos.y;
  1678. apcVec[0].z = vPos.z;
  1679. piEnd->SetVector( "vCameraPos",&apcVec[0]);
  1680. // setup the best technique
  1681. if (g_sCaps.PixelShaderVersion < D3DPS_VERSION(3,0) || g_sOptions.bLowQuality)
  1682. {
  1683. if (g_sOptions.b3Lights)
  1684. piEnd->SetTechnique("DefaultFXSpecular_PS20_D2");
  1685. else piEnd->SetTechnique("DefaultFXSpecular_PS20_D1");
  1686. }
  1687. else
  1688. {
  1689. if (g_sOptions.b3Lights)
  1690. piEnd->SetTechnique("DefaultFXSpecular_D2");
  1691. else piEnd->SetTechnique("DefaultFXSpecular_D1");
  1692. }
  1693. // setup the default material
  1694. UINT dwPasses = 0;
  1695. piEnd->Begin(&dwPasses,0);
  1696. piEnd->BeginPass(0);
  1697. }
  1698. D3DXVECTOR4 vVector = g_aclNormalColors[g_iCurrentColor];
  1699. if (++g_iCurrentColor == 14)
  1700. {
  1701. g_iCurrentColor = 0;
  1702. }
  1703. if (! (!g_sOptions.bRenderMats && bAlpha))
  1704. {
  1705. for (unsigned int i = 0; i < piNode->mNumMeshes;++i)
  1706. {
  1707. // don't render the mesh if the render pass is incorrect
  1708. if (g_sOptions.bRenderMats && (
  1709. g_pcAsset->apcMeshes[piNode->mMeshes[i]]->piOpacityTexture ||
  1710. g_pcAsset->apcMeshes[piNode->mMeshes[i]]->fOpacity != 1.0f))
  1711. {
  1712. if (!bAlpha)continue;
  1713. }
  1714. else if (bAlpha)continue;
  1715. // now setup the material
  1716. if (g_sOptions.bRenderMats)
  1717. {
  1718. CMaterialManager::Instance().SetupMaterial(
  1719. g_pcAsset->apcMeshes[piNode->mMeshes[i]],pcProj,aiMe,pcCam,vPos);
  1720. }
  1721. if (bAlpha)CMeshRenderer::Instance().DrawSorted(piNode->mMeshes[i],aiMe);
  1722. else CMeshRenderer::Instance().DrawUnsorted(piNode->mMeshes[i]);
  1723. // now end the material
  1724. if (g_sOptions.bRenderMats)
  1725. {
  1726. CMaterialManager::Instance().EndMaterial(
  1727. g_pcAsset->apcMeshes[piNode->mMeshes[i]]);
  1728. }
  1729. // render normal vectors?
  1730. if (g_sOptions.bRenderNormals && g_pcAsset->apcMeshes[piNode->mMeshes[i]]->piVBNormals)
  1731. {
  1732. // this is very similar to the code in SetupMaterial()
  1733. ID3DXEffect* piEnd = g_piNormalsEffect;
  1734. piEnd->SetVector("OUTPUT_COLOR",&vVector);
  1735. piEnd->SetMatrix("WorldViewProjection",
  1736. (const D3DXMATRIX*)&pcProj);
  1737. UINT dwPasses = 0;
  1738. piEnd->Begin(&dwPasses,0);
  1739. piEnd->BeginPass(0);
  1740. g_piDevice->SetStreamSource(0,
  1741. g_pcAsset->apcMeshes[piNode->mMeshes[i]]->piVBNormals,0,
  1742. sizeof(AssetHelper::LineVertex));
  1743. g_piDevice->DrawPrimitive(D3DPT_LINELIST,0,
  1744. g_pcAsset->pcScene->mMeshes[piNode->mMeshes[i]]->mNumVertices);
  1745. piEnd->EndPass();
  1746. piEnd->End();
  1747. }
  1748. }
  1749. // end the default material
  1750. if (!g_sOptions.bRenderMats)
  1751. {
  1752. g_piDefaultEffect->EndPass();
  1753. g_piDefaultEffect->End();
  1754. }
  1755. }
  1756. // render all child nodes
  1757. for (unsigned int i = 0; i < piNode->mNumChildren;++i)
  1758. {
  1759. RenderNode(piNode->mChildren[i],aiMe,bAlpha );
  1760. }
  1761. // need to reset the viewmode?
  1762. if (bChangedVM)
  1763. this->m_iViewMode = VIEWMODE_NODE;
  1764. return 1;
  1765. }
  1766. //-------------------------------------------------------------------------------
  1767. int CDisplay::RenderPatternBG()
  1768. {
  1769. if (!g_piPatternEffect)
  1770. {
  1771. // the pattern effect won't work on ps_2_0 cards
  1772. if (g_sCaps.PixelShaderVersion >= D3DPS_VERSION(3,0))
  1773. {
  1774. // seems we have not yet compiled this shader.
  1775. // and NOW is the best time to do that ...
  1776. ID3DXBuffer* piBuffer = NULL;
  1777. if(FAILED( D3DXCreateEffect(g_piDevice,
  1778. g_szCheckerBackgroundShader.c_str(),
  1779. (UINT)g_szCheckerBackgroundShader.length(),
  1780. NULL,
  1781. NULL,
  1782. D3DXSHADER_USE_LEGACY_D3DX9_31_DLL,
  1783. NULL,
  1784. &g_piPatternEffect,&piBuffer)))
  1785. {
  1786. if( piBuffer)
  1787. {
  1788. MessageBox(g_hDlg,(LPCSTR)piBuffer->GetBufferPointer(),"HLSL",MB_OK);
  1789. piBuffer->Release();
  1790. }
  1791. return 0;
  1792. }
  1793. if( piBuffer)
  1794. {
  1795. piBuffer->Release();
  1796. piBuffer = NULL;
  1797. }
  1798. }
  1799. else
  1800. {
  1801. // clear the color buffer in magenta
  1802. // (hopefully this is ugly enough that every ps_2_0 cards owner
  1803. // runs to the next shop to buy himself a new card ...)
  1804. g_piDevice->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
  1805. D3DCOLOR_ARGB(0xFF,0xFF,0,0xFF), 1.0f,0 );
  1806. return 1;
  1807. }
  1808. }
  1809. // clear the depth buffer only
  1810. g_piDevice->Clear(0,NULL,D3DCLEAR_ZBUFFER,
  1811. D3DCOLOR_ARGB(0xFF,0xFF,0,0xFF), 1.0f,0 );
  1812. // setup the colors to be used ...
  1813. g_piPatternEffect->SetVector("COLOR_ONE",&this->m_avCheckerColors[0]);
  1814. g_piPatternEffect->SetVector("COLOR_TWO",&this->m_avCheckerColors[1]);
  1815. // setup the shader
  1816. UINT dw;
  1817. g_piPatternEffect->Begin(&dw,0);
  1818. g_piPatternEffect->BeginPass(0);
  1819. RECT sRect;
  1820. GetWindowRect(GetDlgItem(g_hDlg,IDC_RT),&sRect);
  1821. sRect.right -= sRect.left;
  1822. sRect.bottom -= sRect.top;
  1823. struct SVertex
  1824. {
  1825. float x,y,z,w;
  1826. };
  1827. // build the screen-filling rectangle
  1828. SVertex as[4];
  1829. as[1].x = 0.0f;
  1830. as[1].y = 0.0f;
  1831. as[1].z = 0.2f;
  1832. as[3].x = (float)sRect.right;
  1833. as[3].y = 0.0f;
  1834. as[3].z = 0.2f;
  1835. as[0].x = 0.0f;
  1836. as[0].y = (float)sRect.bottom;
  1837. as[0].z = 0.2f;
  1838. as[2].x = (float)sRect.right;
  1839. as[2].y = (float)sRect.bottom;
  1840. as[2].z = 0.2f;
  1841. as[0].w = 1.0f;
  1842. as[1].w = 1.0f;
  1843. as[2].w = 1.0f;
  1844. as[3].w = 1.0f;
  1845. as[0].x -= 0.5f;as[1].x -= 0.5f;as[2].x -= 0.5f;as[3].x -= 0.5f;
  1846. as[0].y -= 0.5f;as[1].y -= 0.5f;as[2].y -= 0.5f;as[3].y -= 0.5f;
  1847. // draw the rectangle
  1848. DWORD dw2;g_piDevice->GetFVF(&dw2);
  1849. g_piDevice->SetFVF(D3DFVF_XYZRHW);
  1850. g_piDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,
  1851. &as,sizeof(SVertex));
  1852. g_piDevice->SetFVF(dw2);
  1853. // cleanup
  1854. g_piPatternEffect->EndPass();
  1855. g_piPatternEffect->End();
  1856. return 1;
  1857. }
  1858. //-------------------------------------------------------------------------------
  1859. int CDisplay::RenderTextureView()
  1860. {
  1861. if (!g_pcAsset || !g_pcAsset->pcScene)return 0;
  1862. // handle input
  1863. this->HandleInputTextureView();
  1864. // render the background
  1865. this->RenderPatternBG();
  1866. // it might be that there is no texture ...
  1867. if (!this->m_pcCurrentTexture->piTexture)
  1868. {
  1869. // FIX: no such log message. it would be repeated to often
  1870. //CLogDisplay::Instance().AddEntry("Unable to display texture. Image is unreachable.",
  1871. // D3DCOLOR_ARGB(0xFF,0xFF,0,0));
  1872. return 0;
  1873. }
  1874. RECT sRect;
  1875. GetWindowRect(GetDlgItem(g_hDlg,IDC_RT),&sRect);
  1876. sRect.right -= sRect.left;
  1877. sRect.bottom -= sRect.top;
  1878. // commit the texture to the shader
  1879. g_piPassThroughEffect->SetTexture("TEXTURE_2D",*this->m_pcCurrentTexture->piTexture);
  1880. if (AI_TEXTYPE_OPACITY == this->m_pcCurrentTexture->iType)
  1881. {
  1882. g_piPassThroughEffect->SetTechnique("PassThroughAlphaFromR");
  1883. }
  1884. else if ((AI_TEXTYPE_OPACITY | 0x40000000) == this->m_pcCurrentTexture->iType)
  1885. {
  1886. g_piPassThroughEffect->SetTechnique("PassThroughAlphaFromA");
  1887. }
  1888. else g_piPassThroughEffect->SetTechnique("PassThrough");
  1889. UINT dw;
  1890. g_piPassThroughEffect->Begin(&dw,0);
  1891. g_piPassThroughEffect->BeginPass(0);
  1892. if (AI_TEXTYPE_HEIGHT == this->m_pcCurrentTexture->iType ||
  1893. AI_TEXTYPE_NORMALS == this->m_pcCurrentTexture->iType)
  1894. {
  1895. // manually disable alpha blending
  1896. g_piDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE);
  1897. }
  1898. // build a rectangle which centers the texture
  1899. // scaling is OK, but no stretching
  1900. D3DSURFACE_DESC sDesc;
  1901. (*this->m_pcCurrentTexture->piTexture)->GetLevelDesc(0,&sDesc);
  1902. struct SVertex{float x,y,z,w,u,v;};
  1903. SVertex as[4];
  1904. const float nx = (float)sRect.right;
  1905. const float ny = (float)sRect.bottom;
  1906. const float x = (float)sDesc.Width;
  1907. const float y = (float)sDesc.Height;
  1908. float f = std::min((nx-30) / x,(ny-30) / y) * (this->m_fTextureZoom/1000.0f);
  1909. float fHalfX = (nx - (f * x)) / 2.0f;
  1910. float fHalfY = (ny - (f * y)) / 2.0f;
  1911. as[1].x = fHalfX + this->m_vTextureOffset.x;
  1912. as[1].y = fHalfY + this->m_vTextureOffset.y;
  1913. as[1].z = 0.2f;
  1914. as[1].w = 1.0f;
  1915. as[1].u = 0.0f;
  1916. as[1].v = 0.0f;
  1917. as[3].x = nx-fHalfX + this->m_vTextureOffset.x;
  1918. as[3].y = fHalfY + this->m_vTextureOffset.y;
  1919. as[3].z = 0.2f;
  1920. as[3].w = 1.0f;
  1921. as[3].u = 1.0f;
  1922. as[3].v = 0.0f;
  1923. as[0].x = fHalfX + this->m_vTextureOffset.x;
  1924. as[0].y = ny-fHalfY + this->m_vTextureOffset.y;
  1925. as[0].z = 0.2f;
  1926. as[0].w = 1.0f;
  1927. as[0].u = 0.0f;
  1928. as[0].v = 1.0f;
  1929. as[2].x = nx-fHalfX + this->m_vTextureOffset.x;
  1930. as[2].y = ny-fHalfY + this->m_vTextureOffset.y;
  1931. as[2].z = 0.2f;
  1932. as[2].w = 1.0f;
  1933. as[2].u = 1.0f;
  1934. as[2].v = 1.0f;
  1935. as[0].x -= 0.5f;as[1].x -= 0.5f;as[2].x -= 0.5f;as[3].x -= 0.5f;
  1936. as[0].y -= 0.5f;as[1].y -= 0.5f;as[2].y -= 0.5f;as[3].y -= 0.5f;
  1937. // draw the rectangle
  1938. DWORD dw2;g_piDevice->GetFVF(&dw2);
  1939. g_piDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
  1940. g_piDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,
  1941. &as,sizeof(SVertex));
  1942. g_piDevice->SetFVF(dw2);
  1943. g_piPassThroughEffect->EndPass();
  1944. g_piPassThroughEffect->End();
  1945. // do we need to draw UV coordinates?
  1946. return 1;
  1947. }
  1948. };