Background.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. //-------------------------------------------------------------------------------
  2. /**
  3. * This program is distributed under the terms of the GNU Lesser General
  4. * Public License (LGPL).
  5. *
  6. * ASSIMP Viewer Utility
  7. *
  8. */
  9. //-------------------------------------------------------------------------------
  10. #include "stdafx.h"
  11. #include "assimp_view.h"
  12. namespace AssimpView {
  13. // From: U3D build 1256 (src\kernel\graphic\scenegraph\SkyBox.cpp)
  14. // ------------------------------------------------------------------------------
  15. /** \brief Vertex structure for the skybox
  16. */
  17. // ------------------------------------------------------------------------------
  18. struct SkyBoxVertex
  19. {
  20. float x,y,z;
  21. float u,v,w;
  22. };
  23. // ------------------------------------------------------------------------------
  24. /** \brief Vertices for the skybox
  25. */
  26. // ------------------------------------------------------------------------------
  27. SkyBoxVertex g_cubeVertices_indexed[] =
  28. {
  29. { -1.0f, 1.0f, -1.0f, -1.0f,1.0f,-1.0f }, // 0
  30. { 1.0f, 1.0f, -1.0f, 1.0f,1.0f,-1.0f }, // 1
  31. { -1.0f, -1.0f, -1.0f, -1.0f,-1.0f,-1.0f }, // 2
  32. { 1.0f,-1.0f,-1.0f, 1.0f,-1.0f,-1.0f }, // 3
  33. {-1.0f, 1.0f, 1.0f, -1.0f,1.0f,1.0f }, // 4
  34. {-1.0f,-1.0f, 1.0f, -1.0f,-1.0f,1.0f }, // 5
  35. { 1.0f, 1.0f, 1.0f, 1.0f,1.0f,1.0f }, // 6
  36. { 1.0f,-1.0f, 1.0f, 1.0f,-1.0f,1.0f } // 7
  37. };
  38. // ------------------------------------------------------------------------------
  39. /** \brief Indices for the skybox
  40. */
  41. // ------------------------------------------------------------------------------
  42. unsigned short g_cubeIndices[] =
  43. {
  44. 0, 1, 2, 3, 2, 1,4, 5, 6,
  45. 7, 6, 5, 4, 6, 0, 1, 6, 0,
  46. 5, 2, 7,3, 2, 7, 1, 6, 3,
  47. 7, 3, 6, 0, 2, 4, 5, 4, 2,
  48. };
  49. CBackgroundPainter CBackgroundPainter::s_cInstance;
  50. //-------------------------------------------------------------------------------
  51. void CBackgroundPainter::SetColor (D3DCOLOR p_clrNew)
  52. {
  53. if (TEXTURE_CUBE == this->eMode)this->RemoveSBDeps();
  54. this->clrColor = p_clrNew;
  55. this->eMode = SIMPLE_COLOR;
  56. if (this->pcTexture)
  57. {
  58. this->pcTexture->Release();
  59. this->pcTexture = NULL;
  60. }
  61. }
  62. //-------------------------------------------------------------------------------
  63. void CBackgroundPainter::RemoveSBDeps()
  64. {
  65. MODE e = this->eMode;
  66. this->eMode = SIMPLE_COLOR;
  67. if (g_pcAsset && g_pcAsset->pcScene)
  68. {
  69. for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
  70. {
  71. if (aiShadingMode_Gouraud != g_pcAsset->apcMeshes[i]->eShadingMode)
  72. {
  73. DeleteMaterial(g_pcAsset->apcMeshes[i]);
  74. CreateMaterial(g_pcAsset->apcMeshes[i],g_pcAsset->pcScene->mMeshes[i]);
  75. }
  76. }
  77. }
  78. this->eMode = e;
  79. }
  80. //-------------------------------------------------------------------------------
  81. void CBackgroundPainter::ResetSB()
  82. {
  83. this->mMatrix = aiMatrix4x4();
  84. }
  85. //-------------------------------------------------------------------------------
  86. void CBackgroundPainter::SetCubeMapBG (const char* p_szPath)
  87. {
  88. bool bHad = false;
  89. if (this->pcTexture)
  90. {
  91. this->pcTexture->Release();
  92. this->pcTexture = NULL;
  93. if(TEXTURE_CUBE ==this->eMode)bHad = true;
  94. }
  95. this->eMode = TEXTURE_CUBE;
  96. this->szPath = std::string( p_szPath );
  97. // ARRRGHH... ugly. TODO: Rewrite this!
  98. aiString sz;
  99. sz.Set(this->szPath);
  100. FindValidPath(&sz);
  101. this->szPath = std::string( sz.data );
  102. // now recreate all native resources
  103. this->RecreateNativeResource();
  104. if (SIMPLE_COLOR != this->eMode)
  105. {
  106. // this influences all material with specular components
  107. if (!bHad)
  108. {
  109. if (g_pcAsset && g_pcAsset->pcScene)
  110. {
  111. for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
  112. {
  113. if (aiShadingMode_Phong == g_pcAsset->apcMeshes[i]->eShadingMode)
  114. {
  115. DeleteMaterial(g_pcAsset->apcMeshes[i]);
  116. CreateMaterial(g_pcAsset->apcMeshes[i],g_pcAsset->pcScene->mMeshes[i]);
  117. }
  118. }
  119. }
  120. }
  121. else
  122. {
  123. if (g_pcAsset && g_pcAsset->pcScene)
  124. {
  125. for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
  126. {
  127. if (aiShadingMode_Phong == g_pcAsset->apcMeshes[i]->eShadingMode)
  128. {
  129. g_pcAsset->apcMeshes[i]->piEffect->SetTexture(
  130. "lw_tex_envmap",CBackgroundPainter::Instance().GetTexture());
  131. }
  132. }
  133. }
  134. }
  135. }
  136. }
  137. //-------------------------------------------------------------------------------
  138. void CBackgroundPainter::RotateSB(const aiMatrix4x4* pm)
  139. {
  140. this->mMatrix = this->mMatrix * (*pm);
  141. }
  142. //-------------------------------------------------------------------------------
  143. void CBackgroundPainter::SetTextureBG (const char* p_szPath)
  144. {
  145. if (TEXTURE_CUBE == this->eMode)this->RemoveSBDeps();
  146. if (this->pcTexture)
  147. {
  148. this->pcTexture->Release();
  149. this->pcTexture = NULL;
  150. }
  151. this->eMode = TEXTURE_2D;
  152. this->szPath = std::string( p_szPath );
  153. // ARRRGHH... ugly. TODO: Rewrite this!
  154. aiString sz;
  155. sz.Set(this->szPath);
  156. FindValidPath(&sz);
  157. this->szPath = std::string( sz.data );
  158. // now recreate all native resources
  159. this->RecreateNativeResource();
  160. }
  161. //-------------------------------------------------------------------------------
  162. void CBackgroundPainter::OnPreRender()
  163. {
  164. if (SIMPLE_COLOR != this->eMode)
  165. {
  166. // clear the z-buffer only (in wireframe mode we must also clear
  167. // the color buffer )
  168. if (g_sOptions.eDrawMode == RenderOptions::WIREFRAME)
  169. {
  170. g_piDevice->Clear(0,NULL,D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET,
  171. D3DCOLOR_ARGB(0xff,100,100,100),1.0f,0);
  172. }
  173. else
  174. {
  175. g_piDevice->Clear(0,NULL,D3DCLEAR_ZBUFFER,0,1.0f,0);
  176. }
  177. if (TEXTURE_2D == this->eMode)
  178. {
  179. RECT sRect;
  180. GetWindowRect(GetDlgItem(g_hDlg,IDC_RT),&sRect);
  181. sRect.right -= sRect.left;
  182. sRect.bottom -= sRect.top;
  183. struct SVertex
  184. {
  185. float x,y,z,w,u,v;
  186. };
  187. UINT dw;
  188. this->piSkyBoxEffect->Begin(&dw,0);
  189. this->piSkyBoxEffect->BeginPass(0);
  190. SVertex as[4];
  191. as[1].x = 0.0f;
  192. as[1].y = 0.0f;
  193. as[1].z = 0.2f;
  194. as[1].w = 1.0f;
  195. as[1].u = 0.0f;
  196. as[1].v = 0.0f;
  197. as[3].x = (float)sRect.right;
  198. as[3].y = 0.0f;
  199. as[3].z = 0.2f;
  200. as[3].w = 1.0f;
  201. as[3].u = 1.0f;
  202. as[3].v = 0.0f;
  203. as[0].x = 0.0f;
  204. as[0].y = (float)sRect.bottom;
  205. as[0].z = 0.2f;
  206. as[0].w = 1.0f;
  207. as[0].u = 0.0f;
  208. as[0].v = 1.0f;
  209. as[2].x = (float)sRect.right;
  210. as[2].y = (float)sRect.bottom;
  211. as[2].z = 0.2f;
  212. as[2].w = 1.0f;
  213. as[2].u = 1.0f;
  214. as[2].v = 1.0f;
  215. as[0].x -= 0.5f;as[1].x -= 0.5f;as[2].x -= 0.5f;as[3].x -= 0.5f;
  216. as[0].y -= 0.5f;as[1].y -= 0.5f;as[2].y -= 0.5f;as[3].y -= 0.5f;
  217. DWORD dw2;g_piDevice->GetFVF(&dw2);
  218. g_piDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
  219. g_piDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,
  220. &as,sizeof(SVertex));
  221. this->piSkyBoxEffect->EndPass();
  222. this->piSkyBoxEffect->End();
  223. g_piDevice->SetFVF(dw2);
  224. }
  225. return;
  226. }
  227. // clear both the render target and the z-buffer
  228. g_piDevice->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
  229. this->clrColor,1.0f,0);
  230. }
  231. //-------------------------------------------------------------------------------
  232. void CBackgroundPainter::OnPostRender()
  233. {
  234. if (TEXTURE_CUBE == this->eMode)
  235. {
  236. aiMatrix4x4 pcProj;
  237. GetProjectionMatrix(pcProj);
  238. aiMatrix4x4 pcCam;
  239. aiVector3D vPos = GetCameraMatrix(pcCam);
  240. aiMatrix4x4 aiMe;
  241. aiMe[3][0] = vPos.x;
  242. aiMe[3][1] = vPos.y;
  243. aiMe[3][2] = vPos.z;
  244. aiMe = this->mMatrix * aiMe;
  245. pcProj = (aiMe * pcCam) * pcProj;
  246. this->piSkyBoxEffect->SetMatrix("WorldViewProjection",
  247. (const D3DXMATRIX*)&pcProj);
  248. UINT dwPasses;
  249. this->piSkyBoxEffect->Begin(&dwPasses,0);
  250. this->piSkyBoxEffect->BeginPass(0);
  251. DWORD dw2;
  252. g_piDevice->GetFVF(&dw2);
  253. g_piDevice->SetFVF(D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
  254. g_piDevice->DrawIndexedPrimitiveUP(
  255. D3DPT_TRIANGLELIST,0,8,12,g_cubeIndices,D3DFMT_INDEX16,
  256. g_cubeVertices_indexed,sizeof(SkyBoxVertex));
  257. g_piDevice->SetFVF(dw2);
  258. this->piSkyBoxEffect->EndPass();
  259. this->piSkyBoxEffect->End();
  260. }
  261. }
  262. //-------------------------------------------------------------------------------
  263. void CBackgroundPainter::ReleaseNativeResource()
  264. {
  265. if (this->piSkyBoxEffect)
  266. {
  267. this->piSkyBoxEffect->Release();
  268. this->piSkyBoxEffect = NULL;
  269. }
  270. if (this->pcTexture)
  271. {
  272. this->pcTexture->Release();
  273. this->pcTexture = NULL;
  274. }
  275. }
  276. //-------------------------------------------------------------------------------
  277. void CBackgroundPainter::RecreateNativeResource()
  278. {
  279. if (SIMPLE_COLOR == this->eMode)return;
  280. if (TEXTURE_CUBE == this->eMode)
  281. {
  282. // many skyboxes are 16bit FP format which isn't supported
  283. // with bilinear filtering on older cards
  284. D3DFORMAT eFmt = D3DFMT_UNKNOWN;
  285. if(FAILED(g_piD3D->CheckDeviceFormat(0,D3DDEVTYPE_HAL,
  286. D3DFMT_X8R8G8B8,D3DUSAGE_QUERY_FILTER,D3DRTYPE_CUBETEXTURE,D3DFMT_A16B16G16R16F)))
  287. {
  288. eFmt = D3DFMT_A8R8G8B8;
  289. }
  290. if (FAILED(D3DXCreateCubeTextureFromFileEx(
  291. g_piDevice,
  292. this->szPath.c_str(),
  293. D3DX_DEFAULT,
  294. 0,
  295. 0,
  296. eFmt,
  297. D3DPOOL_MANAGED,
  298. D3DX_DEFAULT,
  299. D3DX_DEFAULT,
  300. 0,
  301. NULL,
  302. NULL,
  303. (IDirect3DCubeTexture9**)&this->pcTexture)))
  304. {
  305. const char* szEnd = strrchr(this->szPath.c_str(),'\\');
  306. if (!szEnd)szEnd = strrchr(this->szPath.c_str(),'/');
  307. if (!szEnd)szEnd = this->szPath.c_str()-1;
  308. char szTemp[1024];
  309. sprintf(szTemp,"[ERROR] Unable to load background cubemap %s",szEnd+1);
  310. CLogDisplay::Instance().AddEntry(szTemp,
  311. D3DCOLOR_ARGB(0xFF,0xFF,0,0));
  312. this->eMode = SIMPLE_COLOR;
  313. return;
  314. }
  315. else CLogDisplay::Instance().AddEntry("[OK] The skybox has been imported successfully",
  316. D3DCOLOR_ARGB(0xFF,0,0xFF,0));
  317. }
  318. else
  319. {
  320. if (FAILED(D3DXCreateTextureFromFileEx(
  321. g_piDevice,
  322. this->szPath.c_str(),
  323. D3DX_DEFAULT,
  324. D3DX_DEFAULT,
  325. 0,
  326. 0,
  327. D3DFMT_A8R8G8B8,
  328. D3DPOOL_MANAGED,
  329. D3DX_DEFAULT,
  330. D3DX_DEFAULT,
  331. 0,
  332. NULL,
  333. NULL,
  334. (IDirect3DTexture9**)&this->pcTexture)))
  335. {
  336. const char* szEnd = strrchr(this->szPath.c_str(),'\\');
  337. if (!szEnd)szEnd = strrchr(this->szPath.c_str(),'/');
  338. if (!szEnd)szEnd = this->szPath.c_str()-1;
  339. char szTemp[1024];
  340. sprintf(szTemp,"[ERROR] Unable to load background texture %s",szEnd+1);
  341. CLogDisplay::Instance().AddEntry(szTemp,
  342. D3DCOLOR_ARGB(0xFF,0xFF,0,0));
  343. this->eMode = SIMPLE_COLOR;
  344. return;
  345. }
  346. else CLogDisplay::Instance().AddEntry("[OK] The background texture has been imported successfully",
  347. D3DCOLOR_ARGB(0xFF,0,0xFF,0));
  348. }
  349. if (!piSkyBoxEffect)
  350. {
  351. if(FAILED( D3DXCreateEffect(
  352. g_piDevice,
  353. g_szSkyboxShader.c_str(),
  354. (UINT)g_szSkyboxShader.length(),
  355. NULL,
  356. NULL,
  357. D3DXSHADER_USE_LEGACY_D3DX9_31_DLL,
  358. NULL,
  359. &this->piSkyBoxEffect,NULL)))
  360. {
  361. CLogDisplay::Instance().AddEntry("[ERROR] Unable to compile skybox shader",
  362. D3DCOLOR_ARGB(0xFF,0xFF,0,0));
  363. this->eMode = SIMPLE_COLOR;
  364. return ;
  365. }
  366. }
  367. // commit the correct textures to the shader
  368. if (TEXTURE_CUBE == this->eMode)
  369. {
  370. this->piSkyBoxEffect->SetTexture("lw_tex_envmap",this->pcTexture);
  371. this->piSkyBoxEffect->SetTechnique("RenderSkyBox");
  372. }
  373. else if (TEXTURE_2D == this->eMode)
  374. {
  375. this->piSkyBoxEffect->SetTexture("TEXTURE_2D",this->pcTexture);
  376. this->piSkyBoxEffect->SetTechnique("RenderImage2D");
  377. }
  378. }
  379. };