3DWindow.cpp
上传用户:fengshi120
上传日期:2014-07-17
资源大小:6155k
文件大小:30k
源码类别:

3D图形编程

开发平台:

C/C++

  1. ////////////////////////////////////////////////////////////////////////////////////////////////
  2. // Copyright: Frey Research 
  3. // Unit Name: 3DWindow.cpp 
  4. // Author:     Gary Gray
  5. // Description: custom control for displaying 3-D shapes
  6. /////////////////////////////////////////////////////////////////////////////////////////////////
  7. // 3DWindowSmall.cpp : implementation file
  8. //
  9. #include "stdafx.h"
  10. #include "StereoPlus.h"
  11. #include "StereoPlusDlg.h"
  12. #include <mmSystem.h>
  13. #include "DxUtil.h"
  14. #include <d3d9types.h>
  15. #include "3DWindow.h"
  16. #include ".3DWindow.h"
  17. #ifdef _DEBUG
  18. #define new DEBUG_NEW
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22.  
  23. extern CStereoPlusDlg* pMainDialog;
  24. #define DELETENULL(object) if (object) {delete object;object = NULL;}
  25. #define  RELEASENULL(object) if (object) {object->Release();object = NULL;}
  26. //////////////////////////////////////////////////////////////////////////////
  27. // Globals ///////////////////////////////////////////////////////////////////
  28. //////////////////////////////////////////////////////////////////////////////
  29. struct POINT_VERTEX
  30. {
  31.     D3DXVECTOR3 p;
  32.     D3DCOLOR color;
  33. // static const DWORD FVF;
  34. };
  35. const DWORD POINT_VERTEX_FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE ;
  36. struct MESH_VERTEX_TEX
  37. {
  38.     D3DXVECTOR3 p;
  39.     D3DXVECTOR3 n;
  40. FLOAT tu,tv;
  41. // static const DWORD FVF;
  42. };
  43. const DWORD MESH_VERTEX_TEX_FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0);
  44. BOOL C3DWindow::m_Registered = FALSE;
  45. BOOL C3DWindow::m_bInhibitUpdate = FALSE;
  46. /*lint -save*/
  47. /*lint -e620 ignore Suspicious constant (L or one?) these are all from Microsoft !*/
  48. /*lint -e834 ignore comments on confusing operators there not to me !*/
  49. /////////////////////////////////////////////////////////////////////////////
  50. // C3DWindow
  51. C3DWindow::C3DWindow() : CWnd()
  52. {
  53. m_bOrthographic = false;
  54. m_pD3D = NULL;
  55. m_pD3DDevice = NULL;
  56. m_GUITimerID = NULL;
  57. m_fScale = 1.0F;
  58. m_bRenderZAxis = false;
  59. for(int k=0;k<3;k++)
  60. m_pAxesVB[k] = NULL;
  61. //initialise some memory to please PC-Lint
  62. ZeroMemory(&m_light,sizeof(D3DLIGHT9));
  63. ZeroMemory(&m_D3DsdBackBuffer,sizeof(D3DSURFACE_DESC));
  64. m_strRegistry = "3D Orientation";
  65. UINT uNBytes;
  66. CD3DArcBall* pArcBallProfile = NULL;
  67. theApp.GetProfileBinary("3D Window",m_strRegistry,(LPBYTE*)&pArcBallProfile,&uNBytes);
  68. if(uNBytes == sizeof(CD3DArcBall) && pArcBallProfile)
  69. m_ArcBall = *pArcBallProfile;
  70. DELETENULL(pArcBallProfile);
  71. m_pFont = new CD3DFont( _T("Arial"), 10,NULL);// D3DFONT_BOLD );
  72. m_pFontLarge = new CD3DFont( _T("Arial"), 16,NULL);// D3DFONT_BOLD );
  73. m_pTextureAxisLabelX = NULL;
  74. m_pTextureAxisLabelY = NULL;
  75. m_pTextureAxisLabelZ = NULL;
  76. m_pPixelVB  = NULL;
  77. m_nPoints = 0;
  78. for(int iCone = 0;iCone<3;iCone++)
  79. m_pConeMesh[iCone] = NULL;
  80. }
  81. void C3DWindow::SetRegistryKey(CString strRegistry)
  82. {
  83. m_strRegistry = strRegistry;
  84. UINT uNBytes;
  85. CD3DArcBall* pArcBallProfile = NULL;
  86. theApp.GetProfileBinary("3D Window",m_strRegistry,(LPBYTE*)&pArcBallProfile,&uNBytes);
  87. if(uNBytes == sizeof(CD3DArcBall) && pArcBallProfile)
  88. m_ArcBall = *pArcBallProfile;
  89. DELETENULL(pArcBallProfile);
  90. }
  91. C3DWindow::~C3DWindow()
  92. {
  93. try
  94. {
  95.     SAFE_DELETE( m_pFont );
  96.     SAFE_DELETE( m_pFontLarge );
  97. ASSERT(m_pD3D == NULL);
  98. ASSERT(m_pD3DDevice == NULL);
  99. }
  100. catch (...) {};
  101. }
  102. void C3DWindow::OnNcDestroy() 
  103. {
  104. CWnd::OnNcDestroy();
  105. delete this;
  106. }
  107. BEGIN_MESSAGE_MAP(C3DWindow, CWnd)
  108. //{{AFX_MSG_MAP(C3DWindow)
  109. ON_WM_CREATE()
  110. ON_WM_DESTROY()
  111. ON_WM_NCDESTROY()
  112. ON_WM_RBUTTONUP()
  113. ON_WM_INITMENUPOPUP()
  114. //}}AFX_MSG_MAP
  115. ON_WM_PAINT()
  116. ON_WM_CHAR()
  117. ON_WM_TIMER()
  118. ON_WM_MOUSEMOVE()
  119. ON_WM_LBUTTONDOWN()
  120. ON_WM_LBUTTONUP()
  121. ON_WM_LBUTTONDBLCLK()
  122. END_MESSAGE_MAP()
  123. void C3DWindow::InterpretError(HRESULT hr) const
  124. {
  125. CString strError;
  126. strError = DXGetErrorString9 (hr);
  127. #ifdef _DEBUG
  128. AfxMessageBox(strError,MB_OK);
  129. #endif
  130. }
  131. /////////////////////////////////////////////////////////////////////////////
  132. // C3DWindow message handlers
  133. void C3DWindow::OnRButtonUp(UINT nFlags, CPoint point) 
  134. {
  135. long ControlID = GetWindowLong(m_hWnd,GWL_ID);
  136. CWnd* pParent = GetParent();
  137. LRESULT lResult = pParent->SendMessage(WM_COMMAND,MAKEWPARAM(ControlID,WM_RBUTTONUP),(LPARAM)(HWND)m_hWnd);
  138. if(!lResult)
  139. CWnd::OnRButtonUp(nFlags, point);
  140. }
  141. void C3DWindow::ShowMenu(UINT idrMenu)
  142. CMenu Pum, *pPum;
  143. Pum.LoadMenu(idrMenu);
  144. pPum = Pum.GetSubMenu(0);
  145. CPoint pt;
  146. GetCursorPos(&pt);
  147. pPum->TrackPopupMenu(TPM_CENTERALIGN | TPM_LEFTBUTTON, pt.x, pt.y-18, this);
  148. }
  149. BOOL C3DWindow::OnCommand(WPARAM wParam, LPARAM lParam) 
  150. {
  151. if(lParam == 0)
  152. {
  153. }
  154. return CWnd::OnCommand(wParam, lParam);
  155. }
  156. void C3DWindow::OnInitMenuPopup(CMenu* pPopupMenu, UINT /*nIndex*/, BOOL /*bSysMenu*/)
  157. }
  158. HRESULT C3DWindow::ReleaseD3DX()
  159. {
  160. RELEASENULL(m_pD3DDevice);
  161. RELEASENULL(m_pD3D);
  162. return S_OK;
  163. }
  164. HRESULT C3DWindow::InitD3DX(void)
  165. {
  166. CWaitCursor WaitCursor;
  167.     if ((m_pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == 0)
  168. {
  169. AfxMessageBox(_T("DirectX 9.0c not installed.nPlease install this or later version."));
  170. exit(0);
  171. }
  172. else
  173. {
  174. // Get the current desktop display mode
  175. D3DDISPLAYMODE d3ddm;
  176. if(SUCCEEDED(m_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)))
  177. {
  178. HRESULT hr;
  179. if( FAILED( hr = m_pD3D->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, 
  180. d3ddm.Format, D3DUSAGE_DEPTHSTENCIL,
  181. D3DRTYPE_SURFACE, 
  182. D3DFMT_D16 
  183. ) ) )
  184. {
  185. if( hr == D3DERR_NOTAVAILABLE )
  186. AfxMessageBox("POTENTIAL PROBLEM: We need at least a 16-bit z-buffer!",MB_ICONSTOP);
  187. exit(0);
  188. }
  189. //
  190. // Do we support hardware vertex processing? if so, use it. 
  191. // If not, downgrade to software.
  192. //
  193. D3DCAPS9 d3dCaps;
  194. if( FAILED( m_pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT, 
  195. D3DDEVTYPE_HAL, &d3dCaps ) ) )
  196. {
  197. AfxMessageBox("failure of GetDeviceCaps!",MB_ICONSTOP);
  198. exit(0);
  199. }
  200. DWORD dwBehaviorFlags = 0;
  201. if( d3dCaps.VertexProcessingCaps != 0 )
  202. dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
  203. else
  204. dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
  205. //
  206. // Everything checks out - create a simple, windowed device.
  207. //
  208. ZeroMemory(&m_d3dpp, sizeof(m_d3dpp));
  209. m_d3dpp.BackBufferFormat       = d3ddm.Format;
  210. m_d3dpp.SwapEffect             = D3DSWAPEFFECT_DISCARD;
  211. m_d3dpp.Windowed               = TRUE;
  212. m_d3dpp.EnableAutoDepthStencil = TRUE;
  213. m_d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
  214. m_d3dpp.PresentationInterval   = D3DPRESENT_INTERVAL_IMMEDIATE;
  215. CRect rcWindowClient;
  216. GetClientRect(&rcWindowClient);
  217. m_d3dpp.BackBufferWidth  = (UINT)rcWindowClient.Width();
  218. m_d3dpp.BackBufferHeight = (UINT)rcWindowClient.Height();
  219. hr = m_pD3D->CreateDevice(
  220. D3DADAPTER_DEFAULT,
  221. D3DDEVTYPE_HAL,
  222. m_hWnd,
  223. D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE,
  224. &m_d3dpp, 
  225. &m_pD3DDevice);
  226. // Store render target surface desc
  227. LPDIRECT3DSURFACE9 pBackBuffer;
  228. m_pD3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer );
  229. pBackBuffer->GetDesc( &m_D3DsdBackBuffer );
  230. pBackBuffer->Release();
  231. InitDeviceObjects();
  232. RestoreDeviceObjects();
  233. }
  234. }
  235. return S_OK;
  236. }
  237. HRESULT C3DWindow::RestoreDeviceObjects(void)
  238. {
  239. ASSERT(m_pD3DDevice);
  240.     // Setup render state
  241. D3DMATERIAL9 mtrl;
  242. D3DUtil_InitMaterial( mtrl, 1.0f, 1.0f, 1.0f );
  243. m_pD3DDevice->SetMaterial( &mtrl );
  244. m_pD3DDevice->SetRenderState( D3DRS_WRAP0,     TRUE );
  245.    
  246.     // Set miscellaneous render states
  247.     m_pD3DDevice->SetRenderState( D3DRS_DITHERENABLE,   FALSE );
  248.     m_pD3DDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
  249.     m_pD3DDevice->SetRenderState( D3DRS_ZENABLE,      TRUE );
  250.     // Turn on lighting.
  251. // m_pD3DDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
  252.     // Enable ambient lighting to a dim, grey light, so objects that
  253.     // are not lit by the other lights are not completely black
  254.     m_pD3DDevice->SetRenderState( D3DRS_AMBIENT,D3DCOLOR_COLORVALUE( 0.5, 0.5, 0.5, 1.0 ) );
  255. FLOAT      fAspect = (FLOAT)m_D3DsdBackBuffer.Width / (FLOAT)m_D3DsdBackBuffer.Height;
  256. if(m_bOrthographic)
  257. {
  258.  D3DXMatrixOrthoOffCenterLH (&m_matProj, -10.0f*fAspect, 10.0f*fAspect, -10.0f,10.0f,-100.0f, 100.0f);
  259. }
  260. else
  261. {
  262. // Setup the projection matrix
  263. FLOAT      fAspect = (FLOAT)m_D3DsdBackBuffer.Width / (FLOAT)m_D3DsdBackBuffer.Height;
  264. D3DXMatrixPerspectiveFovLH( &m_matProj, D3DX_PI/4, fAspect,m_fObjectRadius/64.0f, m_fObjectRadius*200.0f ); 
  265. }
  266. m_pD3DDevice->SetTransform( D3DTS_PROJECTION, &m_matProj );
  267.     D3DXMatrixTranspose( &m_matProjT, &m_matProj );
  268. HRESULT hr;
  269.     DWORD dwNumVertices = 2;
  270. for(int k=0;k<3;k++)
  271. {
  272. SAFE_RELEASE(m_pAxesVB[k]);
  273. if(SUCCEEDED(hr = m_pD3DDevice->CreateVertexBuffer( dwNumVertices*sizeof(POINT_VERTEX),
  274. D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY , 
  275. POINT_VERTEX_FVF, D3DPOOL_DEFAULT, &m_pAxesVB[k], NULL )))
  276. {
  277. POINT_VERTEX* pVertices;
  278. if(SUCCEEDED(m_pAxesVB[k]->Lock( 0, 0, (void**)&pVertices, 0 )) )
  279. {
  280. for(DWORD i=0;i<dwNumVertices;i++)
  281. {
  282. pVertices[i].color = D3DCOLOR_ARGB(255,0,255,0);
  283. }
  284. if(k == 0)
  285. {
  286. pVertices[0].p = D3DXVECTOR3(-10.0f,0.0f,0.0f);
  287. pVertices[1].p = D3DXVECTOR3( 10.0f,0.0f,0.0f);
  288. }
  289. else if(k==1)
  290. {//assume 4:3 
  291. pVertices[0].p = D3DXVECTOR3(0.0f,-7.5f,0.0f);
  292. pVertices[1].p = D3DXVECTOR3(0.0f, 7.5f,0.0f);
  293. }
  294. else if(k==2)
  295. {
  296. pVertices[0].p = D3DXVECTOR3(0.0f,0.0f,-10.0f);
  297. pVertices[1].p = D3DXVECTOR3(0.0f,0.0f, 10.0f);
  298. }
  299. m_pAxesVB[k]->Unlock();
  300. }
  301. }
  302. else
  303. {
  304. return E_FAIL;
  305. }
  306. }
  307. if(m_pFont)
  308. {
  309.     m_pFont->InvalidateDeviceObjects();
  310.     m_pFont->RestoreDeviceObjects();
  311. }
  312. if(m_pFontLarge)
  313. {
  314.     m_pFontLarge->InvalidateDeviceObjects();
  315.     m_pFontLarge->RestoreDeviceObjects();
  316. }
  317.     return S_OK;
  318. }
  319. void C3DWindow::SetUpdateTimer(bool bState)
  320. {
  321. if(bState && m_GUITimerID == NULL)
  322. {
  323. m_GUITimerID = SetTimer(GUI_UPDATE_TIMER,33,NULL);
  324. }
  325. else if(!bState && m_GUITimerID != NULL)
  326. {
  327. KillTimer(m_GUITimerID);
  328. m_GUITimerID = NULL;
  329. }
  330. }
  331. int C3DWindow::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  332. {
  333. if (CWnd::OnCreate(lpCreateStruct) == -1)
  334. return -1;
  335. return 0;
  336. }
  337. int C3DWindow::Start(bool bOrthographic) 
  338. {
  339. m_bOrthographic = bOrthographic;
  340.     HRESULT hr = InitD3DX();
  341.     if ( FAILED(hr) )
  342.     {
  343.         InterpretError(hr);
  344. return -1;
  345.     }
  346. m_GUITimerID = SetTimer(GUI_UPDATE_TIMER,33,NULL);
  347. return hr;
  348. }
  349. BOOL C3DWindow::Register()
  350. {
  351. if(m_Registered) return TRUE;
  352. WNDCLASS wc;
  353. wc.style = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  354. wc.lpfnWndProc = C3DWindow::Window3DWndProc;
  355. wc.cbClsExtra = 0;
  356. wc.cbWndExtra = 0;
  357. wc.hInstance = NULL;
  358. wc.hIcon = NULL;
  359. wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
  360. wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  361. wc.lpszMenuName = 0;
  362. wc.lpszClassName = "3DWindow";
  363. if(!::RegisterClass(&wc))
  364. {
  365. ASSERT(0);
  366. return FALSE;
  367. }
  368. m_Registered = TRUE;
  369. return TRUE;
  370. }
  371. LRESULT CALLBACK C3DWindow::Window3DWndProc(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
  372. {
  373. if(uiMsg == WM_NCCREATE)
  374. {
  375. C3DWindow *pCtrl = new C3DWindow;
  376. ASSERT(pCtrl);
  377. BOOL b = pCtrl->SubclassWindow(hWnd);
  378. ASSERT(b);
  379. return b;
  380. }
  381. return ::DefWindowProc(hWnd, uiMsg, wParam, lParam);
  382. }
  383. void C3DWindow::OnDestroy() 
  384. {
  385. if(m_GUITimerID)
  386. {
  387. KillTimer(m_GUITimerID);
  388. m_GUITimerID = NULL;
  389. }
  390. DeleteDeviceObjects();
  391. ReleaseD3DX();
  392.   theApp.WriteProfileBinary("3D Window",m_strRegistry,(LPBYTE)&m_ArcBall,sizeof(CD3DArcBall));
  393. CWnd::OnDestroy();
  394. }
  395. //-----------------------------------------------------------------------------
  396. // Name: Render3DEnvironment()
  397. // Desc: Draws the scene.
  398. //-----------------------------------------------------------------------------
  399. HRESULT C3DWindow::Render3DEnvironment(void)
  400. {
  401. if(C3DWindow::m_bInhibitUpdate)
  402. return S_OK;
  403. ASSERT(m_pD3DDevice);
  404.     HRESULT hr;
  405.     // Test the cooperative level to see if it's okay to render
  406.     if( FAILED( hr = m_pD3DDevice->TestCooperativeLevel() ) )
  407.     {
  408.         if (D3DERR_DEVICELOST == hr)
  409. {
  410. //The device has been lost but cannot be reset at this time. Therefore, rendering is not possible.
  411.             return S_OK;
  412. }
  413. else if (D3DERR_DEVICENOTRESET == hr)
  414. {
  415. //The device has been lost but can be reset at this time.
  416. //Normally, you would call Reset(), but we will cheat here for simplicity's sake.
  417. DeleteDeviceObjects();
  418. ReleaseD3DX();
  419. if (FAILED(InitD3DX()))
  420. {
  421. DeleteDeviceObjects();
  422. ReleaseD3DX();
  423. return S_OK;
  424. }
  425. RestoreDeviceObjects();
  426. }
  427.     }
  428.      // Frame move the scene
  429.     D3DXMatrixTranslation( &m_matWorld,-m_vObjectCenter.x,
  430.                                        -m_vObjectCenter.y,
  431.                                        -m_vObjectCenter.z );
  432.     D3DXMatrixMultiply( &m_matWorld, &m_matWorld, m_ArcBall.GetRotationMatrix() );
  433.     D3DXMatrixMultiply( &m_matWorld, &m_matWorld, m_ArcBall.GetTranslationMatrix() );
  434.     m_pD3DDevice->SetTransform( D3DTS_WORLD, &m_matWorld );
  435.     D3DXMATRIX matView;
  436. D3DXVECTOR3 vecEye( 0.0f, 0.0f, -2.0f*m_fObjectRadius ); 
  437. D3DXVECTOR3 vecAt( 0.0f, 0.0f, 0.0f );
  438. D3DXVECTOR3 vecUp( 0.0f, 1.0f, 0.0f ); 
  439.     D3DXMatrixLookAtLH( &matView, &vecEye,&vecAt,&vecUp );
  440.     m_pD3DDevice->SetTransform( D3DTS_VIEW,  &matView );
  441.     // Render the scene as normal
  442.     if( FAILED( hr = Render() ) )
  443.         return hr;
  444.     // Show the frame on the primary surface.
  445.     m_pD3DDevice->Present( NULL, NULL, NULL, NULL );
  446.     return S_OK;
  447. }
  448. HRESULT C3DWindow::Render(void)
  449. {
  450. HRESULT hr = S_OK;;
  451. if(!m_pD3DDevice || !m_hWnd)
  452. return E_FAIL;
  453. //clear the back buffer
  454. D3DXCOLOR colorClear = D3DXCOLOR(0.4f, 0.5f, 0.8f, 1.0f);
  455. m_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,colorClear, 1.0f, 0L );
  456. CString strError;
  457. D3DXVECTOR3 pos(0.0f,0.0f,0.0f);
  458. hr = m_pD3DDevice->BeginScene();
  459. if( SUCCEEDED( hr ) )
  460. {
  461. D3DXMATRIX matView;
  462. D3DXMATRIX matIdentity; 
  463.     m_pD3DDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
  464. m_pD3DDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
  465.     m_pD3DDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
  466. m_pD3DDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME );
  467. m_pD3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
  468. for(int iAxes=0;iAxes<3;iAxes++) 
  469. {
  470. if(iAxes != 2 || m_bRenderZAxis ) 
  471. {
  472. m_pD3DDevice->SetStreamSource(0,m_pAxesVB[iAxes],0,sizeof(POINT_VERTEX));
  473.   m_pD3DDevice->SetFVF( POINT_VERTEX_FVF );
  474. m_pD3DDevice->DrawPrimitive(D3DPT_LINELIST,0,1);
  475. }
  476. }
  477. bool bDrawAxesEnds  = false;
  478. if(m_pPixelVB)
  479. bDrawAxesEnds = true;
  480. if(bDrawAxesEnds)
  481. {
  482. m_pD3DDevice->SetRenderState(D3DRS_WRAP0, D3DWRAPCOORD_0);
  483. for(int iCone=0;iCone<3;iCone++) 
  484. {
  485. if(iCone != 2 || m_bRenderZAxis ) 
  486. {
  487. m_pD3DDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
  488. m_pD3DDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
  489. m_pD3DDevice->SetRenderState( D3DRS_SPECULARENABLE, TRUE );
  490. m_pD3DDevice->SetVertexShader(NULL);
  491. if(m_pConeMesh[iCone])
  492. {
  493.   m_pD3DDevice->SetFVF( MESH_VERTEX_TEX_FVF );
  494. if(iCone == 0 && m_pTextureAxisLabelX)
  495. m_pD3DDevice->SetTexture(0,m_pTextureAxisLabelX);
  496. if(iCone == 1 && m_pTextureAxisLabelY)
  497. m_pD3DDevice->SetTexture(0,m_pTextureAxisLabelY);
  498. if(iCone == 2 && m_pTextureAxisLabelZ)
  499. m_pD3DDevice->SetTexture(0,m_pTextureAxisLabelZ);
  500. m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  501. m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  502. m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
  503. m_pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_DISABLE );
  504. hr = m_pConeMesh[iCone]->DrawSubset(0);
  505. }
  506. }
  507. }
  508. m_pD3DDevice->SetTexture(0,NULL);
  509. m_pD3DDevice->SetTransform( D3DTS_WORLD, &m_matWorld );
  510. }
  511.   if(m_pPixelVB)
  512. {
  513.     m_pD3DDevice->SetFVF( POINT_VERTEX_FVF );
  514. int np = m_nPoints;
  515. m_pD3DDevice->SetStreamSource(0,m_pPixelVB,0,sizeof(POINT_VERTEX));
  516. if(m_bUsePoints)
  517. {
  518. m_pD3DDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME );
  519. m_pD3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
  520. m_pD3DDevice->DrawPrimitive(D3DPT_POINTLIST,0,np);
  521. }
  522. else
  523. {
  524. m_pD3DDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID ); 
  525.   m_pD3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
  526. m_pD3DDevice->SetRenderState(D3DRS_COLORVERTEX,TRUE);
  527. m_pD3DDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
  528. m_pD3DDevice->SetRenderState( D3DRS_DIFFUSEMATERIALSOURCE,  D3DMCS_COLOR1 );
  529. m_pD3DDevice->SetVertexShader(NULL);
  530. m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,np*4);
  531. }
  532. }
  533. RenderText();
  534. m_pD3DDevice->EndScene();
  535. }
  536. else
  537. {
  538. strError = DXGetErrorString9 (hr);
  539. }
  540.  
  541. return hr;
  542. }
  543. HRESULT C3DWindow::DeleteDeviceObjects(void)
  544. {
  545. for(int k=0;k<3;k++)
  546. {
  547. SAFE_RELEASE(m_pAxesVB[k]);
  548. }
  549. for(int iCone=0;iCone<3;iCone++)
  550. SAFE_RELEASE(m_pConeMesh[iCone]);
  551. SAFE_RELEASE(m_pTextureAxisLabelX);
  552. SAFE_RELEASE(m_pTextureAxisLabelY);
  553. SAFE_RELEASE(m_pTextureAxisLabelZ);
  554. SAFE_RELEASE(m_pPixelVB);
  555. m_nPoints = 0;
  556. if(m_pFont)
  557. m_pFont->DeleteDeviceObjects();
  558. if(m_pFontLarge)
  559. m_pFontLarge->DeleteDeviceObjects();
  560. return S_OK;
  561. }
  562. void C3DWindow::OnPaint()
  563. {
  564. CPaintDC dc(this); // device context for painting
  565. if (m_pD3DDevice)
  566. Render3DEnvironment();
  567. }
  568. BOOL C3DWindow::PreTranslateMessage(MSG* pMsg)
  569. {
  570. // Pass mouse messages to the ArcBall so it can build internal matrices
  571. m_ArcBall.HandleMouseMessages( m_hWnd, pMsg->message,pMsg->wParam,pMsg->lParam );
  572. if(pMsg->message == WM_KEYUP || pMsg->message == WM_KEYDOWN)
  573. {
  574. }
  575. return CWnd::PreTranslateMessage(pMsg);
  576. }
  577. HRESULT C3DWindow::InitDeviceObjects(void)
  578. {
  579. HRESULT hr = S_OK;
  580. ASSERT(m_pD3DDevice);
  581.     // Init the font
  582.     hr = m_pFont->InitDeviceObjects( m_pD3DDevice );
  583.     if( FAILED( hr ) )
  584.         return DXTRACE_ERR( "m_pFont->InitDeviceObjects", hr );
  585.     // Init the other font
  586.     hr = m_pFontLarge->InitDeviceObjects( m_pD3DDevice );
  587.     if( FAILED( hr ) )
  588.         return DXTRACE_ERR( "m_pFontLarge->InitDeviceObjects", hr );
  589. m_vObjectCenter = D3DXVECTOR3(0.0f,0.0f,0.0f);
  590. // Setup the arcball parameters
  591. m_fObjectRadius = 10.0f;
  592. CRect rcClient; 
  593. GetClientRect(&rcClient);
  594.     m_ArcBall.SetWindow( rcClient.Width(), rcClient.Height(), 0.85f );
  595. m_ArcBall.SetRadius( m_fObjectRadius );
  596. m_light.Diffuse.r  = 0.3f;
  597. m_light.Diffuse.g  = 0.3f;
  598. m_light.Diffuse.b  = 0.3f;
  599. m_light.Ambient.r  = 0.1f;
  600. m_light.Ambient.g  = 0.1f;
  601. m_light.Ambient.b  = 0.1f;
  602. m_light.Specular.r = 0.0f;
  603.    m_light.Specular.g = 0.0f;
  604.   m_light.Specular.b = 0.0f; 
  605.     
  606. m_light.Type = D3DLIGHT_POINT;//D3DLIGHT_SPOT;
  607. m_light.Falloff = 1.0f; 
  608. m_light.Direction.x = 0.0f;
  609. m_light.Direction.y = 0.0f;
  610. m_light.Direction.z =  1.0f;
  611. m_light.Attenuation0 = 1.0f; 
  612. m_light.Attenuation1 = 0.0f; 
  613. m_light.Attenuation2 = 0.0f; 
  614.    m_light.Range        = 1000.0f; 
  615. m_light.Position.x   = 0.0f;
  616.   m_light.Position.y   = 0.0f;
  617.   m_light.Position.z   = -18.0f; //the light is behind us 
  618. m_light.Theta  = 0.0f;//these next two control the cone angles of the light
  619.   m_light.Phi  = 0.6f;  
  620. m_pD3DDevice->SetLight( 0, &m_light );
  621.     m_pD3DDevice->LightEnable( 0, TRUE );  
  622. // m_pD3DDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
  623. // m_pD3DDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
  624. // m_pD3DDevice->SetRenderState( D3DRS_SPECULARENABLE, TRUE);
  625.    return S_OK;
  626. }
  627. void C3DWindow::OnTimer(UINT nIDEvent)
  628. {
  629. if(m_pD3DDevice && !pMainDialog->m_bClosing)
  630. Render3DEnvironment();
  631. CWnd::OnTimer(nIDEvent);
  632. }
  633. HRESULT C3DWindow::RenderText(void)
  634. {
  635.     D3DCOLOR fontColor        = D3DCOLOR_ARGB(255,255,255,0);
  636.     TCHAR szMsg[MAX_PATH] = TEXT("");
  637.     // Output display stats
  638.     FLOAT fNextLineL = 5.0f; 
  639.     FLOAT fNextLineR = 5.0f; 
  640. if(m_strTopRightTextLine1 != "")
  641. {
  642. lstrcpy( szMsg,m_strTopRightTextLine1 );
  643. FLOAT fTextX = (FLOAT)(m_D3DsdBackBuffer.Width - 150);  
  644. m_pFont->DrawText( fTextX, fNextLineR, fontColor, szMsg );
  645. }
  646. if(m_strTopLeftTextLine1 != "")
  647. {
  648. lstrcpy( szMsg,m_strTopLeftTextLine1 );
  649. FLOAT fTextX = (FLOAT)(5);  
  650. m_pFont->DrawText( fTextX, fNextLineL, fontColor, szMsg );
  651. }
  652. if(m_strBottomLeftTextLine1 != "")
  653. {
  654. lstrcpy( szMsg,m_strBottomLeftTextLine1 );
  655.   FLOAT fTextX = (FLOAT)(5);  
  656.   m_pFontLarge->DrawText( fTextX, (float)(m_d3dpp.BackBufferHeight - 30), fontColor, szMsg );
  657. }
  658.    return S_OK;
  659. }
  660. void C3DWindow::SetLightOutput(float fDiffuse,float fAmbient)
  661. {
  662. m_light.Diffuse.r  = fDiffuse;
  663. m_light.Diffuse.g  = fDiffuse;
  664. m_light.Diffuse.b  = fDiffuse;
  665. m_light.Ambient.r  = fAmbient;
  666. m_light.Ambient.g  = fAmbient;
  667. m_light.Ambient.b  = fAmbient;
  668. m_light.Specular.r = 0.0f;
  669.    m_light.Specular.g = 0.0f;
  670.   m_light.Specular.b = 0.0f; 
  671.     
  672. m_light.Type = D3DLIGHT_POINT;//D3DLIGHT_SPOT;
  673. m_light.Falloff = 1.0f; 
  674. m_light.Direction.x = 0.0f;
  675. m_light.Direction.y = 0.0f;
  676. m_light.Direction.z =  1.0f;
  677. m_light.Attenuation0 = 1.0f; 
  678. m_light.Attenuation1 = 0.0f; 
  679. m_light.Attenuation2 = 0.0f; 
  680.    m_light.Range        = 1000.0f; 
  681. m_light.Position.x   = 0.0f;
  682.   m_light.Position.y   = 0.0f;
  683.   m_light.Position.z   = -18.0f; //the light is behind us 
  684. m_light.Theta  = 0.0f;//these next two control the cone angles of the light
  685.   m_light.Phi  = 0.6f;  
  686. m_pD3DDevice->SetLight( 0, &m_light );
  687.     m_pD3DDevice->LightEnable( 0, TRUE );  
  688. }
  689. HRESULT C3DWindow::MakeConeMeshes(float fConeShiftX,float fConeShiftY, float fConeShiftZ)
  690. {
  691. for(int iCone=0;iCone<3;iCone++)
  692. SAFE_RELEASE(m_pConeMesh[iCone]);
  693. HRESULT hr;
  694. hr = D3DXCreateTextureFromResource(m_pD3DDevice,NULL,MAKEINTRESOURCE(IDB_BITMAP_XAXIS), &m_pTextureAxisLabelX);
  695. hr = D3DXCreateTextureFromResource(m_pD3DDevice,NULL,MAKEINTRESOURCE(IDB_BITMAP_YAXIS), &m_pTextureAxisLabelY);
  696. hr = D3DXCreateTextureFromResource(m_pD3DDevice,NULL,MAKEINTRESOURCE(IDB_BITMAP_ZAXIS), &m_pTextureAxisLabelZ);
  697. MESH_VERTEX_TEX* pConeVertices;
  698. D3DXMATRIX matTranslation;
  699. D3DXMATRIX matRotation;
  700. ID3DXMesh* pPrimativeMesh = NULL;
  701. double dConeHeight = 0.6; 
  702. fConeShiftX += (float)(dConeHeight/2.0);
  703. fConeShiftY += (float)(dConeHeight/2.0);
  704. fConeShiftZ += (float)(dConeHeight/2.0);
  705. float fConeBaseR = 0.2f;
  706. double dTextureAR = (2.0f*D3DX_PI*fConeBaseR)/dConeHeight;
  707.   
  708. if( SUCCEEDED(D3DXCreateCylinder(m_pD3DDevice,fConeBaseR,0.05f,(float)dConeHeight,20,2,&pPrimativeMesh,NULL)) )
  709. {
  710. for(int iCone=0;iCone<3;iCone++)
  711. {
  712.   if( SUCCEEDED( pPrimativeMesh->CloneMeshFVF( D3DXMESH_MANAGED, MESH_VERTEX_TEX_FVF,m_pD3DDevice,&m_pConeMesh[iCone])))
  713. {
  714. if(iCone == 0)
  715. {
  716. D3DXMatrixTranslation(&matTranslation,fConeShiftX,0.0f,0.0f);
  717.   D3DXMatrixRotationY(&matRotation,D3DX_PI/2.0f);
  718.   }
  719. else if(iCone == 1)
  720.   {
  721. D3DXMatrixTranslation(&matTranslation,0.0f,fConeShiftY,0.0f);
  722.     D3DXMatrixRotationX(&matRotation,-D3DX_PI/2.0f);
  723. }
  724. else if(iCone == 2)
  725. {
  726.   D3DXMatrixTranslation(&matTranslation,0.0f,0.0f,fConeShiftZ);
  727. D3DXMatrixRotationY(&matRotation,0.0f);//D3DX_PI/2.0f);
  728. }
  729. int nVertices = m_pConeMesh[iCone]->GetNumVertices();
  730. LPDIRECT3DVERTEXBUFFER9 pVB;
  731.   if( SUCCEEDED( m_pConeMesh[iCone]->GetVertexBuffer(&pVB)) )
  732. {
  733. pVB->Lock( 0, 0, (void**)&pConeVertices, 0 ); 
  734. for(int k=0; k<nVertices; k++)
  735.   {
  736.   double dTheta = atan2((double)pConeVertices[k].p.x,(double)pConeVertices[k].p.y);
  737.    if(dTheta < 0.0)dTheta += 2.0f*D3DX_PI;
  738.   pConeVertices[k].tv = 0.5f - (float)(pConeVertices[k].p.z/dConeHeight);//0 at bottom 1 at top
  739. pConeVertices[k].tu = (float)(dTheta/(2.0f*D3DX_PI));
  740. D3DXVec3TransformCoord(&pConeVertices[k].p,&pConeVertices[k].p,&matRotation);
  741. D3DXVec3TransformCoord(&pConeVertices[k].p,&pConeVertices[k].p,&matTranslation);
  742. }
  743. pVB->Unlock();
  744. pVB->Release();
  745. }
  746. }
  747. else
  748. {
  749. return E_FAIL;
  750. }
  751. }
  752. SAFE_RELEASE(pPrimativeMesh);
  753. }
  754. return S_OK;
  755. }
  756. void C3DWindow::RemovePixelVB(void)
  757. {
  758. m_nPoints = 0;
  759. SAFE_RELEASE(m_pPixelVB);
  760. }
  761. void C3DWindow::ResetArcBall(void)
  762. {
  763. UINT uNBytes;
  764. CD3DArcBall* pArcBallProfile = NULL;
  765. CString strDefaultArcBall = m_strRegistry + " Default";
  766. theApp.GetProfileBinary("3D Window",strDefaultArcBall,(LPBYTE*)&pArcBallProfile,&uNBytes);
  767. if(uNBytes == sizeof(CD3DArcBall) && pArcBallProfile)
  768. m_ArcBall = *pArcBallProfile;
  769. DELETENULL(pArcBallProfile);
  770. }
  771. HRESULT C3DWindow::ExportPixelVB(CString strFilename)
  772. {
  773. if(m_nPoints <= 0)
  774. return S_FALSE;
  775. CStdioFile ExportFile; 
  776. BOOL bFileOpen = FALSE;
  777. CString strExport;
  778. bFileOpen = ExportFile.Open(strFilename, CFile::modeWrite|CFile::modeCreate);
  779. if(!bFileOpen)
  780. return S_FALSE;
  781. POINT_VERTEX* pPixelVertices = NULL;
  782. if(FAILED(m_pPixelVB->Lock( 0, 0, (void**)&pPixelVertices, 0 )) )
  783. return S_FALSE;
  784. float x,y,z;
  785. for(int iPoint=0;iPoint<m_nPoints;iPoint++)
  786. {
  787. x = pPixelVertices[iPoint].p.x;
  788. y = pPixelVertices[iPoint].p.y;
  789. z = pPixelVertices[iPoint].p.z;
  790. strExport.Format("%f,%f,%fn",x,y,z);
  791. ExportFile.WriteString(strExport);
  792. }
  793. m_pPixelVB->Unlock();
  794. ExportFile.Flush();
  795. ExportFile.Close();
  796. return S_OK;
  797. }
  798. void C3DWindow::OnMouseMove(UINT nFlags, CPoint point)
  799. {
  800. CWnd::OnMouseMove(nFlags, point);
  801. }
  802. void C3DWindow::OnLButtonDown(UINT nFlags, CPoint point)
  803. {
  804. CWnd::OnLButtonDown(nFlags, point);
  805. }
  806. void C3DWindow::OnLButtonUp(UINT nFlags, CPoint point)
  807. {
  808. CWnd::OnLButtonUp(nFlags, point);
  809. }
  810. void C3DWindow::OnLButtonDblClk(UINT nFlags, CPoint point)
  811. {
  812. CWnd::OnLButtonDblClk(nFlags, point);
  813. }
  814. HRESULT C3DWindow::CreateVB(int nPoints,float* pX,float* pY,float* pZ,Color* pC,float* pS)
  815. {
  816. HRESULT hr;
  817. if(nPoints < 1)
  818. return FALSE;
  819. SAFE_RELEASE(m_pPixelVB);
  820. float fMinX =  3.3E38f;
  821. float fMaxX = -3.3E38f;
  822. float fMinY =  3.3E38f;
  823. float fMaxY = -3.3E38f;
  824. float fMinZ =  3.3E38f;
  825. float fMaxZ = -3.3E38f;
  826. double dXSum = 0.0f;
  827. double dYSum = 0.0f;
  828. double dZSum = 0.0f;
  829. for(int iP=0;iP<nPoints;iP++)
  830. {
  831. dXSum += (float)pX[iP];
  832. dYSum += (float)pY[iP];
  833. dZSum += (float)pZ[iP];
  834. fMaxX = max(fMaxX,pX[iP]);
  835. fMinX = min(fMinX,pX[iP]);
  836. fMaxY = max(fMaxY,pY[iP]);
  837. fMinY = min(fMinY,pY[iP]);
  838. fMaxZ = max(fMaxZ,pZ[iP]);
  839. fMinZ = min(fMinZ,pZ[iP]);
  840. }
  841. float fXOffset = -(float)(dXSum/(double)nPoints);
  842. float fYOffset = -(float)(dYSum/(double)nPoints);
  843. float fZOffset = -(float)(dZSum/(double)nPoints);
  844. float fExtentX = fMaxX - fMinX;
  845. float fExtentY = fMaxY - fMinY;
  846. float fMaxExtent = max(fExtentX,fExtentY);
  847. float fScale = 1.0f;
  848. if(fMaxExtent > 0.0f) 
  849. fScale = 20.0f / (fMaxExtent);
  850. m_bUsePoints = false;  
  851. if(m_bUsePoints)
  852. {
  853. if(FAILED(hr = m_pD3DDevice->CreateVertexBuffer( nPoints*sizeof(POINT_VERTEX),
  854. D3DUSAGE_WRITEONLY , 
  855. POINT_VERTEX_FVF, D3DPOOL_MANAGED, &m_pPixelVB, NULL )))
  856. {
  857. return FALSE; 
  858. }
  859. POINT_VERTEX* pPixelVertices = NULL;
  860. if(FAILED(m_pPixelVB->Lock( 0, 0, (void**)&pPixelVertices, 0 )) )
  861. return FALSE;
  862. for(int iP=0;iP<nPoints;iP++)
  863. {
  864. Color c = pC[iP];
  865. pPixelVertices[iP].p.x =  (fXOffset + pX[iP]) * fScale;
  866. pPixelVertices[iP].p.y = -(fYOffset + pY[iP]) * fScale; 
  867. pPixelVertices[iP].p.z =  (fZOffset + pZ[iP]) * fScale;
  868. pPixelVertices[iP].color = D3DCOLOR_ARGB(255,c.GetR(),c.GetG(),c.GetB());
  869. }
  870.     m_pPixelVB->Unlock();
  871. }
  872. else
  873. {
  874. if(FAILED(hr = m_pD3DDevice->CreateVertexBuffer( 12*nPoints*sizeof(POINT_VERTEX),
  875. D3DUSAGE_WRITEONLY , 
  876. POINT_VERTEX_FVF, D3DPOOL_MANAGED, &m_pPixelVB, NULL )))
  877. {
  878. return FALSE;
  879. }
  880. POINT_VERTEX* pPixelVertices = NULL;
  881. if(FAILED(m_pPixelVB->Lock( 0, 0, (void**)&pPixelVertices, 0 )) )
  882. return FALSE;
  883. POINT_VERTEX Quad[4];
  884. int iV = 0;
  885. for(int iP=0;iP<nPoints;iP++)
  886. {
  887. float m_fPixelSize = pS[iP];//pixel size in 3-D world
  888. float fHalf = 0.5f*m_fPixelSize;
  889. Color c = pC[iP];
  890. Quad[0].p.x = (fXOffset + pX[iP]-fHalf) * fScale;
  891. Quad[0].p.y = (fYOffset - pY[iP]-fHalf) * fScale;
  892. Quad[0].p.z = (fZOffset + pZ[iP]) * fScale;
  893. Quad[0].color = D3DCOLOR_ARGB(255,c.GetR(),c.GetG(),c.GetB());
  894. Quad[1].p.x = (fXOffset + pX[iP]+fHalf) * fScale;
  895. Quad[1].p.y = (fYOffset - pY[iP]-fHalf) * fScale;
  896. Quad[1].p.z =   Quad[0].p.z ;
  897. Quad[1].color = Quad[0].color;
  898. Quad[2].p.x = (fXOffset + pX[iP]+fHalf) * fScale;
  899. Quad[2].p.y = (fYOffset - pY[iP]+fHalf) * fScale;
  900. Quad[2].p.z =   Quad[0].p.z ;
  901. Quad[2].color = Quad[0].color;
  902. Quad[3].p.x = (fXOffset + pX[iP]-fHalf) * fScale;
  903. Quad[3].p.y = (fYOffset - pY[iP]+fHalf) * fScale;
  904. Quad[3].p.z =   Quad[0].p.z ;
  905. Quad[3].color = Quad[0].color;
  906. pPixelVertices[iV++] = Quad[0];
  907. pPixelVertices[iV++] = Quad[2]; 
  908. pPixelVertices[iV++] = Quad[1];
  909. pPixelVertices[iV++] = Quad[1];
  910. pPixelVertices[iV++] = Quad[2]; 
  911. pPixelVertices[iV++] = Quad[0];
  912. pPixelVertices[iV++] = Quad[0];
  913. pPixelVertices[iV++] = Quad[3];
  914. pPixelVertices[iV++] = Quad[2];
  915. pPixelVertices[iV++] = Quad[2];
  916. pPixelVertices[iV++] = Quad[3];
  917. pPixelVertices[iV++] = Quad[0];
  918. }
  919.     m_pPixelVB->Unlock();
  920. }
  921. m_nPoints = nPoints;
  922. float fConeShiftX = 10.0f; 
  923. float fConeShiftY = 7.5f; 
  924. float fConeShiftZ =  10.0f;
  925. MakeConeMeshes(fConeShiftX,fConeShiftY,fConeShiftZ);
  926. return TRUE;
  927. }
  928. /*lint -restore*/