ChildView.cpp
上传用户:sesekoo
上传日期:2020-07-18
资源大小:21543k
文件大小:90k
源码类别:

界面编程

开发平台:

Visual C++

  1. // ChildView.cpp : implementation of the CChildView class
  2. //
  3. #include "stdafx.h"
  4. #include "GLViews.h"
  5. #include "ChildView.h"
  6. #include "MainFrm.h"
  7. #include <io.h>
  8. #ifdef _DEBUG
  9. #define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13. /////////////////////////////////////////////////////////////////////////////
  14. // C3DObject
  15. IMPLEMENT_DYNCREATE( C3DObject, CObject );
  16. C3DObject::C3DObject(
  17. LPCTSTR sName, // = GL_VIEWS_NONAME
  18. bool bEnabledParentDependency, //  = true
  19. bool bEnabledScale, //  = false
  20. bool bEnabledTranslation, //  = true
  21. bool bEnabledOrientation //  = true
  22. )
  23. : m_sName( sName )
  24. , m_pParent( NULL )
  25. , m_bEnabledParentDependency( bEnabledParentDependency )
  26. , m_bEnabledScale( bEnabledScale )
  27. , m_bEnabledTranslation( bEnabledTranslation )
  28. , m_bEnabledOrientation( bEnabledOrientation )
  29. , m_hti( NULL )
  30. {
  31. ASSERT( sName != NULL );
  32. ASSERT( !m_sName.IsEmpty() );
  33. LocalLoadIdentity();
  34. }
  35. C3DObject::~C3DObject()
  36. {
  37. ASSERT( m_pParent == NULL );
  38. for( POSITION pos = m_listChilds.GetHeadPosition();
  39. pos != NULL;
  40. )
  41. { // walk all childs
  42. C3DObject * pChild = m_listChilds.GetNext( pos );
  43. ASSERT_VALID( pChild );
  44. ASSERT( pChild->m_pParent == this );
  45. pChild->m_pParent = NULL;
  46. delete pChild;
  47. } // walk all childs
  48. m_listChilds.RemoveAll();
  49. }
  50. void C3DObject::SerializeState(
  51. CArchive & ar
  52. )
  53. {
  54. ASSERT_VALID( this );
  55. if( ar.IsStoring() )
  56. {
  57. ar << m_v3LocalScale.x;
  58. ar << m_v3LocalScale.y;
  59. ar << m_v3LocalScale.z;
  60. ar << m_v3LocalTranslation.x;
  61. ar << m_v3LocalTranslation.y;
  62. ar << m_v3LocalTranslation.z;
  63. ar << m_quatLocalOrientation.x;
  64. ar << m_quatLocalOrientation.y;
  65. ar << m_quatLocalOrientation.z;
  66. ar << m_quatLocalOrientation.w;
  67. // ar << m_mtxLastTransformation.m11;
  68. // ar << m_mtxLastTransformation.m21;
  69. // ar << m_mtxLastTransformation.m31;
  70. // ar << m_mtxLastTransformation.m41;
  71. // ar << m_mtxLastTransformation.m12;
  72. // ar << m_mtxLastTransformation.m22;
  73. // ar << m_mtxLastTransformation.m32;
  74. // ar << m_mtxLastTransformation.m42;
  75. // ar << m_mtxLastTransformation.m13;
  76. // ar << m_mtxLastTransformation.m23;
  77. // ar << m_mtxLastTransformation.m33;
  78. // ar << m_mtxLastTransformation.m43;
  79. // ar << m_mtxLastTransformation.m14;
  80. // ar << m_mtxLastTransformation.m24;
  81. // ar << m_mtxLastTransformation.m34;
  82. // ar << m_mtxLastTransformation.m44;
  83. ar << m_sName;
  84. DWORD dwEnabledFlags = 0L;
  85. if( m_bEnabledParentDependency )
  86. dwEnabledFlags |= 0x00000001L;
  87. if( m_bEnabledScale )
  88. dwEnabledFlags |= 0x00000002L;
  89. if( m_bEnabledTranslation )
  90. dwEnabledFlags |= 0x00000004L;
  91. if( m_bEnabledOrientation )
  92. dwEnabledFlags |= 0x00000008L;
  93. ar << dwEnabledFlags;
  94. } // if( ar.IsStoring() )
  95. else
  96. {
  97. LocalLoadIdentity();
  98. ar >> m_v3LocalScale.x;
  99. ar >> m_v3LocalScale.y;
  100. ar >> m_v3LocalScale.z;
  101. ar >> m_v3LocalTranslation.x;
  102. ar >> m_v3LocalTranslation.y;
  103. ar >> m_v3LocalTranslation.z;
  104. ar >> m_quatLocalOrientation.x;
  105. ar >> m_quatLocalOrientation.y;
  106. ar >> m_quatLocalOrientation.z;
  107. ar >> m_quatLocalOrientation.w;
  108. // ar >> m_mtxLastTransformation.m11;
  109. // ar >> m_mtxLastTransformation.m21;
  110. // ar >> m_mtxLastTransformation.m31;
  111. // ar >> m_mtxLastTransformation.m41;
  112. // ar >> m_mtxLastTransformation.m12;
  113. // ar >> m_mtxLastTransformation.m22;
  114. // ar >> m_mtxLastTransformation.m32;
  115. // ar >> m_mtxLastTransformation.m42;
  116. // ar >> m_mtxLastTransformation.m13;
  117. // ar >> m_mtxLastTransformation.m23;
  118. // ar >> m_mtxLastTransformation.m33;
  119. // ar >> m_mtxLastTransformation.m43;
  120. // ar >> m_mtxLastTransformation.m14;
  121. // ar >> m_mtxLastTransformation.m24;
  122. // ar >> m_mtxLastTransformation.m34;
  123. // ar >> m_mtxLastTransformation.m44;
  124. ar >> m_sName;
  125. ASSERT( !m_sName.IsEmpty() );
  126. m_bEnabledParentDependency = false;
  127. m_bEnabledScale = false;
  128. m_bEnabledTranslation = false;
  129. m_bEnabledOrientation = false;
  130. DWORD dwEnabledFlags = 0L;
  131. ar >> dwEnabledFlags;
  132. if( (dwEnabledFlags&0x00000001L) != 0 )
  133. m_bEnabledParentDependency = true;
  134. if( (dwEnabledFlags&0x00000002L) != 0 )
  135. m_bEnabledScale = true;
  136. if( (dwEnabledFlags&0x00000004L) != 0 )
  137. m_bEnabledTranslation = true;
  138. if( (dwEnabledFlags&0x00000008L) != 0 )
  139. m_bEnabledOrientation = true;
  140. } // else from if( ar.IsStoring() )
  141. }
  142. void C3DObject::WalkTree(
  143. C3DObject::eWalkTreeQuery walkTreeQuery,
  144. C3DCamera * pCam,
  145. C3DView * pView3D,
  146. LPVOID lpvCookie,
  147. C3DMirror * pObjMirror // = NULL
  148. )
  149. {
  150. ASSERT_VALID( this );
  151. if( !OnWalkTree(
  152. walkTreeQuery,
  153. pCam,
  154. pView3D,
  155. lpvCookie,
  156. pObjMirror
  157. )
  158. )
  159. return;
  160. for( POSITION pos = m_listChilds.GetHeadPosition();
  161. pos != NULL;
  162. )
  163. { // walk all childs
  164. C3DObject * pChild = m_listChilds.GetNext( pos );
  165. ASSERT_VALID( pChild );
  166. ASSERT( pChild->m_pParent == this );
  167. if( walkTreeQuery == EWTQ_RENDER
  168. && ( !IsRenderSubtreeItem(pChild) )
  169. )
  170. continue;
  171. pChild->WalkTree(
  172. walkTreeQuery,
  173. pCam,
  174. pView3D,
  175. lpvCookie,
  176. pObjMirror
  177. );
  178. } // walk all childs
  179. }
  180. bool C3DObject::OnWalkTree(
  181. C3DObject::eWalkTreeQuery walkTreeQuery,
  182. C3DCamera * pCam,
  183. C3DView * pView3D,
  184. LPVOID lpvCookie,
  185. C3DMirror * pObjMirror
  186. )
  187. {
  188. bool bRetVal = true;
  189. ASSERT_VALID( this );
  190. switch( walkTreeQuery )
  191. {
  192. case EWTQ_THREAD_INIT:
  193. OnThreadInit( lpvCookie );
  194. break;
  195. case EWTQ_THREAD_DONE:
  196. OnThreadDone( lpvCookie );
  197. break;
  198. case EWTQ_PLAY:
  199. OnPlay( lpvCookie );
  200. break;
  201. case EWTQ_TRANSFORM:
  202. ASSERT_VALID( pCam );
  203. ASSERT_VALID( pView3D );
  204. OnTransform( pCam, pView3D, lpvCookie );
  205. break;
  206. case EWTQ_RENDER:
  207. ASSERT_VALID( pCam );
  208. ASSERT_VALID( pView3D );
  209. OnRender( pCam, pView3D, lpvCookie, pObjMirror );
  210. if( !IsRenderSubtree() )
  211. bRetVal = false;
  212. break;
  213. case EWTQ_ADD_TO_TREE:
  214. OnAddToTree( (CObjectHierarchyTreeCtrl*)lpvCookie );
  215. break;
  216. } // switch( walkTreeQuery )
  217. return bRetVal;
  218. }
  219. void C3DObject::OnThreadInit( LPVOID lpvCookie )
  220. {
  221. ASSERT_VALID( this );
  222. lpvCookie;
  223. }
  224. void C3DObject::OnThreadDone( LPVOID lpvCookie )
  225. {
  226. ASSERT_VALID( this );
  227. lpvCookie;
  228. }
  229. void C3DObject::OnPlay(
  230. LPVOID lpvCookie
  231. )
  232. {
  233. ASSERT_VALID( this );
  234. lpvCookie;
  235. }
  236. void C3DObject::CalcTransformation(
  237. _mrct mtxParentTransformation
  238. )
  239. {
  240. ASSERT_VALID( this );
  241. if( m_bEnabledParentDependency )
  242. m_mtxLastTransformation = mtxParentTransformation;
  243. else
  244. m_mtxLastTransformation.load_identity();
  245. if( m_bEnabledScale )
  246. m_mtxLastTransformation *= m_v3LocalScale.get_as_scale();
  247. if( m_bEnabledTranslation )
  248. m_mtxLastTransformation *= m_v3LocalTranslation.get_as_translation();
  249. if( m_bEnabledOrientation )
  250. m_mtxLastTransformation *= m_quatLocalOrientation;
  251. }
  252. void C3DObject::OnTransform(
  253. C3DCamera * pCam,
  254. C3DView * pView3D,
  255. LPVOID lpvCookie
  256. )
  257. {
  258. ASSERT_VALID( this );
  259. ASSERT_VALID( pCam );
  260. ASSERT_VALID( pView3D );
  261. pCam;
  262. pView3D;
  263. lpvCookie;
  264. C3DObject * pParent = GetParent();
  265. if( pParent != NULL )
  266. CalcTransformation( pParent->m_mtxLastTransformation );
  267. else
  268. {
  269. _mt mtxIdentity;
  270. CalcTransformation( mtxIdentity );
  271. }
  272. }
  273. void C3DObject::OnRender(
  274. C3DCamera * pCam,
  275. C3DView * pView3D,
  276. LPVOID lpvCookie,
  277. C3DMirror * pObjMirror
  278. )
  279. {
  280. ASSERT_VALID( this );
  281. ASSERT_VALID( pCam );
  282. ASSERT_VALID( pView3D );
  283. pCam;
  284. pView3D;
  285. lpvCookie;
  286. pObjMirror;
  287. }
  288. bool C3DObject::IsRenderSubtree()
  289. {
  290. ASSERT_VALID( this );
  291. return true;
  292. }
  293. bool C3DObject::IsRenderSubtreeItem( C3DObject * pObjChild )
  294. {
  295. ASSERT_VALID( this );
  296. ASSERT_VALID( pObjChild );
  297. ASSERT( pObjChild->GetParent() == this );
  298. pObjChild;
  299. return true;
  300. }
  301. void C3DObject::OnAddToTree(
  302. CObjectHierarchyTreeCtrl * pTreeCtrl
  303. )
  304. {
  305. ASSERT_VALID( this );
  306. ASSERT_VALID( pTreeCtrl );
  307. ASSERT( pTreeCtrl->GetSafeHwnd() != NULL );
  308. ASSERT( ::IsWindow( pTreeCtrl->GetSafeHwnd() ) );
  309. ASSERT( m_hti == NULL );
  310. HTREEITEM htiParent = TVI_ROOT;
  311. C3DObject * pObjParent = GetParent();
  312. if( pObjParent != NULL )
  313. {
  314. ASSERT_VALID( pObjParent );
  315. htiParent = pObjParent->m_hti;
  316. ASSERT( htiParent != NULL );
  317. }
  318. CString strTreeItemText;
  319. int nTreeImageIndex = GL_VIEWS_TREE_IMG_IDX_GENERIC_OBJ;
  320. OnQueryTreeDisplayParms(
  321. strTreeItemText,
  322. nTreeImageIndex
  323. );
  324. ASSERT( !strTreeItemText.IsEmpty() );
  325. m_hti =
  326. pTreeCtrl->InsertItem(
  327. (LPCTSTR)strTreeItemText,
  328. nTreeImageIndex,
  329. nTreeImageIndex,
  330. htiParent,
  331. TVI_LAST
  332. );
  333. ASSERT( m_hti != NULL );
  334. VERIFY( pTreeCtrl->SetItemData( m_hti, (DWORD)this ) );
  335. }
  336. void C3DObject::OnTreeItemDblClick(
  337. CObjectHierarchyTreeCtrl * pTreeCtrl
  338. )
  339. {
  340. ASSERT_VALID( this );
  341. ASSERT_VALID( pTreeCtrl );
  342. ASSERT( pTreeCtrl->GetSafeHwnd() != NULL );
  343. ASSERT( ::IsWindow( pTreeCtrl->GetSafeHwnd() ) );
  344. ASSERT( m_hti != NULL );
  345. pTreeCtrl;
  346. }
  347. void C3DObject::OnQueryTreeDisplayParms(
  348. CString & strTreeItemText,
  349. int & nTreeImageIndex
  350. )
  351. {
  352. ASSERT_VALID( this );
  353. strTreeItemText = GetName();
  354. ASSERT( !strTreeItemText.IsEmpty() );
  355. if( m_pParent == NULL )
  356. nTreeImageIndex = GL_VIEWS_TREE_IMG_IDX_ROOT;
  357. }
  358. void C3DObject::GenerateSphere(
  359. int nTextureIndex,
  360. _v3rct ptCenter,
  361. GLfloat fRadius,
  362. int nStacksCount,
  363. GLfloat fAngleTheta0,
  364. GLfloat fAngleTheta1,
  365. GLfloat fAngleTheta1Phi0,
  366. GLfloat fAngleTheta1Phi1,
  367. bool bNoDepth // = false
  368. )
  369. {
  370. ASSERT( fRadius >= 0 && nStacksCount > 3 );
  371. for( int nStackIdx0 = 0; nStackIdx0 < (nStacksCount / 2); nStackIdx0++ )
  372. {
  373. GLfloat fAngleStack0 =
  374. fAngleTheta1Phi0 +
  375. ( fAngleTheta1Phi1 - fAngleTheta1Phi0 ) /
  376. ( nStacksCount / 2 ) * nStackIdx0 ;
  377. GLfloat fAngleStack1 =
  378. fAngleTheta1Phi0 +
  379. ( fAngleTheta1Phi1 - fAngleTheta1Phi0 ) /
  380. ( nStacksCount / 2 ) * ( nStackIdx0 + 1 );
  381. _v3t
  382. vNormalPrev0, vNormalCurr0, vNormalPrev1, vNormalCurr1,
  383. vVertexPrev0, vVertexCurr0, vVertexPrev1, vVertexCurr1;
  384. GLfloat
  385. fTextureCoordPrevX0 = 0.0f, fTextureCoordPrevY0 = 0.0f,
  386. fTextureCoordCurrX0 = 0.0f, fTextureCoordCurrY0 = 0.0f,
  387. fTextureCoordPrevX1 = 0.0f, fTextureCoordPrevY1 = 0.0f,
  388. fTextureCoordCurrX1 = 0.0f, fTextureCoordCurrY1 = 0.0f;
  389. for( int nStackIdx1 = 0; nStackIdx1 <= nStacksCount; nStackIdx1++ )
  390. {
  391. if( nStackIdx1 > 0 )
  392. {
  393. vNormalPrev0 = vNormalCurr0;
  394. vNormalPrev1 = vNormalCurr1;
  395. vVertexPrev0 = vVertexCurr0;
  396. vVertexPrev1 = vVertexCurr1;
  397. fTextureCoordPrevX0 = fTextureCoordCurrX0;
  398. fTextureCoordPrevX1 = fTextureCoordCurrX1;
  399. fTextureCoordPrevY0 = fTextureCoordCurrY0;
  400. fTextureCoordPrevY1 = fTextureCoordCurrY1;
  401. } // if( nStackIdx1 > 0 )
  402. GLfloat fAngleStack2 =
  403. fAngleTheta0 +
  404. nStackIdx1 * (fAngleTheta1 - fAngleTheta0)
  405. / nStacksCount;
  406. vNormalCurr0.load_vector(
  407. _ntr::cos(fAngleStack0) * _ntr::cos(fAngleStack2),
  408. _ntr::sin(fAngleStack0),
  409. _ntr::cos(fAngleStack0) * _ntr::sin(fAngleStack2)
  410. );
  411. vVertexCurr0.load_vector(
  412. ptCenter.x + fRadius * vNormalCurr0.x,
  413. ptCenter.y + fRadius * vNormalCurr0.y,
  414. ptCenter.z + fRadius * vNormalCurr0.z
  415. );
  416. fTextureCoordCurrX0 = ((GLfloat)nStackIdx1) / ((GLfloat)nStacksCount);
  417. fTextureCoordCurrY0 = (2.0f * nStackIdx0) / ((GLfloat)nStacksCount);
  418. vNormalCurr1.load_vector(
  419. _ntr::cos(fAngleStack1) * _ntr::cos(fAngleStack2),
  420. _ntr::sin(fAngleStack1),
  421. _ntr::cos(fAngleStack1) * _ntr::sin(fAngleStack2)
  422. );
  423. vVertexCurr1.load_vector(
  424. ptCenter.x + fRadius * vNormalCurr1.x,
  425. ptCenter.y + fRadius * vNormalCurr1.y,
  426. ptCenter.z + fRadius * vNormalCurr1.z
  427. );
  428. fTextureCoordCurrX1 = ((GLfloat)nStackIdx1) / ((GLfloat)nStacksCount);
  429. fTextureCoordCurrY1 = (2 * (nStackIdx0 + 1)) / (GLfloat)nStacksCount;
  430. if( nStackIdx1 > 0 )
  431. {
  432. C3DSquare * pObjSquare = new C3DSquare;
  433. pObjSquare->m_nTextureIndex = nTextureIndex;
  434. pObjSquare->m_bNoDepth = bNoDepth;
  435. pObjSquare->m_bUseNormal = true;
  436. pObjSquare->m_vecNormal = vNormalCurr1;
  437. pObjSquare->m_arrTextureCoords[0].m_fX = fTextureCoordPrevX0;
  438. pObjSquare->m_arrTextureCoords[0].m_fY = fTextureCoordPrevY0;
  439. pObjSquare->m_arrPoints[0] = vVertexPrev0;
  440. pObjSquare->m_arrTextureCoords[1].m_fX = fTextureCoordPrevX1;
  441. pObjSquare->m_arrTextureCoords[1].m_fY = fTextureCoordPrevY1;
  442. pObjSquare->m_arrPoints[1] = vVertexPrev1;
  443. pObjSquare->m_arrTextureCoords[2].m_fX = fTextureCoordCurrX1;
  444. pObjSquare->m_arrTextureCoords[2].m_fY = fTextureCoordCurrY1;
  445. pObjSquare->m_arrPoints[2] = vVertexCurr1;
  446. pObjSquare->m_arrTextureCoords[3].m_fX = fTextureCoordCurrX0;
  447. pObjSquare->m_arrTextureCoords[3].m_fY = fTextureCoordCurrY0;
  448. pObjSquare->m_arrPoints[3] = vVertexCurr0;
  449. AddChild( pObjSquare );
  450. } // if( nStackIdx1 > 0 )
  451. } // for( int nStackIdx1 = 0; nStackIdx1 <= nStacksCount; nStackIdx1++ )
  452. } // for( int nStackIdx0 = 0; nStackIdx0 < (nStacksCount / 2); nStackIdx0++ )
  453. }
  454. bool C3DObject::stat_LoadResourceToMemory(
  455. LPCTSTR pszResId,
  456. LPCTSTR pszRsType,
  457. LPVOID * pLpvOutBuffer,
  458. DWORD * pDwOutSize
  459. )
  460. {
  461. *pLpvOutBuffer = NULL;
  462. *pDwOutSize = 0L;
  463. HINSTANCE hInst =
  464. ::AfxFindResourceHandle( pszResId, pszRsType );
  465. if( hInst == NULL )
  466. {
  467. ASSERT( FALSE );
  468. return false;
  469. }
  470. HRSRC hRsrc = FindResource( hInst, pszResId, pszRsType );
  471. if( hRsrc == NULL )
  472. {
  473. ASSERT( FALSE );
  474. return false;
  475. }
  476. HGLOBAL hGlobal = LoadResource( hInst, hRsrc );
  477. if( hGlobal == NULL )
  478. {
  479. ASSERT( FALSE );
  480. return false;
  481. }
  482. LPVOID lpvData = LockResource( hGlobal );
  483. DWORD dwSize = SizeofResource( hInst, hRsrc );
  484. if( lpvData == NULL )
  485. {
  486. ASSERT( FALSE );
  487. ::UnlockResource( hGlobal );
  488. ::FreeResource( hGlobal );
  489. return false;
  490. }
  491. if( dwSize == 0L )
  492. {
  493. ASSERT( FALSE );
  494. ::UnlockResource( hGlobal );
  495. ::FreeResource( hGlobal );
  496. return false;
  497. }
  498. *pLpvOutBuffer = malloc( dwSize );
  499. if( (*pLpvOutBuffer) == NULL )
  500. {
  501. ASSERT( FALSE );
  502. ::UnlockResource( hGlobal );
  503. ::FreeResource( hGlobal );
  504. return false;
  505. }
  506. memcpy( *pLpvOutBuffer, lpvData, dwSize );
  507. *pDwOutSize = dwSize;
  508. ::UnlockResource( hGlobal );
  509. ::FreeResource( hGlobal );
  510. return true;
  511. }
  512. bool C3DObject::stat_IsFileExists(
  513. LPCTSTR sFilePath
  514. )
  515. {
  516. ASSERT( sFilePath != NULL );
  517. if( sFilePath == NULL )
  518. return false;
  519. #if (defined _UNICODE)
  520. struct _wfinddata_t fd;
  521. #else
  522. struct _finddata_t fd;
  523. #endif
  524. long hNextFile = (long)
  525. #if (defined _UNICODE)
  526. _wfindfirst(
  527. #else
  528. _findfirst(
  529. #endif
  530. (LPTSTR)sFilePath,
  531. &fd
  532. );
  533. bool bExists = true;
  534. if( hNextFile < 0 )
  535. bExists = false;
  536. else
  537. {
  538. if( (fd.attrib&_A_SUBDIR) != 0 )
  539. bExists = false;
  540. } // else from if( hNextFile < 0 )
  541. _findclose( hNextFile );
  542. return bExists;
  543. }
  544. /////////////////////////////////////////////////////////////////////////////
  545. // C3DModifier
  546. IMPLEMENT_DYNCREATE( C3DModifier, C3DObject );
  547. C3DModifier::C3DModifier(
  548. LPCTSTR sName, // = GL_VIEWS_NONAME
  549. GLfloat fAnglePlayStepPitch, //  = 0.0f
  550. GLfloat fAnglePlayStepYaw, //  = 0.0f
  551. GLfloat fAnglePlayStepRoll //  = 0.0f
  552. )
  553. : C3DObject( sName )
  554. , m_fAnglePlayStepPitch( fAnglePlayStepPitch )
  555. , m_fAnglePlayStepYaw( fAnglePlayStepYaw )
  556. , m_fAnglePlayStepRoll( fAnglePlayStepRoll )
  557. {
  558. }
  559. C3DModifier::~C3DModifier()
  560. {
  561. }
  562. void C3DModifier::OnQueryTreeDisplayParms(
  563. CString & strTreeItemText,
  564. int & nTreeImageIndex
  565. )
  566. {
  567. ASSERT_VALID( this );
  568. ASSERT( ! m_sName.IsEmpty() );
  569. int nCount = int( m_listChilds.GetCount() );
  570. ASSERT( nCount > 0 );
  571. if( nCount > 1 )
  572. {
  573. strTreeItemText = _T("Group modifier "");
  574. strTreeItemText += m_sName;
  575. strTreeItemText += _T(""");
  576. nTreeImageIndex = GL_VIEWS_TREE_IMG_IDX_MODIFIER_GRP;
  577. return;
  578. } // if( nCount > 1 )
  579. C3DObject * pObjHead = m_listChilds.GetHead();
  580. ASSERT_VALID( pObjHead );
  581. CString strChildDisplayText;
  582. pObjHead->OnQueryTreeDisplayParms(
  583. strChildDisplayText,
  584. nTreeImageIndex
  585. );
  586. ASSERT( !strChildDisplayText.IsEmpty() );
  587. strTreeItemText = _T("Modifier for: ");
  588. strTreeItemText += strChildDisplayText;
  589. nTreeImageIndex = GL_VIEWS_TREE_IMG_IDX_MODIFIER_ONE;
  590. }
  591. void C3DModifier::OnPlay(
  592. LPVOID lpvCookie
  593. )
  594. {
  595. ASSERT_VALID( this );
  596. lpvCookie;
  597. #ifdef GL_VIEWS_DRAW_ANIMS
  598. if( m_fAnglePlayStepPitch != 0.0f
  599. && m_fAnglePlayStepYaw != 0.0f
  600. && m_fAnglePlayStepRoll != 0.0f
  601. )
  602. LocalAdjustOrientation(
  603. m_fAnglePlayStepPitch,
  604. m_fAnglePlayStepYaw,
  605. m_fAnglePlayStepRoll
  606. );
  607. #endif // GL_VIEWS_DRAW_ANIMS
  608. }
  609. /////////////////////////////////////////////////////////////////////////////
  610. // C3DSquare
  611. IMPLEMENT_DYNCREATE( C3DSquare, C3DObject );
  612. C3DSquare::C3DSquare()
  613. : C3DObject( GL_VIEWS_SQUARE_NAME )
  614. , m_nTextureIndex( -1 )
  615. , m_bUseNormal( false )
  616. , m_bNoDepth( false )
  617. , m_bNoCullFace( false )
  618. , m_bAdjustAlphaFunc( false )
  619. , m_bAdjustBlendFunc( false )
  620. , m_gleAlphaFunc( GL_NOTEQUAL )
  621. , m_glcAlphaRef( 0.0f )
  622. , m_gleBlendFactorS( GL_SRC_ALPHA )
  623. , m_gleBlendFactorD( GL_ONE )
  624. {
  625. }
  626. C3DSquare::~C3DSquare()
  627. {
  628. }
  629. void C3DSquare::OnRender(
  630. C3DCamera * pCam,
  631. C3DView * pView3D,
  632. LPVOID lpvCookie,
  633. C3DMirror * pObjMirror
  634. )
  635. {
  636. ASSERT_VALID( this );
  637. ASSERT_VALID( pCam );
  638. ASSERT_VALID( pView3D );
  639. pCam;
  640. pView3D;
  641. lpvCookie;
  642. pObjMirror;
  643. glPushMatrix();
  644. glMultMatrixf( m_mtxLastTransformation.arr );
  645. if( m_bNoDepth )
  646. {
  647. glDisable( GL_DEPTH_TEST );
  648. GL_VIEWS_CHECK_OPENGL_ERROR
  649. } // if( m_bNoDepth )
  650. if( m_bNoCullFace )
  651. {
  652. glDisable( GL_CULL_FACE );
  653. GL_VIEWS_CHECK_OPENGL_ERROR
  654. } // if( m_bNoCullFace )
  655. if( m_bAdjustAlphaFunc )
  656. {
  657. glEnable( GL_ALPHA_TEST );
  658. GL_VIEWS_CHECK_OPENGL_ERROR
  659. glAlphaFunc( m_gleAlphaFunc, m_glcAlphaRef );
  660. GL_VIEWS_CHECK_OPENGL_ERROR
  661. } // if( m_bAdjustAlphaFunc )
  662. if( m_bAdjustBlendFunc )
  663. {
  664. glEnable( GL_BLEND );
  665. GL_VIEWS_CHECK_OPENGL_ERROR
  666. glBlendFunc( m_gleBlendFactorS, m_gleBlendFactorD );
  667. GL_VIEWS_CHECK_OPENGL_ERROR
  668. } // if( m_bAdjustBlendFunc )
  669. if( m_nTextureIndex >= 0 )
  670. {
  671. ASSERT( m_nTextureIndex < GL_VIEWS_TEXTURE_COUNT );
  672. glEnable( GL_TEXTURE_2D );
  673. GL_VIEWS_CHECK_OPENGL_ERROR
  674. glBindTexture(
  675. GL_TEXTURE_2D,
  676. pView3D->m_TextureIds[m_nTextureIndex]
  677. );
  678. GL_VIEWS_CHECK_OPENGL_ERROR
  679. } // if( m_nTextureIndex >= 0 )
  680. glBegin(GL_QUADS);
  681. for( int nVertexIdx = 0; nVertexIdx < 4; nVertexIdx++ )
  682. {
  683. glTexCoord2f(
  684. m_arrTextureCoords[nVertexIdx].m_fX,
  685. m_arrTextureCoords[nVertexIdx].m_fY
  686. );
  687. glVertex3fv(
  688. m_arrPoints[nVertexIdx].arr
  689. );
  690. }
  691. glEnd();
  692. if( m_nTextureIndex >= 0 )
  693. {
  694. ASSERT( m_nTextureIndex < GL_VIEWS_TEXTURE_COUNT );
  695. glDisable( GL_TEXTURE_2D );
  696. GL_VIEWS_CHECK_OPENGL_ERROR
  697. } // if( m_nTextureIndex >= 0 )
  698. if( m_bAdjustBlendFunc )
  699. {
  700. glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
  701. GL_VIEWS_CHECK_OPENGL_ERROR
  702. glDisable( GL_BLEND );
  703. GL_VIEWS_CHECK_OPENGL_ERROR
  704. } // if( m_bAdjustBlendFunc )
  705. if( m_bAdjustAlphaFunc )
  706. {
  707. glDisable( GL_ALPHA_TEST );
  708. GL_VIEWS_CHECK_OPENGL_ERROR
  709. } // if( m_bAdjustAlphaFunc )
  710. if( m_bNoCullFace )
  711. {
  712. glEnable( GL_CULL_FACE );
  713. GL_VIEWS_CHECK_OPENGL_ERROR
  714. } // if( m_bNoCullFace )
  715. if( m_bNoDepth )
  716. {
  717. glEnable( GL_DEPTH_TEST );
  718. GL_VIEWS_CHECK_OPENGL_ERROR
  719. } // if( m_bNoDepth )
  720. glPopMatrix();
  721. }
  722. /////////////////////////////////////////////////////////////////////////////
  723. // C3DOuterScene
  724. IMPLEMENT_DYNCREATE( C3DOuterScene, C3DObject );
  725. volatile bool C3DOuterScene::g_bRenderOuterScene = true;
  726. GLfloat C3DOuterScene::g_fBottomPlaneValX = 0.7f;
  727. GLfloat C3DOuterScene::g_fBottomPlaneValY = 0.4f;
  728. GLfloat C3DOuterScene::g_fBottomPlaneValZ = 0.7f;
  729. GLfloat C3DOuterScene::g_fRingRadius = 0.80f;
  730. GLint C3DOuterScene::g_nSphereValStacks = 12;
  731. C3DOuterScene::C3DOuterScene()
  732. : C3DObject( GL_VIEWS_OUTER_SCENE_NAME )
  733. {
  734. }
  735. C3DOuterScene::~C3DOuterScene()
  736. {
  737. }
  738. void C3DOuterScene::OnThreadInit( LPVOID lpvCookie )
  739. {
  740. ASSERT_VALID( this );
  741. lpvCookie;
  742. C3DSquare * pObjSquare = new C3DSquare;
  743. pObjSquare->m_nTextureIndex = GL_VIEWS_TEXTURE_IDX_BOTTOM_PLANE;
  744. pObjSquare->m_bNoDepth = true;
  745. pObjSquare->m_arrTextureCoords[3].m_fX = 2.0f;
  746. pObjSquare->m_arrTextureCoords[3].m_fY = 2.0f;
  747. pObjSquare->m_arrPoints[3] = _v3t( -g_fBottomPlaneValX, -g_fBottomPlaneValY, -g_fBottomPlaneValZ );
  748. pObjSquare->m_arrTextureCoords[2].m_fX = 0.0f;
  749. pObjSquare->m_arrTextureCoords[2].m_fY = 2.0f;
  750. pObjSquare->m_arrPoints[2] = _v3t(  g_fBottomPlaneValX, -g_fBottomPlaneValY, -g_fBottomPlaneValZ );
  751. pObjSquare->m_arrTextureCoords[1].m_fX = 0.0f;
  752. pObjSquare->m_arrTextureCoords[1].m_fY = 0.0f;
  753. pObjSquare->m_arrPoints[1] = _v3t(  g_fBottomPlaneValX, -g_fBottomPlaneValY,  g_fBottomPlaneValZ );
  754. pObjSquare->m_arrTextureCoords[0].m_fX = 2.0f;
  755. pObjSquare->m_arrTextureCoords[0].m_fY = 0.0f;
  756. pObjSquare->m_arrPoints[0] = _v3t( -g_fBottomPlaneValX, -g_fBottomPlaneValY,  g_fBottomPlaneValZ );
  757. pObjSquare->m_bUseNormal = true;
  758. _v3t pt0(
  759. pObjSquare->m_arrPoints[1].x - pObjSquare->m_arrPoints[0].x,
  760. pObjSquare->m_arrPoints[1].y - pObjSquare->m_arrPoints[0].y,
  761. pObjSquare->m_arrPoints[1].z - pObjSquare->m_arrPoints[0].z
  762. );
  763. _v3t pt1(
  764. pObjSquare->m_arrPoints[2].x - pObjSquare->m_arrPoints[0].x,
  765. pObjSquare->m_arrPoints[2].y - pObjSquare->m_arrPoints[0].y,
  766. pObjSquare->m_arrPoints[2].z - pObjSquare->m_arrPoints[0].z
  767. );
  768. _v3t vNormal = pt0 ^ pt1;
  769. vNormal.normalize();
  770. pObjSquare->m_vecNormal = vNormal;
  771. AddChild( pObjSquare );
  772. GenerateSphere(
  773. GL_VIEWS_TEXTURE_IDX_RING,
  774. _v3t( 0.0f, 0.0f, 0.0f ),
  775. g_fRingRadius,
  776. g_nSphereValStacks,
  777. _ntr::get_pi()*2.0f,
  778. 0.0f,
  779. - 0.3f,
  780. + 0.7f,
  781. true
  782. );
  783. }
  784. bool C3DOuterScene::IsRenderSubtree()
  785. {
  786. ASSERT_VALID( this );
  787. return g_bRenderOuterScene;
  788. }
  789. void C3DOuterScene::OnQueryTreeDisplayParms(
  790. CString & strTreeItemText,
  791. int & nTreeImageIndex
  792. )
  793. {
  794. ASSERT_VALID( this );
  795. C3DObject::OnQueryTreeDisplayParms(
  796. strTreeItemText,
  797. nTreeImageIndex
  798. );
  799. nTreeImageIndex = GL_VIEWS_TREE_IMG_IDX_OUTER_SCENE;
  800. }
  801. /////////////////////////////////////////////////////////////////////////////
  802. // C3DCamera
  803. IMPLEMENT_DYNCREATE( C3DCamera, C3DObject );
  804. const GLfloat C3DCamera::g_arrFovValues[GL_VIEWS_FOV_COUNT] =
  805. {
  806. (( 10.0f*3.1415926535897932384626433832795f)/180.0f ), //  0  10 degrees
  807. (( 15.0f*3.1415926535897932384626433832795f)/180.0f ), //  1  15 degrees
  808. (( 20.0f*3.1415926535897932384626433832795f)/180.0f ), //  2  20 degrees
  809. (( 25.0f*3.1415926535897932384626433832795f)/180.0f ), //  3  25 degrees
  810. (( 30.0f*3.1415926535897932384626433832795f)/180.0f ), //  4  30 degrees
  811. (( 35.0f*3.1415926535897932384626433832795f)/180.0f ), //  5  35 degrees
  812. (( 40.0f*3.1415926535897932384626433832795f)/180.0f ), //  6  40 degrees
  813. (( 45.0f*3.1415926535897932384626433832795f)/180.0f ), //  7  45 degrees
  814. (( 50.0f*3.1415926535897932384626433832795f)/180.0f ), //  8  50 degrees
  815. (( 55.0f*3.1415926535897932384626433832795f)/180.0f ), //  9  55 degrees
  816. (( 60.0f*3.1415926535897932384626433832795f)/180.0f ), // 10  60 degrees
  817. (( 65.0f*3.1415926535897932384626433832795f)/180.0f ), // 11  65 degrees
  818. (( 70.0f*3.1415926535897932384626433832795f)/180.0f ), // 12  70 degrees
  819. (( 75.0f*3.1415926535897932384626433832795f)/180.0f ), // 13  75 degrees
  820. (( 80.0f*3.1415926535897932384626433832795f)/180.0f ), // 14  80 degrees
  821. (( 85.0f*3.1415926535897932384626433832795f)/180.0f ), // 15  85 degrees
  822. (( 90.0f*3.1415926535897932384626433832795f)/180.0f ), // 16  90 degrees
  823. (( 95.0f*3.1415926535897932384626433832795f)/180.0f ), // 17  95 degrees
  824. ((100.0f*3.1415926535897932384626433832795f)/180.0f ), // 18 100 degrees
  825. ((110.0f*3.1415926535897932384626433832795f)/180.0f ), // 19 110 degrees
  826. ((120.0f*3.1415926535897932384626433832795f)/180.0f ), // 20 120 degrees
  827. ((130.0f*3.1415926535897932384626433832795f)/180.0f ), // 21 130 degrees
  828. ((140.0f*3.1415926535897932384626433832795f)/180.0f ), // 22 140 degrees
  829. ((150.0f*3.1415926535897932384626433832795f)/180.0f ), // 23 150 degrees
  830. ((160.0f*3.1415926535897932384626433832795f)/180.0f ), // 24 160 degrees
  831. ((170.0f*3.1415926535897932384626433832795f)/180.0f ), // 25 170 degrees
  832. };
  833. volatile bool C3DCamera::g_bRenderCameraAxes = true;
  834. GLfloat C3DCamera::g_fAxisLineLength = 0.025f;
  835. GLfloat C3DCamera::g_fAxisLineWidth = 2.0f;
  836. C3DCamera::C3DCamera(
  837. UINT nTreeDblClickCmdID, // = 0L
  838. LPCTSTR sName, // = GL_VIEWS_NONAME
  839. int nFovIndex, // = GL_VIEWS_FOV_DEF_INDEX
  840. GLfloat fNearPlane, // = 1.0f
  841. GLfloat fFarPlane // = 5.0f
  842. )
  843. : C3DObject( sName )
  844. , m_nTreeDblClickCmdID( nTreeDblClickCmdID )
  845. , m_fAspect( 1.0f )
  846. , m_nFovIndex( nFovIndex )
  847. , m_fNearPlane( fNearPlane )
  848. , m_fFarPlane( fFarPlane )
  849. {
  850. ASSERT( 0 <= m_nFovIndex && m_nFovIndex < GL_VIEWS_FOV_COUNT );
  851. }
  852. C3DCamera::~C3DCamera()
  853. {
  854. }
  855. void C3DCamera::SerializeState(
  856. CArchive & ar
  857. )
  858. {
  859. ASSERT_VALID( this );
  860. ASSERT( 0 <= m_nFovIndex && m_nFovIndex < GL_VIEWS_FOV_COUNT );
  861. C3DObject::SerializeState( ar );
  862. if( ar.IsStoring() )
  863. {
  864. ar << m_fAspect;
  865. ar << DWORD(m_nFovIndex);
  866. ar << m_fNearPlane;
  867. ar << m_fFarPlane;
  868. } // if( ar.IsStoring() )
  869. else
  870. {
  871. ar >> m_fAspect;
  872. DWORD dwTmp;
  873. ar >> dwTmp; m_nFovIndex = int(dwTmp);
  874. ASSERT( 0 <= m_nFovIndex && m_nFovIndex < GL_VIEWS_FOV_COUNT );
  875. if( !(0 <= m_nFovIndex && m_nFovIndex < GL_VIEWS_FOV_COUNT) )
  876. m_nFovIndex = GL_VIEWS_FOV_DEF_INDEX;
  877. ar >> m_fNearPlane;
  878. ar >> m_fFarPlane;
  879. } // else from if( ar.IsStoring() )
  880. }
  881. void C3DCamera::OnRender(
  882. C3DCamera * pCam,
  883. C3DView * pView3D,
  884. LPVOID lpvCookie,
  885. C3DMirror * pObjMirror
  886. )
  887. {
  888. ASSERT_VALID( this );
  889. ASSERT_VALID( pCam );
  890. ASSERT_VALID( pView3D );
  891. pCam;
  892. pView3D;
  893. lpvCookie;
  894. if( (!g_bRenderCameraAxes) )
  895. return;
  896. if( pCam == this && pObjMirror == NULL )
  897. return;
  898. glPushMatrix();
  899. glMultMatrixf( m_mtxLastTransformation.arr );
  900. glLineWidth( g_fAxisLineWidth );
  901. GL_VIEWS_CHECK_OPENGL_ERROR
  902. glBegin( GL_LINES );
  903. glColor3f( 1.0f, 0.0f, 0.0f ); glVertex3f( 0.0f, 0.0f, 0.0f ); glVertex3f( g_fAxisLineLength,              0.0f,              0.0f );
  904. glColor3f( 0.0f, 1.0f, 0.0f ); glVertex3f( 0.0f, 0.0f, 0.0f ); glVertex3f(              0.0f, g_fAxisLineLength,              0.0f );
  905. glColor3f( 0.0f, 0.0f, 1.0f ); glVertex3f( 0.0f, 0.0f, 0.0f ); glVertex3f(              0.0f,              0.0f, g_fAxisLineLength );
  906. glColor3f( 1.0f, 1.0f, 1.0f ); 
  907. glEnd();
  908. glPopMatrix();
  909. }
  910. void C3DCamera::OnTreeItemDblClick(
  911. CObjectHierarchyTreeCtrl * pTreeCtrl
  912. )
  913. {
  914. ASSERT_VALID( this );
  915. ASSERT_VALID( pTreeCtrl );
  916. ASSERT( pTreeCtrl->GetSafeHwnd() != NULL );
  917. ASSERT( ::IsWindow( pTreeCtrl->GetSafeHwnd() ) );
  918. ASSERT( m_hti != NULL );
  919. if( m_nTreeDblClickCmdID == 0L )
  920. return;
  921. CFrameWnd * pFrame = pTreeCtrl->GetParentFrame();
  922. ASSERT_VALID( pFrame );
  923. if( pFrame->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) )
  924. {
  925. pFrame = pFrame->GetParentFrame();
  926. ASSERT_VALID( pFrame );
  927. ASSERT( !pFrame->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) );
  928. }
  929. pFrame->SendMessage( WM_COMMAND, m_nTreeDblClickCmdID );
  930. }
  931. void C3DCamera::OnQueryTreeDisplayParms(
  932. CString & strTreeItemText,
  933. int & nTreeImageIndex
  934. )
  935. {
  936. ASSERT_VALID( this );
  937. C3DObject::OnQueryTreeDisplayParms(
  938. strTreeItemText,
  939. nTreeImageIndex
  940. );
  941. nTreeImageIndex = GL_VIEWS_TREE_IMG_IDX_CAMERA_OBJ;
  942. }
  943. /////////////////////////////////////////////////////////////////////////////
  944. // C3DCube
  945. IMPLEMENT_DYNCREATE( C3DCube, C3DObject );
  946. volatile bool C3DCube::g_bRenderCubeObjects = true;
  947. GLfloat C3DCube::g_fCubeVal = 0.03f;
  948. GLfloat C3DCube::g_fTranslateCubeVal = C3DCube::g_fCubeVal * 2.2f;
  949. C3DCube::C3DCube(
  950. LPCTSTR sName, // = GL_VIEWS_NONAME
  951. bool bCenterCube // = false
  952. )
  953. : C3DObject( sName )
  954. , m_bCenterCube( bCenterCube )
  955. {
  956. }
  957. C3DCube::~C3DCube()
  958. {
  959. }
  960. GLfloat C3DCube::g_fCenterCubePlayPitch = _ntr::d2r(0.4f);
  961. GLfloat C3DCube::g_fCenterCubePlayYaw = _ntr::d2r(0.3f);
  962. GLfloat C3DCube::g_fCenterCubePlayRoll = _ntr::d2r(0.2f);
  963. void C3DCube::OnThreadInit( LPVOID lpvCookie )
  964. {
  965. ASSERT_VALID( this );
  966. lpvCookie;
  967. static const struct
  968. {
  969. int m_nTextureIndex;
  970. struct {
  971. GLfloat m_fTextureX, m_fTextureY,
  972. m_fPosX, m_fPosY, m_fPosZ;
  973. } m_arrVertexData[4];
  974. } g_arrSquaresInitData[] = 
  975. {
  976. { GL_VIEWS_TEXTURE_IDX_CUBE_WHITE,
  977. {
  978. { 0.0f, 0.0f, -g_fCubeVal, -g_fCubeVal,  g_fCubeVal },
  979. { 1.0f, 0.0f,  g_fCubeVal, -g_fCubeVal,  g_fCubeVal },
  980. { 1.0f, 1.0f,  g_fCubeVal,  g_fCubeVal,  g_fCubeVal },
  981. { 0.0f, 1.0f, -g_fCubeVal,  g_fCubeVal,  g_fCubeVal },
  982. },
  983. },
  984. { GL_VIEWS_TEXTURE_IDX_CUBE_WHITE,
  985. {
  986. { 1.0f, 0.0f, -g_fCubeVal, -g_fCubeVal, -g_fCubeVal },
  987. { 1.0f, 1.0f, -g_fCubeVal,  g_fCubeVal, -g_fCubeVal },
  988. { 0.0f, 1.0f,  g_fCubeVal,  g_fCubeVal, -g_fCubeVal },
  989. { 0.0f, 0.0f,  g_fCubeVal, -g_fCubeVal, -g_fCubeVal },
  990. },
  991. },
  992. { GL_VIEWS_TEXTURE_IDX_CUBE_ORANGE,
  993. {
  994. { 1.0f, 0.0f,  g_fCubeVal, -g_fCubeVal, -g_fCubeVal },
  995. { 1.0f, 1.0f,  g_fCubeVal,  g_fCubeVal, -g_fCubeVal },
  996. { 0.0f, 1.0f,  g_fCubeVal,  g_fCubeVal,  g_fCubeVal },
  997. { 0.0f, 0.0f,  g_fCubeVal, -g_fCubeVal,  g_fCubeVal },
  998. },
  999. },
  1000. { GL_VIEWS_TEXTURE_IDX_CUBE_ORANGE,
  1001. {
  1002. { 0.0f, 0.0f, -g_fCubeVal, -g_fCubeVal, -g_fCubeVal },
  1003. { 1.0f, 0.0f, -g_fCubeVal, -g_fCubeVal,  g_fCubeVal },
  1004. { 1.0f, 1.0f, -g_fCubeVal,  g_fCubeVal,  g_fCubeVal },
  1005. { 0.0f, 1.0f, -g_fCubeVal,  g_fCubeVal, -g_fCubeVal },
  1006. },
  1007. },
  1008. };
  1009. for( int nSquareIdx = 0;
  1010. nSquareIdx < (sizeof(g_arrSquaresInitData)/sizeof(g_arrSquaresInitData[0]));
  1011. nSquareIdx++
  1012. )
  1013. {
  1014. C3DSquare * pObjSquare = new C3DSquare;
  1015. pObjSquare->m_nTextureIndex =
  1016. g_arrSquaresInitData[nSquareIdx].m_nTextureIndex;
  1017. for( int nVertexIdx = 0; nVertexIdx < 4; nVertexIdx++ )
  1018. {
  1019. pObjSquare->m_arrTextureCoords[nVertexIdx].m_fX =
  1020. g_arrSquaresInitData[nSquareIdx].m_arrVertexData[nVertexIdx].m_fTextureX;
  1021. pObjSquare->m_arrTextureCoords[nVertexIdx].m_fY =
  1022. g_arrSquaresInitData[nSquareIdx].m_arrVertexData[nVertexIdx].m_fTextureY;
  1023. pObjSquare->m_arrPoints[nVertexIdx].x =
  1024. g_arrSquaresInitData[nSquareIdx].m_arrVertexData[nVertexIdx].m_fPosX;
  1025. pObjSquare->m_arrPoints[nVertexIdx].y =
  1026. g_arrSquaresInitData[nSquareIdx].m_arrVertexData[nVertexIdx].m_fPosY;
  1027. pObjSquare->m_arrPoints[nVertexIdx].z =
  1028. g_arrSquaresInitData[nSquareIdx].m_arrVertexData[nVertexIdx].m_fPosZ;
  1029. }
  1030. pObjSquare->m_bNoCullFace = true;
  1031. pObjSquare->m_bAdjustAlphaFunc = true;
  1032. pObjSquare->m_bAdjustBlendFunc = true;
  1033. AddChild( pObjSquare );
  1034. }
  1035. }
  1036. void C3DCube::OnPlay(
  1037. LPVOID lpvCookie
  1038. )
  1039. {
  1040. ASSERT_VALID( this );
  1041. lpvCookie;
  1042. #ifdef GL_VIEWS_DRAW_ANIMS
  1043. if( m_bCenterCube )
  1044. {
  1045. ASSERT_VALID( m_pParent );
  1046. ASSERT_KINDOF( C3DModifier, m_pParent );
  1047. m_pParent->LocalAdjustOrientation(
  1048. g_fCenterCubePlayPitch,
  1049. g_fCenterCubePlayYaw,
  1050. g_fCenterCubePlayRoll
  1051. );
  1052. }
  1053. #endif // GL_VIEWS_DRAW_ANIMS
  1054. }
  1055. bool C3DCube::IsRenderSubtreeItem( C3DObject * pObjChild )
  1056. {
  1057. ASSERT_VALID( this );
  1058. ASSERT_VALID( pObjChild );
  1059. ASSERT( pObjChild->GetParent() == this );
  1060. if( g_bRenderCubeObjects )
  1061. return true;
  1062. if( pObjChild->IsKindOf(RUNTIME_CLASS(C3DSquare)) )
  1063. return false;
  1064. return true;
  1065. }
  1066. void C3DCube::OnQueryTreeDisplayParms(
  1067. CString & strTreeItemText,
  1068. int & nTreeImageIndex
  1069. )
  1070. {
  1071. ASSERT_VALID( this );
  1072. strTreeItemText =
  1073. m_bCenterCube
  1074. ? _T("center cube")
  1075. : _T("leaf cube")
  1076. ;
  1077. nTreeImageIndex =
  1078. m_bCenterCube
  1079. ? GL_VIEWS_TREE_IMG_IDX_CUBE_CENTER
  1080. : GL_VIEWS_TREE_IMG_IDX_CUBE_LEAF
  1081. ;
  1082. }
  1083. /////////////////////////////////////////////////////////////////////////////
  1084. // C3DPlanet
  1085. IMPLEMENT_DYNCREATE( C3DPlanet, C3DObject );
  1086. volatile bool C3DPlanet::g_bRenderPlanetObjects = true;
  1087. GLfloat C3DPlanet::g_fPlanetRadiusEarth = 0.04f;
  1088. GLfloat C3DPlanet::g_fPlanetRadiusMoon = 0.01f;
  1089. GLint C3DPlanet::g_nPlanetSphereStacks = 12;
  1090. GLfloat C3DPlanet::g_fAnglePlayStepPitchEarth = _ntr::d2r( 2.5f );
  1091. GLfloat C3DPlanet::g_fAnglePlayStepPitchMoon = _ntr::d2r( 4.5f );
  1092. GLfloat C3DPlanet::g_fAnglePlayStepYawEarth = _ntr::d2r( 1.5f );
  1093. GLfloat C3DPlanet::g_fAnglePlayStepYawMoon = _ntr::d2r( 2.5f );
  1094. GLfloat C3DPlanet::g_fAnglePlayStepRollEarth = _ntr::d2r( 4.0f );
  1095. GLfloat C3DPlanet::g_fAnglePlayStepRollMoon = _ntr::d2r( 6.0f );
  1096. C3DPlanet::C3DPlanet(
  1097. LPCTSTR sName, // = GL_VIEWS_NONAME
  1098. int nPlanetTextureIndex, // = GL_VIEWS_TEXTURE_IDX_EARTH
  1099. GLint nPlanetStacks, // = C3DPlanet::g_nPlanetSphereStacks
  1100. GLfloat fPlanetRadius, // = C3DPlanet::g_fPlanetRadiusEarth
  1101. GLfloat fAnglePlayStepPitch, // = C3DPlanet::g_fAnglePlayStepPitchEarth
  1102. GLfloat fAnglePlayStepYaw, // = C3DPlanet::g_fAnglePlayStepYawEarth
  1103. GLfloat fAnglePlayStepRoll // = C3DPlanet::g_fAnglePlayStepRollMoon
  1104. )
  1105. : C3DObject( sName )
  1106. , m_nPlanetTextureIndex( nPlanetTextureIndex )
  1107. , m_nPlanetStacks( nPlanetStacks )
  1108. , m_fPlanetRadius( fPlanetRadius )
  1109. , m_fAnglePlayStepPitch( fAnglePlayStepPitch )
  1110. , m_fAnglePlayStepYaw( fAnglePlayStepYaw )
  1111. , m_fAnglePlayStepRoll( fAnglePlayStepRoll )
  1112. {
  1113. }
  1114. C3DPlanet::~C3DPlanet()
  1115. {
  1116. }
  1117. void C3DPlanet::OnThreadInit( LPVOID lpvCookie )
  1118. {
  1119. ASSERT_VALID( this );
  1120. lpvCookie;
  1121. GenerateSphere(
  1122. m_nPlanetTextureIndex,
  1123. _v3t( 0.0f, 0.0f, 0.0f ),
  1124. m_fPlanetRadius,
  1125. m_nPlanetStacks,
  1126. _ntr::get_pi() * 2.0f,
  1127. 0.0f,
  1128. - _ntr::get_pi() / 2.0f,
  1129. + _ntr::get_pi() / 2.0f
  1130. );
  1131. }
  1132. bool C3DPlanet::IsRenderSubtreeItem( C3DObject * pObjChild )
  1133. {
  1134. ASSERT_VALID( this );
  1135. ASSERT_VALID( pObjChild );
  1136. ASSERT( pObjChild->GetParent() == this );
  1137. if( g_bRenderPlanetObjects )
  1138. return true;
  1139. if( pObjChild->IsKindOf(RUNTIME_CLASS(C3DSquare)) )
  1140. return false;
  1141. return true;
  1142. }
  1143. void C3DPlanet::OnQueryTreeDisplayParms(
  1144. CString & strTreeItemText,
  1145. int & nTreeImageIndex
  1146. )
  1147. {
  1148. ASSERT_VALID( this );
  1149. C3DObject::OnQueryTreeDisplayParms(
  1150. strTreeItemText,
  1151. nTreeImageIndex
  1152. );
  1153. //nTreeImageIndex = ....;
  1154. }
  1155. void C3DPlanet::OnPlay(
  1156. LPVOID lpvCookie
  1157. )
  1158. {
  1159. ASSERT_VALID( this );
  1160. lpvCookie;
  1161. if( !g_bRenderPlanetObjects )
  1162. return;
  1163. #ifdef GL_VIEWS_DRAW_ANIMS
  1164. ASSERT_VALID( m_pParent );
  1165. ASSERT_KINDOF( C3DModifier, m_pParent );
  1166. m_pParent->LocalAdjustOrientation(
  1167. m_fAnglePlayStepPitch,
  1168. m_fAnglePlayStepYaw,
  1169. m_fAnglePlayStepRoll
  1170. );
  1171. #endif // GL_VIEWS_DRAW_ANIMS
  1172. }
  1173. /////////////////////////////////////////////////////////////////////////////
  1174. // C3DText
  1175. IMPLEMENT_DYNCREATE( C3DText, C3DObject );
  1176. volatile bool C3DText::g_bRenderTextObjects = true;
  1177. GLfloat C3DText::g_fScaleModifier = 0.03f;
  1178. GLfloat C3DText::g_fAnglePlayStepPitchText = 0.0f;
  1179. GLfloat C3DText::g_fAnglePlayStepYawText = 0.0f;
  1180. GLfloat C3DText::g_fAnglePlayStepRollText = _ntr::d2r( 2.0f );
  1181. C3DText::C3DText(
  1182. LPCTSTR sName, // = GL_VIEWS_NONAME // should be used to set displayed text or one letter
  1183. COLORREF clrText, // = RGB(255,255,255)
  1184. GLfloat fAnglePlayStepPitch, // = C3DText::g_fAnglePlayStepPitchText
  1185. GLfloat fAnglePlayStepYaw,   // = C3DText::g_fAnglePlayStepYawText
  1186. GLfloat fAnglePlayStepRoll   // = C3DText::g_fAnglePlayStepRollText
  1187. )
  1188. : C3DObject( sName )
  1189. , m_fRed( GLfloat(GetRValue(clrText)) / 255.0f )
  1190. , m_fGreen( GLfloat(GetGValue(clrText)) / 255.0f )
  1191. , m_fBlue( GLfloat(GetBValue(clrText)) / 255.0f )
  1192. , m_fAnglePlayStepPitch( fAnglePlayStepPitch )
  1193. , m_fAnglePlayStepYaw( fAnglePlayStepYaw )
  1194. , m_fAnglePlayStepRoll( fAnglePlayStepRoll )
  1195. {
  1196. }
  1197. C3DText::~C3DText()
  1198. {
  1199. }
  1200. void C3DText::OnPlay(
  1201. LPVOID lpvCookie
  1202. )
  1203. {
  1204. ASSERT_VALID( this );
  1205. lpvCookie;
  1206. if( !g_bRenderTextObjects )
  1207. return;
  1208. #ifdef GL_VIEWS_DRAW_ANIMS
  1209. ASSERT_VALID( m_pParent );
  1210. ASSERT_KINDOF( C3DModifier, m_pParent );
  1211. m_pParent->LocalAdjustOrientation(
  1212. m_fAnglePlayStepPitch,
  1213. m_fAnglePlayStepYaw,
  1214. m_fAnglePlayStepRoll
  1215. );
  1216. #endif // GL_VIEWS_DRAW_ANIMS
  1217. }
  1218. void C3DText::OnRender(
  1219. C3DCamera * pCam,
  1220. C3DView * pView3D,
  1221. LPVOID lpvCookie,
  1222. C3DMirror * pObjMirror
  1223. )
  1224. {
  1225. ASSERT_VALID( this );
  1226. ASSERT_VALID( pCam );
  1227. ASSERT_VALID( pView3D );
  1228. pCam;
  1229. lpvCookie;
  1230. pObjMirror;
  1231. if( !g_bRenderTextObjects )
  1232. return;
  1233. if( !pView3D->m_Font3D.IsFontCreated() )
  1234. return;
  1235. LPCTSTR sText = GetName();
  1236. ASSERT( sText != NULL );
  1237. if( _tcslen(sText) == 0 )
  1238. return;
  1239. glEnable( GL_ALPHA_TEST );
  1240. GL_VIEWS_CHECK_OPENGL_ERROR
  1241. glAlphaFunc( GL_NOTEQUAL, 0.0 );
  1242. GL_VIEWS_CHECK_OPENGL_ERROR
  1243. glDisable( GL_CULL_FACE );
  1244. GL_VIEWS_CHECK_OPENGL_ERROR
  1245. glPushMatrix();
  1246. glMultMatrixf( m_mtxLastTransformation.arr );
  1247. glColor3f( m_fRed, m_fGreen, m_fBlue );
  1248. glEnable( GL_BLEND );
  1249. GL_VIEWS_CHECK_OPENGL_ERROR
  1250. glBlendFunc( GL_SRC_ALPHA, GL_ONE );
  1251. GL_VIEWS_CHECK_OPENGL_ERROR
  1252. glPushMatrix();
  1253. glScalef(
  1254. g_fScaleModifier,
  1255. g_fScaleModifier,
  1256. g_fScaleModifier
  1257. );
  1258. pView3D->m_Font3D.TextOut( sText );
  1259. glPopMatrix();
  1260. glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
  1261. GL_VIEWS_CHECK_OPENGL_ERROR
  1262. glDisable( GL_BLEND );
  1263. GL_VIEWS_CHECK_OPENGL_ERROR
  1264. glColor3f( 1.0f, 1.0f, 1.0f ); 
  1265. glPopMatrix();
  1266. glDisable( GL_ALPHA_TEST );
  1267. GL_VIEWS_CHECK_OPENGL_ERROR
  1268. glEnable( GL_CULL_FACE );
  1269. GL_VIEWS_CHECK_OPENGL_ERROR
  1270. }
  1271. void C3DText::OnQueryTreeDisplayParms(
  1272. CString & strTreeItemText,
  1273. int & nTreeImageIndex
  1274. )
  1275. {
  1276. ASSERT_VALID( this );
  1277. strTreeItemText.Format(
  1278. _T("text "%s""),
  1279. GetName()
  1280. );
  1281. ASSERT( !strTreeItemText.IsEmpty() );
  1282. nTreeImageIndex = GL_VIEWS_TREE_IMG_IDX_TEXT_OBJ;
  1283. }
  1284. /////////////////////////////////////////////////////////////////////////////
  1285. // C3DWnd
  1286. IMPLEMENT_DYNCREATE( C3DWnd, C3DObject );
  1287. _v3t C3DWnd::g_arrDefPointsWndAviPlayer[4] =
  1288. {
  1289. _v3t( -0.12f, -0.11f, -0.35f ),
  1290. _v3t(  0.12f, -0.11f, -0.35f ),
  1291. _v3t(  0.12f,  0.11f, -0.35f ),
  1292. _v3t( -0.12f,  0.11f, -0.35f ),
  1293. };
  1294. _v3t C3DWnd::g_arrDefPointsWndMirror[4] =
  1295. {
  1296. _v3t(  0.12f, -0.11f,  0.35f ),
  1297. _v3t( -0.12f, -0.11f,  0.35f ),
  1298. _v3t( -0.12f,  0.11f,  0.35f ),
  1299. _v3t(  0.12f,  0.11f,  0.35f ),
  1300. };
  1301. C3DWnd::C3DWnd(
  1302. LPCTSTR sName, // = GL_VIEWS_WND_AVI_PLAYER
  1303. int nPlaneTextureIndex, // = GL_VIEWS_TEXTURE_IDX_WND_AVI_PLAYER
  1304. _v3rct pt0, // = C3DWnd::g_arrDefPointsWndAviPlayer[0]
  1305. _v3rct pt1, // = C3DWnd::g_arrDefPointsWndAviPlayer[1]
  1306. _v3rct pt2, // = C3DWnd::g_arrDefPointsWndAviPlayer[2]
  1307. _v3rct pt3  // = C3DWnd::g_arrDefPointsWndAviPlayer[3]
  1308. )
  1309. : C3DObject( sName )
  1310. , m_nPlaneTextureIndex( nPlaneTextureIndex )
  1311. {
  1312. m_arrWndPoints[0] = pt0;
  1313. m_arrWndPoints[1] = pt1;
  1314. m_arrWndPoints[2] = pt2;
  1315. m_arrWndPoints[3] = pt3;
  1316. _RecalcNormalAndContentArea();
  1317. }
  1318. C3DWnd::~C3DWnd()
  1319. {
  1320. }
  1321. void C3DWnd::_RecalcNormalAndContentArea()
  1322. {
  1323. ASSERT_VALID( this );
  1324. _v3t pt0(
  1325. m_arrWndPoints[1].x - m_arrWndPoints[0].x,
  1326. m_arrWndPoints[1].y - m_arrWndPoints[0].y,
  1327. m_arrWndPoints[1].z - m_arrWndPoints[0].z
  1328. );
  1329. _v3t pt1(
  1330. m_arrWndPoints[2].x - m_arrWndPoints[0].x,
  1331. m_arrWndPoints[2].y - m_arrWndPoints[0].y,
  1332. m_arrWndPoints[2].z - m_arrWndPoints[0].z
  1333. );
  1334. m_lastNormal = pt0 ^ pt1;
  1335. m_lastNormal.normalize();
  1336. stat_CalcWindowContentPlane(
  1337. m_arrWndPoints,
  1338. m_arrContentPoints
  1339. );
  1340. }
  1341. void C3DWnd::stat_CalcWindowContentPlane(
  1342. _v3t * arrWndPoints,
  1343. _v3t * arrContentPoints
  1344. )
  1345. {
  1346. ASSERT( arrWndPoints != NULL );
  1347. ASSERT( arrContentPoints != NULL );
  1348. for( int i = 0; i< 4; i++ )
  1349. {
  1350. // arrContentPoints[i].x = arrWndPoints[i].x * 0.9700f;
  1351. // arrContentPoints[i].y = arrWndPoints[i].y * 0.8000f;
  1352. // arrContentPoints[i].z = arrWndPoints[i].z - arrWndPoints[i].z * 0.0001f;
  1353. arrContentPoints[i].x = arrWndPoints[i].x * 0.9650f;
  1354. arrContentPoints[i].y = arrWndPoints[i].y * ( (i < 2 ) ? 0.7850f : 0.7600f );
  1355. arrContentPoints[i].z = arrWndPoints[i].z - arrWndPoints[i].z * 0.0001f;
  1356. }
  1357. }
  1358. void C3DWnd::OnRender(
  1359. C3DCamera * pCam,
  1360. C3DView * pView3D,
  1361. LPVOID lpvCookie,
  1362. C3DMirror * pObjMirror
  1363. )
  1364. {
  1365. ASSERT_VALID( this );
  1366. ASSERT_VALID( pCam );
  1367. ASSERT_VALID( pView3D );
  1368. pCam;
  1369. pView3D;
  1370. lpvCookie;
  1371. pObjMirror;
  1372. glPushMatrix();
  1373. glMultMatrixf( m_mtxLastTransformation.arr );
  1374. glEnable( GL_ALPHA_TEST );
  1375. GL_VIEWS_CHECK_OPENGL_ERROR
  1376. glAlphaFunc( GL_NOTEQUAL, 0.0f );
  1377. GL_VIEWS_CHECK_OPENGL_ERROR
  1378. glEnable( GL_BLEND );
  1379. GL_VIEWS_CHECK_OPENGL_ERROR
  1380. glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR );
  1381. GL_VIEWS_CHECK_OPENGL_ERROR
  1382. glEnable( GL_TEXTURE_2D );
  1383. GL_VIEWS_CHECK_OPENGL_ERROR
  1384. glBindTexture(
  1385. GL_TEXTURE_2D,
  1386. pView3D->m_TextureIds[m_nPlaneTextureIndex]
  1387. );
  1388. GL_VIEWS_CHECK_OPENGL_ERROR
  1389. glDisable( GL_DEPTH_TEST );
  1390. GL_VIEWS_CHECK_OPENGL_ERROR
  1391. glBegin(GL_QUADS);
  1392. glNormal3fv( m_lastNormal.arr );
  1393. glTexCoord2f(0.0f, 0.0f); glVertex3fv( m_arrWndPoints[0].arr );
  1394. glTexCoord2f(1.0f, 0.0f); glVertex3fv( m_arrWndPoints[1].arr );
  1395. glTexCoord2f(1.0f, 1.0f); glVertex3fv( m_arrWndPoints[2].arr );
  1396. glTexCoord2f(0.0f, 1.0f); glVertex3fv( m_arrWndPoints[3].arr );
  1397. glEnd();
  1398. glEnable( GL_DEPTH_TEST );
  1399. GL_VIEWS_CHECK_OPENGL_ERROR
  1400. glDisable( GL_TEXTURE_2D );
  1401. GL_VIEWS_CHECK_OPENGL_ERROR
  1402. glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
  1403. GL_VIEWS_CHECK_OPENGL_ERROR
  1404. glDisable( GL_BLEND );
  1405. GL_VIEWS_CHECK_OPENGL_ERROR
  1406. glDisable( GL_ALPHA_TEST );
  1407. GL_VIEWS_CHECK_OPENGL_ERROR
  1408. glPopMatrix();
  1409. }
  1410. /////////////////////////////////////////////////////////////////////////////
  1411. // C3DMirror
  1412. IMPLEMENT_DYNCREATE( C3DMirror, C3DWnd );
  1413. volatile bool C3DMirror::g_bRenderMirrors = true;
  1414. C3DMirror::C3DMirror(
  1415. LPCTSTR sName, // = GL_VIEWS_WND_MIRROR
  1416. int nPlaneTextureIndex, // = GL_VIEWS_TEXTURE_IDX_WND_MIRROR
  1417. _v3rct pt0, // = C3DWnd::g_arrDefPointsWndMirror[0]
  1418. _v3rct pt1, // = C3DWnd::g_arrDefPointsWndMirror[1]
  1419. _v3rct pt2, // = C3DWnd::g_arrDefPointsWndMirror[2]
  1420. _v3rct pt3  // = C3DWnd::g_arrDefPointsWndMirror[3]
  1421. )
  1422. : C3DWnd( sName, nPlaneTextureIndex, pt0, pt1, pt2, pt3 )
  1423. , m_bRenderingThisMirror( false )
  1424. {
  1425. }
  1426. C3DMirror::~C3DMirror()
  1427. {
  1428. }
  1429. void C3DMirror::OnRender(
  1430. C3DCamera * pCam,
  1431. C3DView * pView3D,
  1432. LPVOID lpvCookie,
  1433. C3DMirror * pObjMirror
  1434. )
  1435. {
  1436. ASSERT_VALID( this );
  1437. ASSERT_VALID( pCam );
  1438. ASSERT_VALID( pView3D );
  1439. pCam;
  1440. pView3D;
  1441. lpvCookie;
  1442. if( m_bRenderingThisMirror )
  1443. return;
  1444. C3DWnd::OnRender( pCam, pView3D, lpvCookie, pObjMirror );
  1445. if( !g_bRenderMirrors )
  1446. return;
  1447. if( pObjMirror != NULL )
  1448. return; // multiple mirrors currently not supported by this sample
  1449. m_bRenderingThisMirror = true;
  1450. // clear mirror (make it black)
  1451. glDisable( GL_DEPTH_TEST );
  1452. GL_VIEWS_CHECK_OPENGL_ERROR
  1453. glPushMatrix();
  1454. glMultMatrixf( m_mtxLastTransformation.arr );
  1455. glBegin( GL_QUADS );
  1456. glColor3f( 0.0f, 0.0f, 0.0f );
  1457. glVertex3fv( m_arrContentPoints[0].arr );
  1458. glVertex3fv( m_arrContentPoints[1].arr );
  1459. glVertex3fv( m_arrContentPoints[2].arr );
  1460. glVertex3fv( m_arrContentPoints[3].arr );
  1461. glColor3f( 1.0f, 1.0f, 1.0f );
  1462. glEnd();
  1463. glPopMatrix();
  1464. glEnable( GL_DEPTH_TEST );
  1465. GL_VIEWS_CHECK_OPENGL_ERROR
  1466. // create content mask in the stencil buffer
  1467. glEnable( GL_STENCIL_TEST );
  1468. GL_VIEWS_CHECK_OPENGL_ERROR
  1469. glStencilFunc( GL_ALWAYS, 1, 1 );
  1470. GL_VIEWS_CHECK_OPENGL_ERROR
  1471. glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
  1472. GL_VIEWS_CHECK_OPENGL_ERROR
  1473. glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
  1474. GL_VIEWS_CHECK_OPENGL_ERROR
  1475. glDisable( GL_DEPTH_TEST );
  1476. GL_VIEWS_CHECK_OPENGL_ERROR
  1477. glPushMatrix();
  1478. glMultMatrixf( m_mtxLastTransformation.arr );
  1479. glBegin( GL_QUADS );
  1480. glVertex3fv( m_arrContentPoints[0].arr );
  1481. glVertex3fv( m_arrContentPoints[1].arr );
  1482. glVertex3fv( m_arrContentPoints[2].arr );
  1483. glVertex3fv( m_arrContentPoints[3].arr );
  1484. glEnd();
  1485. glPopMatrix();
  1486. glEnable( GL_DEPTH_TEST );
  1487. GL_VIEWS_CHECK_OPENGL_ERROR
  1488. glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
  1489. GL_VIEWS_CHECK_OPENGL_ERROR
  1490. // compute reflection matrix and render mirror content
  1491. glStencilFunc( GL_EQUAL, 1, 1 );
  1492. GL_VIEWS_CHECK_OPENGL_ERROR
  1493. glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
  1494. GL_VIEWS_CHECK_OPENGL_ERROR
  1495. glPushMatrix();
  1496. _mt _mtxReflection;
  1497. // TODO: calc dynamically m_arrContentPoints[0].z for _ptEq (plane equation)
  1498. _v4t _ptEq( m_lastNormal.x, m_lastNormal.y, m_lastNormal.z, m_arrContentPoints[0].z );
  1499. //_v4t _ptEq( 0.0f, 0.0f, -1.0f, 0.35f );
  1500. _mtxReflection.load_reflection( _ptEq );
  1501. glMultMatrixf( _mtxReflection.arr );
  1502. double _ptEqDouble[4] = { _ptEq.a, _ptEq.b, _ptEq.c, _ptEq.d };
  1503. glClipPlane( GL_CLIP_PLANE0, _ptEqDouble );
  1504. GL_VIEWS_CHECK_OPENGL_ERROR
  1505. glEnable( GL_CLIP_PLANE0 );
  1506. GL_VIEWS_CHECK_OPENGL_ERROR
  1507. glCullFace( GL_BACK );
  1508. GL_VIEWS_CHECK_OPENGL_ERROR
  1509. the3DPipe.GetRoot()->WalkTree(
  1510. C3DObject::EWTQ_RENDER,
  1511. pCam,
  1512. pView3D,
  1513. lpvCookie,
  1514. this
  1515. );
  1516. glCullFace( GL_FRONT );
  1517. GL_VIEWS_CHECK_OPENGL_ERROR
  1518. glDisable( GL_CLIP_PLANE0 );
  1519. GL_VIEWS_CHECK_OPENGL_ERROR
  1520. glPopMatrix();
  1521. glDisable( GL_STENCIL_TEST );
  1522. GL_VIEWS_CHECK_OPENGL_ERROR
  1523. m_bRenderingThisMirror = false;
  1524. }
  1525. void C3DMirror::OnQueryTreeDisplayParms(
  1526. CString & strTreeItemText,
  1527. int & nTreeImageIndex
  1528. )
  1529. {
  1530. ASSERT_VALID( this );
  1531. C3DObject::OnQueryTreeDisplayParms(
  1532. strTreeItemText,
  1533. nTreeImageIndex
  1534. );
  1535. nTreeImageIndex = GL_VIEWS_TREE_IMG_IDX_WND_MIRROR;
  1536. }
  1537. /////////////////////////////////////////////////////////////////////////////
  1538. // C3DAviPlayer
  1539. IMPLEMENT_DYNCREATE( C3DAviPlayer, C3DWnd );
  1540. volatile bool C3DAviPlayer::g_bRenderAviPlayers = true;
  1541. static LPCTSTR g_sAviPlayerTempFilePath = _T(".\AVITEMP.AVI");
  1542. C3DAviPlayer::C3DAviPlayer(
  1543. LPCTSTR sName, // = GL_VIEWS_WND_AVI_PLAYER
  1544. int nPlaneTextureIndex, // = GL_VIEWS_TEXTURE_IDX_WND_AVI_PLAYER
  1545. int nSurfaceTextureIndex, // = GL_VIEWS_TEXTURE_IDX_AVI_SURFACE
  1546. _v3rct pt0, // = C3DWnd::g_arrDefPointsWndAviPlayer[0]
  1547. _v3rct pt1, // = C3DWnd::g_arrDefPointsWndAviPlayer[1]
  1548. _v3rct pt2, // = C3DWnd::g_arrDefPointsWndAviPlayer[2]
  1549. _v3rct pt3, // = C3DWnd::g_arrDefPointsWndAviPlayer[3]
  1550. int nRenderWidth, // = 256
  1551. int nRenderHeight // = 256
  1552. )
  1553. : C3DWnd( sName, nPlaneTextureIndex, pt0, pt1, pt2, pt3 )
  1554. , m_bInitComplete( false )
  1555. , m_pAviStream( NULL )
  1556. , m_pGetFrame( NULL )
  1557. , m_nAviWidth( 0 )
  1558. , m_nAviHeight( 0 )
  1559. , m_nRenderWidth( nRenderWidth )
  1560. , m_nRenderHeight( nRenderHeight )
  1561. , m_nRenderSize( nRenderWidth*nRenderHeight )
  1562. , m_hDrawDib( NULL )
  1563. , m_nFrameNumber( 0 )
  1564. , m_nFrameCount( 0 )
  1565. , m_hDC( NULL )
  1566. , m_hBitmap( NULL )
  1567. , m_pDibRawData( NULL )
  1568. , m_nSurfaceTextureIndex( nSurfaceTextureIndex )
  1569. {
  1570. ATLASSERT( m_nRenderWidth > 0 );
  1571. ATLASSERT( m_nRenderHeight > 0 );
  1572. ATLASSERT( m_nRenderSize > 0 );
  1573. }
  1574. C3DAviPlayer::~C3DAviPlayer()
  1575. {
  1576. ASSERT( !m_bInitComplete );
  1577. }
  1578. void C3DAviPlayer::stat_AlertDisplay( LPCTSTR sText )
  1579. {
  1580. ASSERT( sText != NULL );
  1581. ::AfxMessageBox( sText, MB_OK|MB_ICONERROR );
  1582. }
  1583. void C3DAviPlayer::OnThreadInit( LPVOID lpvCookie )
  1584. {
  1585. ASSERT_VALID( this );
  1586. C3DObject::OnThreadInit( lpvCookie );
  1587. ATLASSERT( m_nRenderWidth > 0 );
  1588. ATLASSERT( m_nRenderHeight > 0 );
  1589. ATLASSERT( m_nRenderSize > 0 );
  1590. if( !stat_IsFileExists(g_sAviPlayerTempFilePath) )
  1591. {
  1592. LPVOID lpvBuffer = NULL;
  1593. DWORD dwSize = 0;
  1594. if( !stat_LoadResourceToMemory(
  1595. MAKEINTRESOURCE(IDR_AVIFILE_FOR_PLAYER),
  1596. _T("AVI"),
  1597. &lpvBuffer,
  1598. &dwSize
  1599. )
  1600. || lpvBuffer == NULL
  1601. || dwSize == 0
  1602. )
  1603. {
  1604. ASSERT( FALSE );
  1605. stat_AlertDisplay( _T("Failed to load AVI resource") );
  1606. return;
  1607. }
  1608. bool bFileSaved = false;
  1609. try
  1610. {
  1611. CFile _file(
  1612. g_sAviPlayerTempFilePath,
  1613. CFile::modeCreate
  1614. |CFile::modeWrite
  1615. |CFile::typeBinary
  1616. |CFile::shareExclusive
  1617. );
  1618. _file.Seek( 0, CFile::begin );
  1619. _file.Write( lpvBuffer, dwSize );
  1620. _file.Close();
  1621. bFileSaved = true;
  1622. } // try
  1623. catch( CException * pXept )
  1624. {
  1625. pXept->Delete();
  1626. ASSERT( FALSE );
  1627. } // catch( CException * pXept )
  1628. catch( ... )
  1629. {
  1630. ASSERT( FALSE );
  1631. } // catch( ... )
  1632. ::free( lpvBuffer );
  1633. if( !bFileSaved )
  1634. {
  1635. ASSERT( FALSE );
  1636. stat_AlertDisplay( _T("Failed to extract AVI resource") );
  1637. return;
  1638. }
  1639. } // if( !statIsFileExists(sFilePath) )
  1640. ::AVIFileInit();
  1641. if( ::AVIStreamOpenFromFile(
  1642. &m_pAviStream,
  1643. g_sAviPlayerTempFilePath,
  1644. streamtypeVIDEO,
  1645. 0,
  1646. OF_READ,
  1647. NULL
  1648. ) != 0
  1649. )
  1650. {
  1651. ASSERT( FALSE );
  1652. stat_AlertDisplay( _T("AVI stream initialization failed") );
  1653. return;
  1654. }
  1655. ::AVIStreamInfo(
  1656. m_pAviStream,
  1657. &m_pAviInfo,
  1658. sizeof(m_pAviInfo)
  1659. );
  1660. m_nAviWidth =
  1661. m_pAviInfo.rcFrame.right - m_pAviInfo.rcFrame.left;
  1662. m_nAviHeight =
  1663. m_pAviInfo.rcFrame.bottom - m_pAviInfo.rcFrame.top;
  1664. m_nFrameCount =
  1665. ::AVIStreamLength( m_pAviStream );
  1666. m_hDC =
  1667. ::CreateCompatibleDC( NULL );
  1668. if( m_hDC == NULL )
  1669. {
  1670. ASSERT( FALSE );
  1671. stat_AlertDisplay( _T("Failed to alloc HDC for AVI stream") );
  1672. return;
  1673. }
  1674. ::memset( &m_dataBmpInfoHdr, 0, sizeof(BITMAPINFOHEADER) );
  1675. m_dataBmpInfoHdr.biSize = sizeof(BITMAPINFOHEADER);
  1676. m_dataBmpInfoHdr.biPlanes = 1;
  1677. m_dataBmpInfoHdr.biBitCount = 32; //24;
  1678. m_dataBmpInfoHdr.biWidth = m_nRenderWidth;
  1679. m_dataBmpInfoHdr.biHeight = m_nRenderHeight;
  1680. m_dataBmpInfoHdr.biCompression = BI_RGB;
  1681. m_hBitmap =
  1682. ::CreateDIBSection(
  1683. m_hDC,
  1684. (BITMAPINFO*)( &m_dataBmpInfoHdr ),
  1685. DIB_RGB_COLORS,
  1686. (void**)(&m_pDibRawData),
  1687. NULL,
  1688. NULL
  1689. );
  1690. if( m_hBitmap == NULL )
  1691. {
  1692. ASSERT( FALSE );
  1693. stat_AlertDisplay( _T("Failed to create DIB section") );
  1694. return;
  1695. }
  1696. ATLASSERT( m_pDibRawData != NULL );
  1697. ::SelectObject( m_hDC, m_hBitmap );
  1698. m_pGetFrame =
  1699. ::AVIStreamGetFrameOpen(
  1700. m_pAviStream,
  1701. NULL
  1702. );
  1703. if( m_pGetFrame == NULL )
  1704. {
  1705. // ASSERT( FALSE );
  1706. stat_AlertDisplay( _T("AVI frame initialization failed") );
  1707. return;
  1708. }
  1709. m_hDrawDib = ::DrawDibOpen();
  1710. if( m_hDrawDib == NULL )
  1711. {
  1712. ASSERT( FALSE );
  1713. stat_AlertDisplay( _T("DrawDibOpen() failed") );
  1714. return;
  1715. }
  1716. m_bInitComplete = true;
  1717. }
  1718. void C3DAviPlayer::OnThreadDone( LPVOID lpvCookie )
  1719. {
  1720. ASSERT_VALID( this );
  1721. C3DObject::OnThreadDone( lpvCookie );
  1722. if( m_hBitmap != NULL )
  1723. ::DeleteObject( m_hBitmap );
  1724. if( m_hDrawDib != NULL )
  1725. ::DrawDibClose( m_hDrawDib );
  1726. if( m_pGetFrame != NULL )
  1727. ::AVIStreamGetFrameClose( m_pGetFrame );
  1728. if( m_pAviStream != NULL )
  1729. ::AVIStreamRelease( m_pAviStream );
  1730. ::AVIFileExit();
  1731. try
  1732. {
  1733. CFile::Remove( g_sAviPlayerTempFilePath );
  1734. } // try
  1735. catch( CException * pXept )
  1736. {
  1737. pXept->Delete();
  1738. ASSERT( FALSE );
  1739. } // catch( CException * pXept )
  1740. catch( ... )
  1741. {
  1742. ASSERT( FALSE );
  1743. } // catch( ... )
  1744. m_bInitComplete = false;
  1745. }
  1746. void C3DAviPlayer::OnRender(
  1747. C3DCamera * pCam,
  1748. C3DView * pView3D,
  1749. LPVOID lpvCookie,
  1750. C3DMirror * pObjMirror
  1751. )
  1752. {
  1753. ASSERT_VALID( this );
  1754. ASSERT_VALID( pCam );
  1755. ASSERT_VALID( pView3D );
  1756. pCam;
  1757. pView3D;
  1758. lpvCookie;
  1759. C3DWnd::OnRender( pCam, pView3D, lpvCookie, pObjMirror );
  1760. if( (!g_bRenderAviPlayers) || (!m_bInitComplete) )
  1761. return;
  1762. glPushMatrix();
  1763. glMultMatrixf( m_mtxLastTransformation.arr );
  1764. glEnable( GL_TEXTURE_2D );
  1765. GL_VIEWS_CHECK_OPENGL_ERROR
  1766. glBindTexture(
  1767. GL_TEXTURE_2D,
  1768. pView3D->m_TextureIds[m_nSurfaceTextureIndex]
  1769. );
  1770. GL_VIEWS_CHECK_OPENGL_ERROR
  1771. ////////// begin get AVI frame //////////
  1772. LPBITMAPINFOHEADER lpbi;
  1773. lpbi = (LPBITMAPINFOHEADER)
  1774. ::AVIStreamGetFrame(
  1775. m_pGetFrame,
  1776. m_nFrameNumber
  1777. );
  1778. unsigned char * pAviFrameRawData = (unsigned char *)
  1779. lpbi
  1780. + lpbi->biSize
  1781. + lpbi->biClrUsed * sizeof(RGBQUAD);
  1782. ::DrawDibDraw(
  1783. m_hDrawDib,
  1784. m_hDC,
  1785. 0, 0, m_nRenderWidth, m_nRenderHeight,
  1786. lpbi,
  1787. pAviFrameRawData,
  1788. 0, 0, m_nAviWidth, m_nAviHeight,
  1789. 0
  1790. );
  1791. unsigned char * pBufferRGBA = m_pDibRawData;
  1792. for( int i = 0; i < m_nRenderSize; i++ )
  1793. {
  1794. unsigned char _byte = *pBufferRGBA;
  1795. *pBufferRGBA = *(pBufferRGBA+2);
  1796. pBufferRGBA ++;
  1797. pBufferRGBA ++;
  1798. *pBufferRGBA = _byte;
  1799. pBufferRGBA ++;
  1800. *pBufferRGBA = 255;
  1801. pBufferRGBA ++;
  1802. }
  1803. glTexSubImage2D(
  1804. GL_TEXTURE_2D, 0,
  1805. 0, 0, m_nRenderWidth, m_nRenderHeight,
  1806. GL_RGBA, GL_UNSIGNED_BYTE,
  1807. m_pDibRawData
  1808. );
  1809. GL_VIEWS_CHECK_OPENGL_ERROR
  1810. ////////// end get AVI frame //////////
  1811. glBegin( GL_QUADS );
  1812. glTexCoord2f( 0.0f, 0.0f ); glVertex3fv( m_arrContentPoints[0].arr );
  1813. glTexCoord2f( 1.0f, 0.0f ); glVertex3fv( m_arrContentPoints[1].arr );
  1814. glTexCoord2f( 1.0f, 1.0f ); glVertex3fv( m_arrContentPoints[2].arr );
  1815. glTexCoord2f( 0.0f, 1.0f ); glVertex3fv( m_arrContentPoints[3].arr );
  1816. glEnd();
  1817. glDisable( GL_TEXTURE_2D );
  1818. GL_VIEWS_CHECK_OPENGL_ERROR
  1819. glPopMatrix();
  1820. }
  1821. void C3DAviPlayer::OnQueryTreeDisplayParms(
  1822. CString & strTreeItemText,
  1823. int & nTreeImageIndex
  1824. )
  1825. {
  1826. ASSERT_VALID( this );
  1827. C3DObject::OnQueryTreeDisplayParms(
  1828. strTreeItemText,
  1829. nTreeImageIndex
  1830. );
  1831. nTreeImageIndex = GL_VIEWS_TREE_IMG_IDX_WND_AVI;
  1832. }
  1833. void C3DAviPlayer::OnPlay(
  1834. LPVOID lpvCookie
  1835. )
  1836. {
  1837. ASSERT_VALID( this );
  1838. lpvCookie;
  1839. #ifdef GL_VIEWS_DRAW_ANIMS
  1840. if( m_bInitComplete && g_bRenderAviPlayers )
  1841. {
  1842. m_nFrameNumber ++;
  1843. if( m_nFrameNumber >= m_nFrameCount )
  1844. m_nFrameNumber = 0;
  1845. } // if( m_bInitComplete && g_bRenderAviPlayers )
  1846. #endif // GL_VIEWS_DRAW_ANIMS
  1847. }
  1848. /////////////////////////////////////////////////////////////////////////////
  1849. // C3DTexture
  1850. void C3DTexture::_Destroy()
  1851. {
  1852. if( m_sizeTexture.cx == 0 )
  1853. {
  1854. ASSERT( m_sizeTexture.cy == 0 );
  1855. ASSERT( m_pData == NULL );
  1856. return;
  1857. }
  1858. ASSERT( m_sizeTexture.cy != 0 );
  1859. ASSERT( m_pData != NULL );
  1860. free( m_pData );
  1861. m_sizeTexture.cx = m_sizeTexture.cy = 0;
  1862. m_pData = NULL;
  1863. m_bAlphaLayerExist = false;
  1864. }
  1865. C3DTexture::C3DTexture()
  1866. : m_sizeTexture( 0, 0 )
  1867. , m_pData( NULL )
  1868. , m_bAlphaLayerExist( false )
  1869. {
  1870. }
  1871. C3DTexture::~C3DTexture()
  1872. {
  1873. _Destroy();
  1874. }
  1875. bool C3DTexture::LoadResourceBitmapAs32Bit(
  1876. LPCTSTR lpszResource,
  1877. unsigned char nAlphaClearVal // = 255
  1878. )
  1879. {
  1880. Empty();
  1881. CBitmap _bmp, _dib, *pBmpOldSrc = NULL, *pBmpOldDst = NULL;
  1882. if( !_bmp.LoadBitmap(lpszResource) )
  1883. {
  1884. ASSERT( FALSE );
  1885. return false;
  1886. }
  1887. BITMAP _bmp_info;
  1888. _bmp.GetBitmap( &_bmp_info );
  1889. if( _bmp_info.bmPlanes != 1
  1890. || _bmp_info.bmWidth <= 0
  1891. || _bmp_info.bmHeight <= 0
  1892. )
  1893. {
  1894. ASSERT( FALSE );
  1895. return false;
  1896. }
  1897. const int nBytesPerPixel = 4;
  1898. int nPixelCount = _bmp_info.bmWidth * _bmp_info.bmHeight;
  1899. int nBytesCount = nPixelCount * nBytesPerPixel;
  1900. CWindowDC dcDesktop( NULL );
  1901. CDC dcSrc, dcDst;
  1902. if( !dcSrc.CreateCompatibleDC(&dcDesktop)
  1903. || !dcDst.CreateCompatibleDC(&dcDesktop)
  1904. )
  1905. {
  1906. ASSERT( FALSE );
  1907. return false;
  1908. }
  1909. BITMAPINFOHEADER bih;
  1910. ::memset( (LPVOID)&bih, 0, sizeof(BITMAPINFOHEADER) );
  1911. bih.biSize = sizeof(BITMAPINFOHEADER);
  1912. bih.biWidth = _bmp_info.bmWidth;
  1913. bih.biHeight = _bmp_info.bmHeight;
  1914. bih.biPlanes = 1;
  1915. bih.biBitCount = 32; /*_bmp_info.bmBitsPixel*/;
  1916. bih.biCompression = BI_RGB;
  1917. bih.biSizeImage = nPixelCount;
  1918. LPVOID pColorSurface = NULL;
  1919. HBITMAP hDIB =
  1920. ::CreateDIBSection(
  1921. dcDesktop.GetSafeHdc(),
  1922. (LPBITMAPINFO)&bih,
  1923. DIB_RGB_COLORS,
  1924. &pColorSurface,
  1925. NULL,
  1926. NULL
  1927. );
  1928. if( hDIB == NULL || pColorSurface == NULL )
  1929. {
  1930. ASSERT( FALSE );
  1931. return false;
  1932. }
  1933. _dib.Attach( hDIB );
  1934. pBmpOldSrc = dcSrc.SelectObject( &_bmp );
  1935. pBmpOldDst = dcDst.SelectObject( &_dib );
  1936. dcDst.BitBlt(
  1937. 0, 0, _bmp_info.bmWidth, _bmp_info.bmHeight,
  1938. &dcSrc, 
  1939. 0, 0,
  1940. SRCCOPY
  1941. );
  1942. dcDst.SelectObject( pBmpOldDst );
  1943. dcSrc.SelectObject( pBmpOldSrc );
  1944. m_pData = ::malloc( nBytesCount );
  1945. if( m_pData == NULL )
  1946. {
  1947. ASSERT( FALSE );
  1948. return false;
  1949. }
  1950. ::memcpy( m_pData, pColorSurface, nBytesCount );
  1951. m_sizeTexture.cx = _bmp_info.bmWidth;
  1952. m_sizeTexture.cy = _bmp_info.bmHeight;
  1953. ASSERT( !m_bAlphaLayerExist );
  1954. m_bAlphaLayerExist = true;
  1955. unsigned char
  1956. _uc0, _uc1, _uc2,
  1957. *pData = (unsigned char *)m_pData;
  1958. for( int i = 0; i < nPixelCount; i++ )
  1959. {
  1960. _uc0 = pData[ 4*i + 0 ];
  1961. _uc1 = pData[ 4*i + 1 ];
  1962. _uc2 = pData[ 4*i + 2 ];
  1963. pData[ 4*i + 0 ] = _uc2;
  1964. pData[ 4*i + 1 ] = _uc1;
  1965. pData[ 4*i + 2 ] = _uc0;
  1966. pData[ 4*i + 3 ] = nAlphaClearVal;
  1967. }
  1968. return true;
  1969. }
  1970. bool C3DTexture::AddAlphaLayer(
  1971. unsigned char nAlphaClearVal // = 255
  1972. )
  1973. {
  1974. if( IsEmpty() || m_bAlphaLayerExist )
  1975. return false;
  1976. unsigned char * pDataOld = (unsigned char *)m_pData;
  1977. ASSERT( pDataOld != NULL );
  1978. ASSERT( m_sizeTexture.cx > 0 && m_sizeTexture.cy > 0 );
  1979. int nPixelCount = m_sizeTexture.cx * m_sizeTexture.cy;
  1980. unsigned char * pDataNew = new unsigned char[4*nPixelCount];
  1981. for( int i = 0; i < nPixelCount; i++ )
  1982. {
  1983. pDataNew[ 4*i + 0 ] = pDataOld[ 3*i + 0 ];
  1984. pDataNew[ 4*i + 1 ] = pDataOld[ 3*i + 1 ];
  1985. pDataNew[ 4*i + 2 ] = pDataOld[ 3*i + 2 ];
  1986. pDataNew[ 4*i + 3 ] = nAlphaClearVal;
  1987. }
  1988. delete [] pDataOld;
  1989. pDataOld = pDataNew;
  1990. return true;
  1991. }
  1992. bool C3DTexture::SetAlphaLayer(
  1993. unsigned char nAlphaSetVal // = 255
  1994. )
  1995. {
  1996. if( IsEmpty() || (!m_bAlphaLayerExist) )
  1997. return false;
  1998. unsigned char * pData = (unsigned char *)m_pData;
  1999. ASSERT( pData != NULL );
  2000. ASSERT( m_sizeTexture.cx > 0 && m_sizeTexture.cy > 0 );
  2001. int nPixelCount = m_sizeTexture.cx * m_sizeTexture.cy;
  2002. for( int i = 0; i < nPixelCount; i++ )
  2003. pData[ 4*i + 3 ] = nAlphaSetVal;
  2004. return true;
  2005. }
  2006. bool C3DTexture::SetAlphaLayerIf(
  2007. unsigned char nAlphaSetVal,
  2008. COLORREF clr
  2009. )
  2010. {
  2011. if( IsEmpty() || (!m_bAlphaLayerExist) )
  2012. return false;
  2013. unsigned char * pData = (unsigned char *)m_pData;
  2014. ASSERT( pData != NULL );
  2015. ASSERT( m_sizeTexture.cx > 0 && m_sizeTexture.cy > 0 );
  2016. int nPixelCount = m_sizeTexture.cx * m_sizeTexture.cy;
  2017. unsigned char byteR = GetRValue(clr);
  2018. unsigned char byteG = GetGValue(clr);
  2019. unsigned char byteB = GetBValue(clr);
  2020. for( int i = 0; i < nPixelCount; i++ )
  2021. {
  2022. if( byteR == pData[ 4*i + 0 ]
  2023. && byteG == pData[ 4*i + 1 ]
  2024. && byteB == pData[ 4*i + 2 ]
  2025. )
  2026. pData[ 4*i + 3 ] = nAlphaSetVal;
  2027. }
  2028. return true;
  2029. }
  2030. bool C3DTexture::SetAlphaLayerNB()
  2031. {
  2032. if( IsEmpty() || (!m_bAlphaLayerExist) )
  2033. return false;
  2034. unsigned char * pData = (unsigned char *)m_pData;
  2035. ASSERT( pData != NULL );
  2036. ASSERT( m_sizeTexture.cx > 0 && m_sizeTexture.cy > 0 );
  2037. int nPixelCount = m_sizeTexture.cx * m_sizeTexture.cy;
  2038. for( int i = 0; i < nPixelCount; i++ )
  2039. {
  2040. unsigned char byteR = pData[ 4*i + 0 ];
  2041. pData[ 4*i + 3 ] = byteR;
  2042. }
  2043. return true;
  2044. }
  2045. /////////////////////////////////////////////////////////////////////////////
  2046. // C3DView
  2047. IMPLEMENT_DYNCREATE( C3DView, CObject );
  2048. C3DView::C3DView(
  2049. HWND hWndOutput // = NULL
  2050. )
  2051. : m_hWndOutput( hWndOutput )
  2052. , m_sizeView( GL_VIEWS_MIN_VIEW_DX, GL_VIEWS_MIN_VIEW_DY )
  2053. , m_sizeViewNE( GL_VIEWS_MIN_VIEW_DX, GL_VIEWS_MIN_VIEW_DY )
  2054. , m_hOpenGlContext( NULL )
  2055. , m_nCameraIndex( 0L )
  2056. , m_strViewName( _T("noname") )
  2057. {
  2058. ASSERT( m_hWndOutput != NULL );
  2059. ASSERT( ::IsWindow(m_hWndOutput) );
  2060. _Init();
  2061. }
  2062. C3DView::~C3DView()
  2063. {
  2064. _Done();
  2065. }
  2066. bool C3DView::IsViewVisible() const
  2067. {
  2068. ASSERT_VALID( this );
  2069. ASSERT( m_hWndOutput != NULL );
  2070. ASSERT( ::IsWindow( ((HWND)m_hWndOutput) ) );
  2071. if( ::IsWindowVisible( ((HWND)m_hWndOutput) ) )
  2072. {
  2073. return (
  2074. ::SendMessage(
  2075. m_hWndOutput,
  2076. GL_VIEWS_WM_QUERY_VIEW_VISIBILITY,
  2077. 0L,
  2078. 0L
  2079. ) != 0
  2080. ) ? true : false;
  2081. // HWND hWndParent = ::GetParent( m_hWndOutput );
  2082. // ASSERT( hWndParent != NULL );
  2083. // ASSERT( ::IsWindow( hWndParent ) );
  2084. // if( ::IsWindowVisible( hWndParent ) )
  2085. // return true;
  2086. }
  2087. return false;
  2088. }
  2089. void C3DView::Lock()
  2090. {
  2091. ASSERT_VALID( this );
  2092. m_csGDI.Lock();
  2093. }
  2094. void C3DView::Unlock()
  2095. {
  2096. ASSERT_VALID( this );
  2097. m_csGDI.Unlock();
  2098. }
  2099. void C3DView::_Init()
  2100. {
  2101. m_dc.SetViewSize( m_sizeView, false );
  2102. m_dc.GetInternalBitmap();
  2103. ASSERT( m_dc.GetSafeHdc() != NULL );
  2104. if( m_hOpenGlContext != NULL )
  2105. return;
  2106. static PIXELFORMATDESCRIPTOR pfd =
  2107. {
  2108. sizeof(PIXELFORMATDESCRIPTOR),
  2109. 1,
  2110. PFD_SUPPORT_OPENGL|PFD_DRAW_TO_BITMAP,
  2111. PFD_TYPE_RGBA,
  2112. OnGlGetBufferBits(__EBB_COLOR),
  2113. 0, 0, 0, 0, 0, 0,
  2114. OnGlGetBufferBits(__EBB_ALPHA),
  2115. 0,
  2116. OnGlGetBufferBits(__EBB_ACCUM),
  2117. 0, 0, 0, 0,
  2118. OnGlGetBufferBits(__EBB_Z),
  2119. OnGlGetBufferBits(__EBB_STENCIL),
  2120. OnGlGetBufferBits(__EBB_AUXILIARY),
  2121. PFD_MAIN_PLANE,
  2122. 0,
  2123. 0, 0, 0
  2124. };
  2125. GLuint PixelFormat = ChoosePixelFormat( m_dc.GetSafeHdc(), &pfd );
  2126. if( !PixelFormat )
  2127. {
  2128. OnGlAlertDisplay( _T("Failed to choose the pixel format") );
  2129. ASSERT( FALSE );
  2130. return;
  2131. }
  2132. if( !SetPixelFormat( m_dc.GetSafeHdc(), PixelFormat, &pfd ) )
  2133. {
  2134. OnGlAlertDisplay( _T("Failed to set the pixel format") );
  2135. ASSERT( FALSE );
  2136. return;
  2137. }
  2138. m_hOpenGlContext = wglCreateContext( m_dc.GetSafeHdc() );
  2139. if( m_hOpenGlContext == NULL )
  2140. {
  2141. OnGlAlertDisplay( _T("Failed to create OpenGL rendering context") );
  2142. ASSERT( FALSE );
  2143. return;
  2144. }
  2145. if( !wglMakeCurrent( m_dc.GetSafeHdc(), m_hOpenGlContext ) )
  2146. {
  2147. OnGlAlertDisplay( _T("Failed to activate OpenGL rendering context") );
  2148. ASSERT( FALSE );
  2149. return;
  2150. }
  2151. struct
  2152. {
  2153. LPCTSTR m_lpszResource;
  2154. } _texture_init_data[GL_VIEWS_TEXTURE_COUNT] =
  2155. {
  2156. { MAKEINTRESOURCE(IDB_BITMAP_CUBE_ORANGE) },
  2157. { MAKEINTRESOURCE(IDB_BITMAP_CUBE_WHITE) },
  2158. { MAKEINTRESOURCE(IDB_BITMAP_RING) },
  2159. { MAKEINTRESOURCE(IDB_BITMAP_BOTTOM_PLANE) },
  2160. { MAKEINTRESOURCE(IDB_BITMAP_WND_AVI_PLAYER) },
  2161. { MAKEINTRESOURCE(IDB_BITMAP_WND_AVI_PLAYER) }, // for surface
  2162. { MAKEINTRESOURCE(IDB_BITMAP_WND_MIRROR) },
  2163. { MAKEINTRESOURCE(IDB_BITMAP_EARTH) },
  2164. { MAKEINTRESOURCE(IDB_BITMAP_MOON) },
  2165. };
  2166. glEnable( GL_TEXTURE_2D );
  2167. GL_VIEWS_CHECK_OPENGL_ERROR
  2168. for( int nTextureIdx = 0; nTextureIdx < GL_VIEWS_TEXTURE_COUNT; nTextureIdx++ )
  2169. {
  2170. C3DTexture objTexture;
  2171. if( !objTexture.LoadResourceBitmapAs32Bit(
  2172. _texture_init_data[nTextureIdx].m_lpszResource
  2173. )
  2174. )
  2175. {
  2176. ASSERT( FALSE );
  2177. return;
  2178. }
  2179. ASSERT( objTexture.IsAlphaLayerExist() );
  2180. objTexture.SetAlphaLayerIf( 180, RGB(245,21,3) );
  2181. objTexture.SetAlphaLayerIf( 0, RGB(0,0,0) );
  2182. glGenTextures( 1, &m_TextureIds[nTextureIdx] );
  2183. GL_VIEWS_CHECK_OPENGL_ERROR
  2184. glBindTexture( GL_TEXTURE_2D, m_TextureIds[nTextureIdx] );
  2185. GL_VIEWS_CHECK_OPENGL_ERROR
  2186. glTexImage2D(
  2187. GL_TEXTURE_2D,
  2188. 0,
  2189. GL_RGBA,
  2190. objTexture.GetWidth(),
  2191. objTexture.GetHeight(),
  2192. 0,
  2193. GL_RGBA,
  2194. GL_UNSIGNED_BYTE,
  2195. objTexture.GetData()
  2196. );
  2197. GL_VIEWS_CHECK_OPENGL_ERROR
  2198. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
  2199. GL_VIEWS_CHECK_OPENGL_ERROR
  2200. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  2201. GL_VIEWS_CHECK_OPENGL_ERROR
  2202. }
  2203. glDisable( GL_TEXTURE_2D );
  2204. GL_VIEWS_CHECK_OPENGL_ERROR
  2205. ASSERT( !m_Font3D.IsFontCreated() );
  2206. VERIFY( m_Font3D.CreateFont( m_dc.GetSafeHdc() ) );
  2207. if( !wglMakeCurrent( NULL, NULL ) )
  2208. {
  2209. OnGlAlertDisplay( _T("Failed to release contexts") );
  2210. ASSERT( FALSE );
  2211. return;
  2212. }
  2213. }
  2214. void C3DView::_Done()
  2215. {
  2216. m_Font3D.DeleteFont();
  2217. if( m_hOpenGlContext != NULL )
  2218. {
  2219. if( !wglDeleteContext( m_hOpenGlContext ) )
  2220. {
  2221. OnGlAlertDisplay( _T("Failed to release rendering context") );
  2222. ASSERT( FALSE );
  2223. }
  2224. m_hOpenGlContext = NULL;
  2225. } // if( m_hOpenGlContext != NULL )
  2226. m_dc.DeleteDC();
  2227. }
  2228. void C3DView::SetViewSize( CSize sizeView )
  2229. {
  2230. ASSERT_VALID( this );
  2231. ASSERT( m_sizeView.cx >= GL_VIEWS_MIN_VIEW_DX && m_sizeView.cy >= GL_VIEWS_MIN_VIEW_DY );
  2232. ASSERT( m_sizeViewNE.cx >= GL_VIEWS_MIN_VIEW_DX && m_sizeViewNE.cy >= GL_VIEWS_MIN_VIEW_DY );
  2233. Lock();
  2234. m_sizeViewNE.cx = max( GL_VIEWS_MIN_VIEW_DX, sizeView.cx );
  2235. m_sizeViewNE.cy = max( GL_VIEWS_MIN_VIEW_DY, sizeView.cy );
  2236. Unlock();
  2237. }
  2238. void C3DView::AdjustViewSize(
  2239. bool bLockView // = true
  2240. )
  2241. {
  2242. ASSERT_VALID( this );
  2243. if( m_sizeView == m_sizeViewNE )
  2244. return;
  2245. if( bLockView )
  2246. Lock();
  2247. ASSERT( m_sizeView.cx >= GL_VIEWS_MIN_VIEW_DX && m_sizeView.cy >= GL_VIEWS_MIN_VIEW_DY );
  2248. ASSERT( m_sizeViewNE.cx >= GL_VIEWS_MIN_VIEW_DX && m_sizeViewNE.cy >= GL_VIEWS_MIN_VIEW_DY );
  2249. _Done();
  2250. m_sizeView = m_sizeViewNE;
  2251. _Init();
  2252. if( bLockView )
  2253. Unlock();
  2254. }
  2255. void C3DView::DoStepLeft( GLfloat fStepSize )
  2256. {
  2257. ASSERT_VALID( this );
  2258. Lock();
  2259. C3DCamera * pCam = the3DPipe.GetCamera( m_nCameraIndex );
  2260. ASSERT_VALID( pCam );
  2261. pCam->DoStepLeft( fStepSize );
  2262. Unlock();
  2263. }
  2264. void C3DView::DoStepUp( GLfloat fStepSize )
  2265. {
  2266. ASSERT_VALID( this );
  2267. Lock();
  2268. C3DCamera * pCam = the3DPipe.GetCamera( m_nCameraIndex );
  2269. ASSERT_VALID( pCam );
  2270. pCam->DoStepUp( fStepSize );
  2271. Unlock();
  2272. }
  2273. void C3DView::DoStepForward( GLfloat fStepSize )
  2274. {
  2275. ASSERT_VALID( this );
  2276. Lock();
  2277. C3DCamera * pCam = the3DPipe.GetCamera( m_nCameraIndex );
  2278. ASSERT_VALID( pCam );
  2279. pCam->DoStepForward( fStepSize );
  2280. Unlock();
  2281. }
  2282. void C3DView::DoLookLeft( GLfloat fAngleDegrees )
  2283. {
  2284. ASSERT_VALID( this );
  2285. Lock();
  2286. C3DCamera * pCam = the3DPipe.GetCamera( m_nCameraIndex );
  2287. ASSERT_VALID( pCam );
  2288. pCam->DoLookLeft( fAngleDegrees );
  2289. Unlock();
  2290. }
  2291. void C3DView::DoLookUp( GLfloat fAngleDegrees )
  2292. {
  2293. ASSERT_VALID( this );
  2294. Lock();
  2295. C3DCamera * pCam = the3DPipe.GetCamera( m_nCameraIndex );
  2296. ASSERT_VALID( pCam );
  2297. pCam->DoLookUp( fAngleDegrees );
  2298. Unlock();
  2299. }
  2300. void C3DView::DoLookOwnAxis( GLfloat fAngleDegrees )
  2301. {
  2302. ASSERT_VALID( this );
  2303. Lock();
  2304. C3DCamera * pCam = the3DPipe.GetCamera( m_nCameraIndex );
  2305. ASSERT_VALID( pCam );
  2306. pCam->DoLookOwnAxis( fAngleDegrees );
  2307. Unlock();
  2308. }
  2309. /////////////////////////////////////////////////////////////////////////////
  2310. // C3DPipeThread
  2311. C3DPipeThread the3DPipe;
  2312. C3DPipeThread::C3DPipeThread()
  2313. : m_bInitComplete( false )
  2314. , m_eventShutdownStart( FALSE, FALSE, NULL, NULL )
  2315. , m_eventShutdownComplete( FALSE, FALSE, NULL, NULL )
  2316. , m_eventRenderViews( FALSE, FALSE, NULL, NULL )
  2317. , m_pRoot( new C3DObject(GL_VIEWS_ROOTNAME) )
  2318. , m_bTimerAnimationEnabled( false )
  2319. {
  2320. m_bAutoDelete = FALSE;
  2321. }
  2322. C3DPipeThread::~C3DPipeThread()
  2323. {
  2324. ASSERT( !m_bAutoDelete );
  2325. _ResourcesFree();
  2326. m_arrCams.RemoveAll();
  2327. delete m_pRoot;
  2328. }
  2329. bool C3DPipeThread::_ResourcesInit()
  2330. {
  2331. return true;
  2332. }
  2333. void C3DPipeThread::_ResourcesFree()
  2334. {
  2335. int nViewCount = int( m_arrViews.GetSize() );
  2336. for( int nViewIdx = 0; nViewIdx < nViewCount; nViewIdx++ )
  2337. {
  2338. C3DView * pView3D = m_arrViews[nViewIdx];
  2339. ASSERT_VALID( pView3D );
  2340. delete pView3D;
  2341. }
  2342. m_arrViews.RemoveAll();
  2343. m_bInitComplete = false;
  2344. }
  2345. C3DObject * C3DPipeThread::GetRoot()
  2346. {
  2347. ASSERT_VALID( this );
  2348. ASSERT_VALID( m_pRoot );
  2349. return m_pRoot;
  2350. }
  2351. const C3DObject * C3DPipeThread::GetRoot() const
  2352. {
  2353. ASSERT_VALID( this );
  2354. ASSERT_VALID( m_pRoot );
  2355. return m_pRoot;
  2356. }
  2357. void C3DPipeThread::AddView( C3DView * pView3D )
  2358. {
  2359. ASSERT_VALID( this );
  2360. ASSERT_VALID( m_pRoot );
  2361. ASSERT_VALID( pView3D );
  2362. m_arrViews.Add( pView3D );
  2363. }
  2364. int C3DPipeThread::GetViewCount() const
  2365. {
  2366. ASSERT_VALID( this );
  2367. ASSERT_VALID( m_pRoot );
  2368. return int( m_arrViews.GetSize() );
  2369. }
  2370. C3DView * C3DPipeThread::GetView( int nIndex )
  2371. {
  2372. ASSERT_VALID( this );
  2373. ASSERT_VALID( m_pRoot );
  2374. ASSERT( 0 <= nIndex && nIndex < m_arrViews.GetSize() );
  2375. C3DView * pView3D = m_arrViews[nIndex];
  2376. ASSERT_VALID( pView3D );
  2377. return pView3D;
  2378. }
  2379. void C3DPipeThread::AddCamera( C3DCamera * pCam )
  2380. {
  2381. ASSERT_VALID( this );
  2382. ASSERT_VALID( m_pRoot );
  2383. ASSERT_VALID( pCam );
  2384. ASSERT( !m_bInitComplete );
  2385. m_pRoot->AddChild( pCam );
  2386. m_arrCams.Add( pCam );
  2387. }
  2388. int C3DPipeThread::GetCameraCount() const
  2389. {
  2390. ASSERT_VALID( this );
  2391. ASSERT_VALID( m_pRoot );
  2392. return int( m_arrCams.GetSize() );
  2393. }
  2394. C3DCamera * C3DPipeThread::GetCamera( int nIndex )
  2395. {
  2396. ASSERT_VALID( this );
  2397. ASSERT_VALID( m_pRoot );
  2398. ASSERT( 0 <= nIndex && nIndex < m_arrCams.GetSize() );
  2399. C3DCamera * pCam = m_arrCams[nIndex];
  2400. ASSERT_VALID( pCam );
  2401. return pCam;
  2402. }
  2403. void C3DPipeThread::Render()
  2404. {
  2405. m_eventRenderViews.SetEvent();
  2406. }
  2407. void C3DPipeThread::ShutdownAndWaitFor()
  2408. {
  2409. if( !m_bInitComplete )
  2410. return;
  2411. m_eventShutdownStart.SetEvent();
  2412. for( CExtPopupMenuWnd::PassMsgLoop(false);
  2413. !m_eventShutdownComplete.Lock(500);
  2414. CExtPopupMenuWnd::PassMsgLoop(false)
  2415. );
  2416. }
  2417. BOOL C3DPipeThread::InitInstance()
  2418. {
  2419. if( !_ResourcesInit() )
  2420. {
  2421. ASSERT( FALSE );
  2422. return FALSE;
  2423. }
  2424. ASSERT( m_arrViews.GetSize() > 0 );
  2425. m_bInitComplete = true;
  2426. return TRUE;
  2427. }
  2428. void C3DPipeThread::Delete()
  2429. {
  2430. ASSERT( !m_bAutoDelete );
  2431. _ResourcesFree();
  2432. CWinThread::Delete();
  2433. }
  2434. int C3DPipeThread::Run()
  2435. {
  2436. ASSERT( m_bInitComplete );
  2437. ASSERT_VALID( m_pRoot );
  2438. ObjectWriteAccessSet( true );
  2439. m_pRoot->WalkTree(
  2440. C3DObject::EWTQ_THREAD_INIT,
  2441. NULL,
  2442. NULL,
  2443. NULL,
  2444. NULL
  2445. );
  2446. ObjectWriteAccessSet( false );
  2447. int nViewCount = int( m_arrViews.GetSize() );
  2448. ASSERT( nViewCount > 0 );
  2449. CSyncObject * arrToWait[2] =
  2450. {
  2451. &m_eventShutdownStart,
  2452. &m_eventRenderViews
  2453. };
  2454. CMultiLock _ml( arrToWait, 2, FALSE );
  2455. for( ; true; )
  2456. {
  2457. DWORD dwWaitResult = _ml.Lock( INFINITE, FALSE, 0 );
  2458. if( dwWaitResult != (WAIT_OBJECT_0 + 1) )
  2459. break;
  2460. bool bResetWriteAccess = false;
  2461. for( int nViewIdx = 0; nViewIdx < nViewCount; nViewIdx++ )
  2462. {
  2463. C3DView * pView3D = m_arrViews[nViewIdx];
  2464. ASSERT_VALID( pView3D );
  2465. if( !pView3D->IsViewVisible() )
  2466. continue;
  2467. bool bSendMsgComplete = false;
  2468. pView3D->Lock();
  2469. ASSERT( !pView3D->m_strViewName.IsEmpty() );
  2470. pView3D->AdjustViewSize( false );
  2471. ASSERT( pView3D->Get3DDC().GetSafeHdc() != NULL );
  2472. if( pView3D->Get3DDC().GetSafeHdc() != NULL )
  2473. {
  2474. if( !bResetWriteAccess )
  2475. {
  2476. ObjectWriteAccessSet( true );
  2477. bResetWriteAccess = true;
  2478. }
  2479. ASSERT( GetCameraCount() > 0 );
  2480. C3DCamera * pCam = GetCamera( pView3D->GetCameraIndex() );
  2481. ASSERT_VALID( pCam );
  2482. m_pRoot->WalkTree(
  2483. C3DObject::EWTQ_TRANSFORM,
  2484. pCam,
  2485. pView3D,
  2486. NULL,
  2487. NULL
  2488. );
  2489. if( !wglMakeCurrent( pView3D->Get3DDC().GetSafeHdc(), pView3D->GetOpenGlContext() ) )
  2490. {
  2491. pView3D->OnGlAlertDisplay( _T("Failed to activate OpenGL rendering context") );
  2492. ASSERT( FALSE );
  2493. continue;
  2494. } // if( !wglMakeCurrent( pView3D->Get3DDC().GetSafeHdc(), pView3D->GetOpenGlContext() ) )
  2495. else
  2496. {
  2497. #ifdef _DEBUG
  2498. static int g_nRenderCounter = 0;
  2499. TRACE2( "    >>> 3D-PIPE: rendering %s images (counter=%d)n", (LPCTSTR)pView3D->m_strViewName, g_nRenderCounter );
  2500. g_nRenderCounter++;
  2501. #endif // _DEBUG
  2502. glShadeModel( GL_SMOOTH );
  2503. GL_VIEWS_CHECK_OPENGL_ERROR
  2504. glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
  2505. GL_VIEWS_CHECK_OPENGL_ERROR
  2506. glClearDepth( 1.0f );
  2507. GL_VIEWS_CHECK_OPENGL_ERROR
  2508. glEnable( GL_DEPTH_TEST );
  2509. GL_VIEWS_CHECK_OPENGL_ERROR
  2510. glDepthFunc( GL_LEQUAL );
  2511. GL_VIEWS_CHECK_OPENGL_ERROR
  2512. glDepthMask( GL_TRUE );
  2513. GL_VIEWS_CHECK_OPENGL_ERROR
  2514. glClearStencil( 0 );
  2515. GL_VIEWS_CHECK_OPENGL_ERROR
  2516. glEnable( GL_CULL_FACE );
  2517. GL_VIEWS_CHECK_OPENGL_ERROR
  2518. glCullFace( GL_FRONT );
  2519. GL_VIEWS_CHECK_OPENGL_ERROR
  2520. glFrontFace( GL_CW );
  2521. GL_VIEWS_CHECK_OPENGL_ERROR
  2522. glClear(
  2523. GL_COLOR_BUFFER_BIT
  2524. |GL_DEPTH_BUFFER_BIT
  2525. |GL_STENCIL_BUFFER_BIT
  2526. );
  2527. GL_VIEWS_CHECK_OPENGL_ERROR
  2528. glColorMask( 1, 1, 1, 1 );
  2529. GL_VIEWS_CHECK_OPENGL_ERROR
  2530. CSize _sizeView3D = pView3D->GetViewSize();
  2531. pCam->m_fAspect =
  2532. ((GLfloat)_sizeView3D.cx)
  2533. / ((GLfloat)_sizeView3D.cy)
  2534. ;
  2535. glViewport(
  2536. 0,
  2537. 0,
  2538. _sizeView3D.cx,
  2539. _sizeView3D.cy
  2540. );
  2541. GL_VIEWS_CHECK_OPENGL_ERROR
  2542. glMatrixMode( GL_PROJECTION );
  2543. GL_VIEWS_CHECK_OPENGL_ERROR
  2544. _mt mtxPerspective;
  2545. mtxPerspective.load_perspective(
  2546. pCam->GetFov(),
  2547. pCam->m_fAspect,
  2548. pCam->m_fNearPlane,
  2549. pCam->m_fFarPlane
  2550. );
  2551. glLoadMatrixf( mtxPerspective.arr );
  2552. GL_VIEWS_CHECK_OPENGL_ERROR
  2553. glMatrixMode( GL_MODELVIEW );
  2554. GL_VIEWS_CHECK_OPENGL_ERROR
  2555. _mt _mtxCameraInversion( pCam->m_mtxLastTransformation );
  2556. _mtxCameraInversion.load_inversion();
  2557. glLoadMatrixf(_mtxCameraInversion.arr);
  2558. GL_VIEWS_CHECK_OPENGL_ERROR
  2559. m_pRoot->WalkTree(
  2560. C3DObject::EWTQ_RENDER,
  2561. pCam,
  2562. pView3D,
  2563. NULL,
  2564. NULL
  2565. );
  2566. glFinish();
  2567. GL_VIEWS_CHECK_OPENGL_ERROR
  2568. if( !wglMakeCurrent( NULL, NULL ) )
  2569. {
  2570. pView3D->OnGlAlertDisplay( _T("Failed to release contexts") );
  2571. ASSERT( FALSE );
  2572. }
  2573. bSendMsgComplete = true;
  2574. } // else from if( !wglMakeCurrent( pView3D->Get3DDC().GetSafeHdc(), pView3D->GetOpenGlContext() ) )
  2575. } // if( pView3D->Get3DDC().GetSafeHdc() != NULL )
  2576. pView3D->Unlock();
  2577. if( bSendMsgComplete )
  2578. {
  2579. if( bResetWriteAccess )
  2580. {
  2581. ObjectWriteAccessSet( false );
  2582. bResetWriteAccess = false;
  2583. }
  2584. ::SendMessage(
  2585. pView3D->GetOutputHWND(),
  2586. GL_VIEWS_WM_RENDER_FRAME_COMPLETE,
  2587. 0L,
  2588. 0L
  2589. );
  2590. }
  2591. } // for( int nViewIdx = 0; nViewIdx < nViewCount; nViewIdx++ )
  2592. if( m_bTimerAnimationEnabled )
  2593. {
  2594. #ifdef _DEBUG
  2595. static int g_nRecalcPosCounter = 0;
  2596. TRACE1( "    >>> 3D-PIPE: recalculating object positions (counter=%d)n", g_nRecalcPosCounter );
  2597. g_nRecalcPosCounter++;
  2598. #endif // _DEBUG
  2599. if( !bResetWriteAccess )
  2600. {
  2601. ObjectWriteAccessSet( true );
  2602. bResetWriteAccess = true;
  2603. }
  2604. m_pRoot->WalkTree(
  2605. C3DObject::EWTQ_PLAY,
  2606. NULL,
  2607. NULL,
  2608. NULL,
  2609. NULL
  2610. );
  2611. } // if( m_bTimerAnimationEnabled )
  2612. if( bResetWriteAccess )
  2613. {
  2614. ObjectWriteAccessSet( false );
  2615. bResetWriteAccess = false;
  2616. }
  2617. } // for( ; true; )
  2618. ObjectWriteAccessSet( true );
  2619. m_pRoot->WalkTree(
  2620. C3DObject::EWTQ_THREAD_DONE,
  2621. NULL,
  2622. NULL,
  2623. NULL,
  2624. NULL
  2625. );
  2626. ObjectWriteAccessSet( false );
  2627. _ResourcesFree();
  2628. m_eventShutdownComplete.SetEvent();
  2629. return 0L;
  2630. }
  2631. /////////////////////////////////////////////////////////////////////////////
  2632. // CCameraSelectionComboBox
  2633. IMPLEMENT_DYNAMIC( CCameraSelectionComboBox, CExtComboBox )
  2634. CCameraSelectionComboBox::CCameraSelectionComboBox()
  2635. {
  2636. }
  2637. CCameraSelectionComboBox::~CCameraSelectionComboBox()
  2638. {
  2639. }
  2640. BEGIN_MESSAGE_MAP( CCameraSelectionComboBox, CExtComboBox )
  2641. //{{AFX_MSG_MAP(CCameraSelectionComboBox)
  2642. //}}AFX_MSG_MAP
  2643. ON_CONTROL_REFLECT(CBN_SELENDOK,OnReflectCbnSelEndOK)
  2644. END_MESSAGE_MAP()
  2645. void CCameraSelectionComboBox::SyncCameraWithSelectedItem(
  2646. bool bSetFocusToView // = false
  2647. )
  2648. {
  2649. ASSERT_VALID( this );
  2650. CWnd * pWnd = GetParent();
  2651. ASSERT_VALID( pWnd );
  2652. ASSERT_KINDOF( CExtToolControlBar, pWnd );
  2653. CChildView * pChildView = STATIC_DOWNCAST( CChildView, pWnd->GetParent() );
  2654. ASSERT_VALID( pChildView );
  2655. C3DView * pView3D = pChildView->m_wndGlPanel.GetView3D();
  2656. if( pView3D == NULL )
  2657. return;
  2658. ASSERT_VALID( pView3D );
  2659. int nCurSel = GetCurSel();
  2660. ASSERT( 0 <= nCurSel && nCurSel < GL_VIEWS_CAMERA_COUNT );
  2661. int nCamIdxOld = pView3D->GetCameraIndex();
  2662. ASSERT( 0 <= nCamIdxOld && nCamIdxOld < GL_VIEWS_CAMERA_COUNT );
  2663. if( nCamIdxOld != nCurSel )
  2664. {
  2665. pView3D->SetCameraIndex( nCurSel );
  2666. } // if( nCamIdxOld != nCurSel )
  2667. if( bSetFocusToView )
  2668. pChildView->SetFocus();
  2669. if( nCamIdxOld != nCurSel )
  2670. {
  2671. CFrameWnd * pFrame = GetParentFrame();
  2672. ASSERT_VALID( pFrame );
  2673. CMainFrame * pMainFrame =
  2674. DYNAMIC_DOWNCAST( CMainFrame, pFrame );
  2675. if( pMainFrame == NULL )
  2676. {
  2677. pMainFrame =
  2678. DYNAMIC_DOWNCAST( CMainFrame, pFrame->GetParentFrame() );
  2679. ASSERT_VALID( pMainFrame );
  2680. }
  2681. pMainFrame->SyncCameraFovValue();
  2682. } // if( nCamIdxOld != nCurSel )
  2683. the3DPipe.Render();
  2684. }
  2685. int CCameraSelectionComboBox::SetCurSel(
  2686. int nSelect,
  2687. bool bSetFocusToView // = false
  2688. )
  2689. {
  2690. ASSERT( 0 <= nSelect && nSelect < GL_VIEWS_CAMERA_COUNT );
  2691. int nRetVal = CExtComboBox::SetCurSel( nSelect );
  2692. SyncCameraWithSelectedItem( bSetFocusToView );
  2693. return nRetVal;
  2694. }
  2695. void CCameraSelectionComboBox::OnReflectCbnSelEndOK()
  2696. {
  2697. ASSERT_VALID( this );
  2698. bool bSetFocusToView = false;
  2699. HWND hWndFocus = ::GetFocus();
  2700. if( hWndFocus == m_hWnd )
  2701. bSetFocusToView = true;
  2702. SyncCameraWithSelectedItem( bSetFocusToView );
  2703. }
  2704. /////////////////////////////////////////////////////////////////////////////
  2705. // CCameraFovComboBox
  2706. IMPLEMENT_DYNAMIC( CCameraFovComboBox, CExtComboBox )
  2707. CCameraFovComboBox::CCameraFovComboBox()
  2708. {
  2709. }
  2710. CCameraFovComboBox::~CCameraFovComboBox()
  2711. {
  2712. }
  2713. BEGIN_MESSAGE_MAP( CCameraFovComboBox, CExtComboBox )
  2714. //{{AFX_MSG_MAP(CCameraFovComboBox)
  2715. //}}AFX_MSG_MAP
  2716. ON_CONTROL_REFLECT(CBN_SELENDOK,OnReflectCbnSelEndOK)
  2717. END_MESSAGE_MAP()
  2718. void CCameraFovComboBox::SyncCameraWithSelectedItem(
  2719. bool bSetFocusToView // = false
  2720. )
  2721. {
  2722. ASSERT_VALID( this );
  2723. CWnd * pWnd = GetParent();
  2724. ASSERT_VALID( pWnd );
  2725. ASSERT_KINDOF( CExtToolControlBar, pWnd );
  2726. CChildView * pChildView = STATIC_DOWNCAST( CChildView, pWnd->GetParent() );
  2727. ASSERT_VALID( pChildView );
  2728. C3DView * pView3D = pChildView->m_wndGlPanel.GetView3D();
  2729. if( pView3D == NULL )
  2730. return;
  2731. ASSERT_VALID( pView3D );
  2732. int nCamIdx = pView3D->GetCameraIndex();
  2733. ASSERT( 0 <= nCamIdx && nCamIdx < GL_VIEWS_CAMERA_COUNT );
  2734. C3DCamera * pCam = the3DPipe.GetCamera( nCamIdx );
  2735. ASSERT_VALID( pCam );
  2736. int nFovIdx = GetCurSel();
  2737. ASSERT( 0 <= nFovIdx && nFovIdx < GL_VIEWS_FOV_COUNT );
  2738. bool bRender = false;
  2739. the3DPipe.ObjectWriteAccessSet( true );
  2740. if( pCam->m_nFovIndex != nFovIdx ) 
  2741. {
  2742. pCam->m_nFovIndex = nFovIdx;
  2743. bRender = true;
  2744. }
  2745. the3DPipe.ObjectWriteAccessSet( false );
  2746. if( bSetFocusToView )
  2747. pChildView->SetFocus();
  2748. if( bRender )
  2749. {
  2750. CFrameWnd * pFrame = GetParentFrame();
  2751. ASSERT_VALID( pFrame );
  2752. CMainFrame * pMainFrame =
  2753. DYNAMIC_DOWNCAST( CMainFrame, pFrame );
  2754. if( pMainFrame == NULL )
  2755. {
  2756. pMainFrame =
  2757. DYNAMIC_DOWNCAST( CMainFrame, pFrame->GetParentFrame() );
  2758. ASSERT_VALID( pMainFrame );
  2759. }
  2760. pMainFrame->SyncCameraFovValue( nCamIdx, nFovIdx );
  2761. the3DPipe.Render();
  2762. }
  2763. }
  2764. int CCameraFovComboBox::SetCurSel(
  2765. int nSelect,
  2766. bool bSetFocusToView // = false
  2767. )
  2768. {
  2769. ASSERT( 0 <= nSelect && nSelect < GL_VIEWS_FOV_COUNT );
  2770. int nRetVal = CExtComboBox::SetCurSel( nSelect );
  2771. SyncCameraWithSelectedItem( bSetFocusToView );
  2772. return nRetVal;
  2773. }
  2774. void CCameraFovComboBox::OnReflectCbnSelEndOK()
  2775. {
  2776. ASSERT_VALID( this );
  2777. bool bSetFocusToView = false;
  2778. HWND hWndFocus = ::GetFocus();
  2779. if( hWndFocus == m_hWnd )
  2780. bSetFocusToView = true;
  2781. SyncCameraWithSelectedItem( bSetFocusToView );
  2782. }
  2783. /////////////////////////////////////////////////////////////////////////////
  2784. // CObjectHierarchyTreeCtrl
  2785. IMPLEMENT_DYNAMIC( CObjectHierarchyTreeCtrl, CTreeCtrl )
  2786. CObjectHierarchyTreeCtrl::CObjectHierarchyTreeCtrl()
  2787. : CExtNCSB < CTreeCtrl > ( true, true )
  2788. {
  2789. }
  2790. CObjectHierarchyTreeCtrl::~CObjectHierarchyTreeCtrl()
  2791. {
  2792. }
  2793. BEGIN_MESSAGE_MAP( CObjectHierarchyTreeCtrl, CTreeCtrl )
  2794. //{{AFX_MSG_MAP(CObjectHierarchyTreeCtrl)
  2795. ON_WM_LBUTTONDBLCLK()
  2796. //}}AFX_MSG_MAP
  2797. END_MESSAGE_MAP()
  2798. /////////////////////////////////////////////////////////////////////////////
  2799. // CObjectHierarchyTreeCtrl message handlers
  2800. void CObjectHierarchyTreeCtrl::OnLButtonDblClk(UINT nFlags, CPoint point) 
  2801. {
  2802. CExtNCSB < CTreeCtrl > :: OnLButtonDblClk( nFlags, point );
  2803. UINT htFlags = 0L;
  2804. HTREEITEM _hti = CExtNCSB < CTreeCtrl > :: HitTest( point, &htFlags );
  2805. if( _hti != NULL
  2806. && (htFlags&(TVHT_ONITEM)) != 0
  2807. )
  2808. {
  2809. C3DObject * pObj = (C3DObject *)
  2810. CExtNCSB < CTreeCtrl > :: GetItemData( _hti );
  2811. ASSERT( pObj != NULL );
  2812. ASSERT_VALID( pObj );
  2813. ASSERT_KINDOF( C3DObject, pObj );
  2814. pObj->OnTreeItemDblClick( this );
  2815. }
  2816. }
  2817. /////////////////////////////////////////////////////////////////////////////
  2818. // CChildView
  2819. IMPLEMENT_DYNAMIC( CChildView, CWnd )
  2820. GLfloat CChildView::g_fStepRotationAngle = 2.0f;
  2821. GLfloat CChildView::g_fStepWalkSize = 0.02f;
  2822. CChildView::CChildView(
  2823. UINT nIdResourceCursor
  2824. )
  2825. : m_wndGlPanel( nIdResourceCursor )
  2826. {
  2827. ASSERT( (ID_SELCAM9) == (ID_SELCAM8 + 1) );
  2828. ASSERT( (ID_SELCAM8) == (ID_SELCAM7 + 1) );
  2829. ASSERT( (ID_SELCAM7) == (ID_SELCAM6 + 1) );
  2830. ASSERT( (ID_SELCAM6) == (ID_SELCAM5 + 1) );
  2831. ASSERT( (ID_SELCAM5) == (ID_SELCAM4 + 1) );
  2832. ASSERT( (ID_SELCAM4) == (ID_SELCAM3 + 1) );
  2833. ASSERT( (ID_SELCAM3) == (ID_SELCAM2 + 1) );
  2834. ASSERT( (ID_SELCAM2) == (ID_SELCAM1 + 1) );
  2835. ASSERT( (ID_SELCAM1) == (ID_SELCAM0 + 1) );
  2836. }
  2837. CChildView::~CChildView()
  2838. {
  2839. }
  2840. BEGIN_MESSAGE_MAP( CChildView, CWnd )
  2841. //{{AFX_MSG_MAP(CChildView)
  2842. ON_WM_PAINT()
  2843. ON_WM_ERASEBKGND()
  2844. ON_WM_CREATE()
  2845. ON_WM_SIZE()
  2846. ON_COMMAND(ID_ROTATE_ABOUT_X0, OnRotateAboutX0)
  2847. ON_COMMAND(ID_ROTATE_ABOUT_X1, OnRotateAboutX1)
  2848. ON_COMMAND(ID_ROTATE_ABOUT_Y0, OnRotateAboutY0)
  2849. ON_COMMAND(ID_ROTATE_ABOUT_Y1, OnRotateAboutY1)
  2850. ON_COMMAND(ID_ROTATE_ABOUT_Z0, OnRotateAboutZ0)
  2851. ON_COMMAND(ID_ROTATE_ABOUT_Z1, OnRotateAboutZ1)
  2852. ON_COMMAND(ID_TRANSLATE_X0, OnTranslateX0)
  2853. ON_COMMAND(ID_TRANSLATE_X1, OnTranslateX1)
  2854. ON_COMMAND(ID_TRANSLATE_Y0, OnTranslateY0)
  2855. ON_COMMAND(ID_TRANSLATE_Y1, OnTranslateY1)
  2856. ON_COMMAND(ID_TRANSLATE_Z0, OnTranslateZ0)
  2857. ON_COMMAND(ID_TRANSLATE_Z1, OnTranslateZ1)
  2858. ON_WM_SETFOCUS()
  2859. ON_WM_CONTEXTMENU()
  2860. ON_UPDATE_COMMAND_UI(ID_BTN_MENU_ROTATION, OnUpdateEnabledBtnInBar)
  2861. ON_COMMAND(ID_CAM_FOV_INC, OnCamFovInc)
  2862. ON_UPDATE_COMMAND_UI(ID_CAM_FOV_INC, OnUpdateCamFovInc)
  2863. ON_COMMAND(ID_CAM_FOV_DEC, OnCamFovDec)
  2864. ON_UPDATE_COMMAND_UI(ID_CAM_FOV_DEC, OnUpdateCamFovDec)
  2865. //}}AFX_MSG_MAP
  2866. ON_COMMAND_RANGE( ID_SELCAM0, ID_SELCAM9, OnSelectCamera )
  2867. ON_UPDATE_COMMAND_UI_RANGE( ID_SELCAM0, ID_SELCAM9, OnUpdateSelectCamera )
  2868. ON_UPDATE_COMMAND_UI( ID_CAMERA_SELECTION_COMBO, OnUpdateEnabledBtnInBar )
  2869. ON_UPDATE_COMMAND_UI( ID_CAMERA_FOV_COMBO, OnUpdateEnabledBtnInBar )
  2870. ON_UPDATE_COMMAND_UI( ID_BTN_MENU_ROTATION, OnUpdateEnabledBtnInBar )
  2871. ON_UPDATE_COMMAND_UI( ID_BTN_MENU_TRANSLATION, OnUpdateEnabledBtnInBar )
  2872. ON_REGISTERED_MESSAGE(
  2873. CExtPopupMenuWnd::g_nMsgPrepareMenu,
  2874. OnExtMenuPrepare
  2875. )
  2876. END_MESSAGE_MAP()
  2877. /////////////////////////////////////////////////////////////////////////////
  2878. // CChildView message handlers
  2879. LRESULT CChildView::OnExtMenuPrepare(WPARAM wParam, LPARAM lParam)
  2880. {
  2881. lParam;
  2882. CExtPopupMenuWnd::MsgPrepareMenuData_t * pData =
  2883. reinterpret_cast
  2884. < CExtPopupMenuWnd::MsgPrepareMenuData_t * >
  2885. ( wParam );
  2886. ASSERT( pData != NULL );
  2887. CExtPopupMenuWnd * pPopup = pData->m_pPopup;
  2888. ASSERT( pPopup != NULL );
  2889. // remove camera selection combo command
  2890. INT nPos = pPopup->ItemFindPosForCmdID(ID_CAMERA_SELECTION_COMBO);
  2891. if( nPos >= 0 )
  2892. pPopup->ItemRemove( nPos );
  2893. if( pPopup->ItemGetCount() > 0
  2894. && pPopup->ItemGetInfo(0).IsSeparator()
  2895. )
  2896. pPopup->ItemRemove( 0 );
  2897. // replace camera FOV combo command
  2898. nPos = pPopup->ItemFindPosForCmdID(ID_CAMERA_FOV_COMBO);
  2899. if( nPos >= 0 )
  2900. {
  2901. pPopup->ItemRemove( nPos );
  2902. if( pPopup->ItemInsert(
  2903. (UINT)CExtPopupMenuWnd::TYPE_POPUP,
  2904. nPos,
  2905. _T("Camera FOV"),
  2906. NULL,
  2907. m_hWnd
  2908. )
  2909. )
  2910. {
  2911. CExtPopupMenuWnd * pSubMenu =
  2912. pPopup->ItemGetPopup( nPos );
  2913. ASSERT_VALID( pSubMenu );
  2914. VERIFY(
  2915. pSubMenu->ItemInsert(
  2916. ID_CAM_FOV_INC,
  2917. -1,
  2918. NULL,
  2919. NULL,
  2920. m_hWnd
  2921. )
  2922. );
  2923. VERIFY(
  2924. pSubMenu->ItemInsert(
  2925. ID_CAM_FOV_DEC,
  2926. -1,
  2927. NULL,
  2928. NULL,
  2929. m_hWnd
  2930. )
  2931. );
  2932. UpdateDialogControls( this, TRUE );
  2933. }
  2934. #ifdef _DEBUG
  2935. else
  2936. {
  2937. ASSERT( FALSE );
  2938. }
  2939. #endif // _DEBUG
  2940. }
  2941. // remove leading separator if exist
  2942. if( pPopup->ItemGetCount() > 0
  2943. && pPopup->ItemGetInfo(0).IsSeparator()
  2944. )
  2945. pPopup->ItemRemove( 0 );
  2946. return TRUE;
  2947. }
  2948. BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs) 
  2949. {
  2950. if( ! (CExtWRB < CWnd > ::PreCreateWindow(cs) ) )
  2951. return FALSE;
  2952. cs.dwExStyle &= ~(WS_EX_STATICEDGE|WS_EX_CLIENTEDGE);
  2953. cs.style &= ~WS_BORDER;
  2954. cs.style |= WS_CLIPSIBLINGS;
  2955. cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, 
  2956. ::LoadCursor(NULL, IDC_ARROW), HBRUSH(COLOR_WINDOW+1), NULL);
  2957. return TRUE;
  2958. }
  2959. void CChildView::OnPaint() 
  2960. {
  2961. CPaintDC dcPaint( this );
  2962. CExtPaintManager::stat_ExcludeChildAreas(
  2963. dcPaint.GetSafeHdc(),
  2964. GetSafeHwnd()
  2965. );
  2966. }
  2967. BOOL CChildView::OnEraseBkgnd(CDC* pDC) 
  2968. {
  2969. pDC;
  2970. return TRUE;
  2971. }
  2972. int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  2973. {
  2974. if( CExtWRB < CWnd >::OnCreate(lpCreateStruct) == -1 )
  2975. {
  2976. ASSERT( FALSE );
  2977. return -1;
  2978. }
  2979. m_wndToolbar.m_bPresubclassDialogMode = true;
  2980. if( !m_wndToolbar.Create(
  2981. _T(""),
  2982. this,
  2983. AFX_IDW_DIALOGBAR,
  2984. WS_CHILD|WS_VISIBLE
  2985. |CBRS_ALIGN_TOP|CBRS_TOOLTIPS
  2986. |CBRS_FLYBY|CBRS_SIZE_DYNAMIC
  2987. )
  2988. )
  2989. {
  2990. ASSERT( FALSE );
  2991. return -1;
  2992. }
  2993. if( !m_wndToolbar.LoadToolBar(IDR_TOOLBAR_INVIEW) )
  2994. {
  2995. ASSERT( FALSE );
  2996. return -1;
  2997. }
  2998. if( !m_wndToolbar.InitNavigationBar() )
  2999. return -1;
  3000. if( !m_wndGlPanel.Create(
  3001. this,
  3002. GL_VIEWS_ID_VIEW_DLG_CTRL_ID
  3003. )
  3004. )
  3005. {
  3006. ASSERT( FALSE );
  3007. return -1;
  3008. }
  3009. m_wndGlPanel.SetFont( CFont::FromHandle((HFONT)::GetStockObject(DEFAULT_GUI_FONT)) );
  3010. CWnd::RepositionBars( 0, 0xFFFF, GL_VIEWS_ID_VIEW_DLG_CTRL_ID );
  3011. return 0;
  3012. }
  3013. void CChildView::OnSize(UINT nType, int cx, int cy) 
  3014. {
  3015. CExtWRB < CWnd > ::OnSize(nType, cx, cy);
  3016. if( nType != SIZE_MINIMIZED )
  3017. CWnd::RepositionBars( 0, 0xFFFF, GL_VIEWS_ID_VIEW_DLG_CTRL_ID );
  3018. }
  3019. void CChildView::OnUpdateEnabledBtnInBar(CCmdUI* pCmdUI) 
  3020. {
  3021. ASSERT( pCmdUI != NULL );
  3022. pCmdUI->Enable();
  3023. }
  3024. void CChildView::OnSetFocus(CWnd* pOldWnd) 
  3025. {
  3026. CWnd ::OnSetFocus(pOldWnd);
  3027. m_wndGlPanel.SetFocus();
  3028. }
  3029. void CChildView::OnContextMenu(CWnd* pWnd, CPoint point) 
  3030. {
  3031. pWnd;
  3032. point;
  3033. }
  3034. void CChildView::OnRotateAboutX0() 
  3035. {
  3036. ASSERT_VALID( this );
  3037. C3DView * pView3D = m_wndGlPanel.GetView3D();
  3038. if( pView3D == NULL )
  3039. return;
  3040. ASSERT_VALID( pView3D );
  3041. pView3D->DoLookUp( g_fStepRotationAngle );
  3042. the3DPipe.Render();
  3043. }
  3044. void CChildView::OnRotateAboutX1() 
  3045. {
  3046. ASSERT_VALID( this );
  3047. C3DView * pView3D = m_wndGlPanel.GetView3D();
  3048. if( pView3D == NULL )
  3049. return;
  3050. ASSERT_VALID( pView3D );
  3051. pView3D->DoLookUp( -g_fStepRotationAngle );
  3052. the3DPipe.Render();
  3053. }
  3054. void CChildView::OnRotateAboutY0() 
  3055. {
  3056. ASSERT_VALID( this );
  3057. C3DView * pView3D = m_wndGlPanel.GetView3D();
  3058. if( pView3D == NULL )
  3059. return;
  3060. ASSERT_VALID( pView3D );
  3061. pView3D->DoLookLeft( g_fStepRotationAngle );
  3062. the3DPipe.Render();
  3063. }
  3064. void CChildView::OnRotateAboutY1() 
  3065. {
  3066. ASSERT_VALID( this );
  3067. C3DView * pView3D = m_wndGlPanel.GetView3D();
  3068. if( pView3D == NULL )
  3069. return;
  3070. ASSERT_VALID( pView3D );
  3071. pView3D->DoLookLeft( -g_fStepRotationAngle );
  3072. the3DPipe.Render();
  3073. }
  3074. void CChildView::OnRotateAboutZ0() 
  3075. {
  3076. ASSERT_VALID( this );
  3077. C3DView * pView3D = m_wndGlPanel.GetView3D();
  3078. if( pView3D == NULL )
  3079. return;
  3080. ASSERT_VALID( pView3D );
  3081. pView3D->DoLookOwnAxis( g_fStepRotationAngle );
  3082. the3DPipe.Render();
  3083. }
  3084. void CChildView::OnRotateAboutZ1() 
  3085. {
  3086. ASSERT_VALID( this );
  3087. C3DView * pView3D = m_wndGlPanel.GetView3D();
  3088. if( pView3D == NULL )
  3089. return;
  3090. ASSERT_VALID( pView3D );
  3091. pView3D->DoLookOwnAxis( -g_fStepRotationAngle );
  3092. the3DPipe.Render();
  3093. }
  3094. void CChildView::OnTranslateX0() 
  3095. {
  3096. ASSERT_VALID( this );
  3097. C3DView * pView3D = m_wndGlPanel.GetView3D();
  3098. if( pView3D == NULL )
  3099. return;
  3100. ASSERT_VALID( pView3D );
  3101. pView3D->DoStepLeft( g_fStepWalkSize );
  3102. the3DPipe.Render();
  3103. }
  3104. void CChildView::OnTranslateX1() 
  3105. {
  3106. ASSERT_VALID( this );
  3107. C3DView * pView3D = m_wndGlPanel.GetView3D();
  3108. if( pView3D == NULL )
  3109. return;
  3110. ASSERT_VALID( pView3D );
  3111. pView3D->DoStepLeft( -g_fStepWalkSize );
  3112. the3DPipe.Render();
  3113. }
  3114. void CChildView::OnTranslateY0() 
  3115. {
  3116. ASSERT_VALID( this );
  3117. C3DView * pView3D = m_wndGlPanel.GetView3D();
  3118. if( pView3D == NULL )
  3119. return;
  3120. ASSERT_VALID( pView3D );
  3121. pView3D->DoStepUp( g_fStepWalkSize );
  3122. the3DPipe.Render();
  3123. }
  3124. void CChildView::OnTranslateY1() 
  3125. {
  3126. ASSERT_VALID( this );
  3127. C3DView * pView3D = m_wndGlPanel.GetView3D();
  3128. if( pView3D == NULL )
  3129. return;
  3130. ASSERT_VALID( pView3D );
  3131. pView3D->DoStepUp( -g_fStepWalkSize );
  3132. the3DPipe.Render();
  3133. }
  3134. void CChildView::OnTranslateZ0() 
  3135. {
  3136. ASSERT_VALID( this );
  3137. C3DView * pView3D = m_wndGlPanel.GetView3D();
  3138. if( pView3D == NULL )
  3139. return;
  3140. ASSERT_VALID( pView3D );
  3141. pView3D->DoStepForward( g_fStepWalkSize );
  3142. the3DPipe.Render();
  3143. }
  3144. void CChildView::OnTranslateZ1() 
  3145. {
  3146. ASSERT_VALID( this );
  3147. C3DView * pView3D = m_wndGlPanel.GetView3D();
  3148. if( pView3D == NULL )
  3149. return;
  3150. ASSERT_VALID( pView3D );
  3151. pView3D->DoStepForward( -g_fStepWalkSize );
  3152. the3DPipe.Render();
  3153. }
  3154. void CChildView::OnSelectCamera( UINT nCmdID )
  3155. {
  3156. ASSERT_VALID( this );
  3157. ASSERT( ID_SELCAM0 <= nCmdID && nCmdID <= ID_SELCAM9 );
  3158. int nCameraIndex = nCmdID - ID_SELCAM0;
  3159. ASSERT( 0 <= nCameraIndex && nCameraIndex < GL_VIEWS_CAMERA_COUNT );
  3160. m_wndToolbar.m_wndCameraSelCombo.SetCurSel( nCameraIndex );
  3161. }
  3162. void CChildView::OnUpdateSelectCamera(CCmdUI* pCmdUI)
  3163. {
  3164. ASSERT_VALID( this );
  3165. ASSERT( pCmdUI != NULL );
  3166. ASSERT( ID_SELCAM0 <= pCmdUI->m_nID && pCmdUI->m_nID <= ID_SELCAM9 );
  3167. int nCameraIndexReal = m_wndToolbar.m_wndCameraSelCombo.GetCurSel();
  3168. if( nCameraIndexReal < 0 )
  3169. {
  3170. pCmdUI->Enable( FALSE );
  3171. return;
  3172. }
  3173. ASSERT( 0 <= nCameraIndexReal && nCameraIndexReal < GL_VIEWS_CAMERA_COUNT );
  3174. int nCameraIndexToCmp = pCmdUI->m_nID - ID_SELCAM0;
  3175. ASSERT( 0 <= nCameraIndexToCmp && nCameraIndexToCmp < GL_VIEWS_CAMERA_COUNT );
  3176. pCmdUI->Enable( TRUE );
  3177. pCmdUI->SetRadio(
  3178. (nCameraIndexReal == nCameraIndexToCmp)
  3179. ? TRUE
  3180. : FALSE
  3181. );
  3182. }
  3183. void CChildView::OnCamFovInc() 
  3184. {
  3185. ASSERT_VALID( this );
  3186. int nCameraIndexReal = m_wndToolbar.m_wndCameraSelCombo.GetCurSel();
  3187. ASSERT(
  3188. ( 0 <= nCameraIndexReal && nCameraIndexReal < GL_VIEWS_CAMERA_COUNT )
  3189. || nCameraIndexReal < 0
  3190. );
  3191. if( nCameraIndexReal < 0 )
  3192. return;
  3193. C3DCamera * pCam = the3DPipe.GetCamera( nCameraIndexReal );
  3194. ASSERT_VALID( pCam );
  3195. int nFovIdx = pCam->m_nFovIndex;
  3196. ASSERT( 0 <= nFovIdx && nFovIdx < GL_VIEWS_FOV_COUNT );
  3197. if( nFovIdx == (GL_VIEWS_FOV_COUNT-1) )
  3198. return;
  3199. m_wndToolbar.m_wndCameraFovCombo.SetCurSel( nFovIdx+1, false );
  3200. }
  3201. void CChildView::OnUpdateCamFovInc(CCmdUI* pCmdUI) 
  3202. {
  3203. ASSERT_VALID( this );
  3204. ASSERT( pCmdUI != NULL );
  3205. int nCameraIndexReal = m_wndToolbar.m_wndCameraSelCombo.GetCurSel();
  3206. ASSERT(
  3207. ( 0 <= nCameraIndexReal && nCameraIndexReal < GL_VIEWS_CAMERA_COUNT )
  3208. || nCameraIndexReal < 0
  3209. );
  3210. if( nCameraIndexReal < 0 )
  3211. {
  3212. pCmdUI->Enable( FALSE );
  3213. return;
  3214. }
  3215. C3DCamera * pCam = the3DPipe.GetCamera( nCameraIndexReal );
  3216. ASSERT_VALID( pCam );
  3217. int nFovIdx = pCam->m_nFovIndex;
  3218. ASSERT( 0 <= nFovIdx && nFovIdx < GL_VIEWS_FOV_COUNT );
  3219. pCmdUI->Enable(
  3220. (nFovIdx < (GL_VIEWS_FOV_COUNT-1)) ? TRUE : FALSE
  3221. );
  3222. }
  3223. void CChildView::OnCamFovDec() 
  3224. {
  3225. ASSERT_VALID( this );
  3226. int nCameraIndexReal = m_wndToolbar.m_wndCameraSelCombo.GetCurSel();
  3227. ASSERT(
  3228. ( 0 <= nCameraIndexReal && nCameraIndexReal < GL_VIEWS_CAMERA_COUNT )
  3229. || nCameraIndexReal < 0
  3230. );
  3231. if( nCameraIndexReal < 0 )
  3232. return;
  3233. C3DCamera * pCam = the3DPipe.GetCamera( nCameraIndexReal );
  3234. ASSERT_VALID( pCam );
  3235. int nFovIdx = pCam->m_nFovIndex;
  3236. ASSERT( 0 <= nFovIdx && nFovIdx < GL_VIEWS_FOV_COUNT );
  3237. if( nFovIdx == 0 )
  3238. return;
  3239. m_wndToolbar.m_wndCameraFovCombo.SetCurSel( nFovIdx-1, false );
  3240. }
  3241. void CChildView::OnUpdateCamFovDec(CCmdUI* pCmdUI) 
  3242. {
  3243. ASSERT_VALID( this );
  3244. ASSERT( pCmdUI != NULL );
  3245. int nCameraIndexReal = m_wndToolbar.m_wndCameraSelCombo.GetCurSel();
  3246. ASSERT(
  3247. ( 0 <= nCameraIndexReal && nCameraIndexReal < GL_VIEWS_CAMERA_COUNT )
  3248. || nCameraIndexReal < 0
  3249. );
  3250. if( nCameraIndexReal < 0 )
  3251. {
  3252. pCmdUI->Enable( FALSE );
  3253. return;
  3254. }
  3255. C3DCamera * pCam = the3DPipe.GetCamera( nCameraIndexReal );
  3256. ASSERT_VALID( pCam );
  3257. int nFovIdx = pCam->m_nFovIndex;
  3258. ASSERT( 0 <= nFovIdx && nFovIdx < GL_VIEWS_FOV_COUNT );
  3259. pCmdUI->Enable(
  3260. (nFovIdx > 0) ? TRUE : FALSE
  3261. );
  3262. }