3DHelperDemoDlg.cpp
上传用户:qzpk666
上传日期:2022-08-04
资源大小:59k
文件大小:9k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // 3DHelperDemoDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "3DHelperDemo.h"
  5. #include "3DHelperDemoDlg.h"
  6. #include "MemDC.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. #define _USE_NET_DISPLAY_
  13. //#undef _USE_NET_DISPLAY_
  14. const int ID_TIMER_REDRAW = 1;
  15. const UINT TIMER_REDRAW_INTERVAL = 25;
  16. #ifndef RAD
  17. #define RAD(x) ((x)*3.14159265f/180.0f)
  18. #endif
  19. /////////////////////////////////////////////////////////////////////////////
  20. // CAboutDlg dialog used for App About
  21. class CAboutDlg : public CDialog
  22. {
  23. public:
  24. CAboutDlg();
  25. // Dialog Data
  26. //{{AFX_DATA(CAboutDlg)
  27. enum { IDD = IDD_ABOUTBOX };
  28. //}}AFX_DATA
  29. // ClassWizard generated virtual function overrides
  30. //{{AFX_VIRTUAL(CAboutDlg)
  31. protected:
  32. virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  33. //}}AFX_VIRTUAL
  34. // Implementation
  35. protected:
  36. //{{AFX_MSG(CAboutDlg)
  37. //}}AFX_MSG
  38. DECLARE_MESSAGE_MAP()
  39. };
  40. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  41. {
  42. //{{AFX_DATA_INIT(CAboutDlg)
  43. //}}AFX_DATA_INIT
  44. }
  45. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  46. {
  47. CDialog::DoDataExchange(pDX);
  48. //{{AFX_DATA_MAP(CAboutDlg)
  49. //}}AFX_DATA_MAP
  50. }
  51. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  52. //{{AFX_MSG_MAP(CAboutDlg)
  53. // No message handlers
  54. //}}AFX_MSG_MAP
  55. END_MESSAGE_MAP()
  56. /////////////////////////////////////////////////////////////////////////////
  57. // CMy3DHelperDemoDlg dialog
  58. CMy3DHelperDemoDlg::CMy3DHelperDemoDlg(CWnd* pParent /*=NULL*/)
  59. : CDialog(CMy3DHelperDemoDlg::IDD, pParent)
  60. {
  61. //{{AFX_DATA_INIT(CMy3DHelperDemoDlg)
  62. //}}AFX_DATA_INIT
  63. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  64. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  65. m_pVectorData = NULL;
  66. }
  67. void CMy3DHelperDemoDlg::DoDataExchange(CDataExchange* pDX)
  68. {
  69. CDialog::DoDataExchange(pDX);
  70. //{{AFX_DATA_MAP(CMy3DHelperDemoDlg)
  71. DDX_Control(pDX, IDC_CHECK_COORD_AXES, m_ctrlAxes);
  72. DDX_Control(pDX, IDC_CHECK_COORDS, m_ctrlCoordinates);
  73. DDX_Control(pDX, IDC_CHECK_VISIBILITY_CUBE, m_ctrlVisibilityCube);
  74. //}}AFX_DATA_MAP
  75. }
  76. BEGIN_MESSAGE_MAP(CMy3DHelperDemoDlg, CDialog)
  77. //{{AFX_MSG_MAP(CMy3DHelperDemoDlg)
  78. ON_WM_SYSCOMMAND()
  79. ON_WM_PAINT()
  80. ON_WM_QUERYDRAGICON()
  81. ON_WM_TIMER()
  82. ON_BN_CLICKED(IDC_CHECK_VISIBILITY_CUBE, OnCheckVisibilityCube)
  83. //}}AFX_MSG_MAP
  84. END_MESSAGE_MAP()
  85. /////////////////////////////////////////////////////////////////////////////
  86. // CMy3DHelperDemoDlg message handlers
  87. BOOL CMy3DHelperDemoDlg::OnInitDialog()
  88. {
  89. CDialog::OnInitDialog();
  90. // Add "About..." menu item to system menu.
  91. // IDM_ABOUTBOX must be in the system command range.
  92. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  93. ASSERT(IDM_ABOUTBOX < 0xF000);
  94. CMenu* pSysMenu = GetSystemMenu(FALSE);
  95. if (pSysMenu != NULL)
  96. {
  97. CString strAboutMenu;
  98. strAboutMenu.LoadString(IDS_ABOUTBOX);
  99. if (!strAboutMenu.IsEmpty())
  100. {
  101. pSysMenu->AppendMenu(MF_SEPARATOR);
  102. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  103. }
  104. }
  105. // Set the icon for this dialog.  The framework does this automatically
  106. //  when the application's main window is not a dialog
  107. SetIcon(m_hIcon, TRUE); // Set big icon
  108. SetIcon(m_hIcon, FALSE); // Set small icon
  109. // TODO: Add extra initialization here
  110. m_ctrlVisibilityCube.SetCheck(0);
  111. m_ctrlCoordinates.EnableWindow(FALSE);
  112. m_ctrlAxes.EnableWindow(FALSE);
  113. initialize();
  114. return TRUE;  // return TRUE  unless you set the focus to a control
  115. }
  116. void CMy3DHelperDemoDlg::OnSysCommand(UINT nID, LPARAM lParam)
  117. {
  118. if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  119. {
  120. CAboutDlg dlgAbout;
  121. dlgAbout.DoModal();
  122. }
  123. else
  124. {
  125. CDialog::OnSysCommand(nID, lParam);
  126. }
  127. }
  128. // If you add a minimize button to your dialog, you will need the code below
  129. //  to draw the icon.  For MFC applications using the document/view model,
  130. //  this is automatically done for you by the framework.
  131. void CMy3DHelperDemoDlg::OnPaint() 
  132. {
  133. if (IsIconic())
  134. {
  135. CPaintDC dc(this); // device context for painting
  136. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  137. // Center icon in client rectangle
  138. int cxIcon = GetSystemMetrics(SM_CXICON);
  139. int cyIcon = GetSystemMetrics(SM_CYICON);
  140. CRect rect;
  141. GetClientRect(&rect);
  142. int x = (rect.Width() - cxIcon + 1) / 2;
  143. int y = (rect.Height() - cyIcon + 1) / 2;
  144. // Draw the icon
  145. dc.DrawIcon(x, y, m_hIcon);
  146. }
  147. else
  148. {
  149. CDialog::OnPaint();
  150. }
  151. }
  152. // The system calls this to obtain the cursor to display while the user drags
  153. //  the minimized window.
  154. HCURSOR CMy3DHelperDemoDlg::OnQueryDragIcon()
  155. {
  156. return (HCURSOR) m_hIcon;
  157. }
  158. void CMy3DHelperDemoDlg::OnTimer(UINT nIDEvent) 
  159. {
  160. // TODO: Add your message handler code here and/or call default
  161. if(nIDEvent == ID_TIMER_REDRAW) {
  162. KillTimer(nIDEvent);
  163. CWnd *pTarget = GetDlgItem(IDC_STATIC_PLACEHOLDER);
  164. if(pTarget==NULL) {
  165. return;
  166. }
  167. m_c3DHelper.UpdateTrackBall(pTarget->GetDC());
  168. redraw();
  169. SetTimer(ID_TIMER_REDRAW, TIMER_REDRAW_INTERVAL, NULL);
  170. }
  171. CDialog::OnTimer(nIDEvent);
  172. }
  173. void CMy3DHelperDemoDlg::redraw()
  174. {
  175. // Create off-screen dc (prevents flickering)
  176. CWnd *pTarget = GetDlgItem(IDC_STATIC_PLACEHOLDER);
  177. if(pTarget==NULL) {
  178. return;
  179. }
  180. CRect rcDraw;
  181. pTarget->GetClientRect(rcDraw);
  182. // Create the offscreen dc
  183. CDC *pTDC = pTarget->GetDC();
  184. if(pTDC==NULL) {
  185. return;
  186. }
  187. CMemDC cDC(pTDC, &rcDraw);
  188. CDC *pDC = (CDC*)cDC;
  189. // Clean up the screen an draw a hint
  190. pDC->FillSolidRect(rcDraw.left, rcDraw.top, rcDraw.Width(),rcDraw.Height(), RGB(0,0,0));
  191. pDC->SetTextColor(RGB(255,255,0));
  192. pDC->SetBkMode(OPAQUE);
  193. pDC->TextOut(1,1, _T("Drag mouse to rotate..."));
  194. // Macros easing the access to data
  195. #define ID(xx,yy) (((yy)*m_iXSize)+(xx))
  196. #define V(xx,yy) m_pVectorData[ID(xx,yy)]
  197. #define Vx(xx,yy) V(xx,yy).x
  198. #define Vy(xx,yy) V(xx,yy).y
  199. #define Vxy(xx,yy) Vx(xx,yy),Vy(xx,yy)
  200. int x,y;
  201. float fWaves = 3.0f;
  202. float xFact = fWaves/(float)m_iXSize*100.0f;
  203. float yFact = fWaves/(float)m_iYSize*100.0f;
  204. for(y=0; y<m_iYSize;y++) {
  205. for(x=0; x<m_iXSize;x++) {
  206. // Data *should be* in range of (-1,-1,-1 / 1,1,1) - looks prettier! 
  207. V(x,y).s3D.x = -1.0f+2.0f*((float)x/(float)m_iXSize);
  208. V(x,y).s3D.y = -1.0f+2.0f*((float)y/(float)m_iYSize);
  209. // Draw a *pretty* curve
  210. V(x,y).s3D.z = (cosf(RAD(((m_iCurrAngle+y)%360)*yFact))+sinf(RAD(((m_iCurrAngle+x)%360)*xFact)))/2.0f;
  211. }
  212. }
  213. m_iCurrAngle ++;
  214. m_iCurrAngle= m_iCurrAngle%360;
  215. BYTE col = 0;
  216. // Step 1: Calculate 2D coordinates
  217. NeHe::Vector cIn, cOut;
  218. for(y=0; y<m_iYSize;y++) {
  219. for(x=0; x<m_iXSize;x++) {
  220. cIn.x = V(x,y).s3D.x;
  221. cIn.y = V(x,y).s3D.y;
  222. cIn.z = V(x,y).s3D.z;
  223. cOut = m_c3DHelper.RenderPoint(cIn);
  224. V(x,y).x = (int)cOut.x;
  225. V(x,y).y = (int)cOut.y;
  226. #ifndef _USE_NET_DISPLAY_
  227. //col = (BYTE)(((float)255.0f/(float)m_iYSize)*(float)y);
  228. col = 255;
  229. pDC->SetPixelV((int)cOut.x, (int)cOut.y, RGB(col,col,col));
  230. #endif
  231. }
  232. }
  233. // More complex / maybe slower: Draw a 3D grid/net
  234. #ifdef _USE_NET_DISPLAY_
  235. // Step 2: Draw "3D-net"
  236. CPen cPen;
  237. cPen.CreatePen(PS_SOLID,1,RGB(128,128,128));
  238. CPen *pOld = pDC->SelectObject(&cPen);
  239. for(y=0; y<m_iYSize-1;y++) {
  240. for(x=0; x<m_iXSize-1;x++) {
  241. pDC->MoveTo(Vxy(x  ,y  ));
  242. pDC->LineTo(Vxy(x+1,y  ));
  243. pDC->MoveTo(Vxy(x  ,y  ));
  244. pDC->LineTo(Vxy(x  ,y+1));
  245. //pDC->MoveTo(Vxy(x  ,y  ));
  246. //pDC->LineTo(Vxy(x+1,y+1));
  247. }
  248. }
  249. // Draw final frame line
  250. pDC->MoveTo(Vxy(0,m_iYSize-1));
  251. for(x=0; x<m_iXSize;x++) {
  252. pDC->LineTo(Vxy(x,m_iYSize-1));
  253. }
  254. pDC->MoveTo(Vxy(m_iXSize-1,0));
  255. for(y=0; y<m_iYSize;y++) {
  256. pDC->LineTo(Vxy(m_iXSize-1,y));
  257. }
  258. pDC->SelectObject(pOld);
  259. #endif //_USE_NET_DISPLAY_
  260. BOOL bCubeEnabled = (1==m_ctrlVisibilityCube.GetCheck());
  261. BOOL bCoords = (1 == m_ctrlCoordinates.GetCheck());
  262. BOOL bAxes = (1 == m_ctrlAxes.GetCheck());
  263. if(bCubeEnabled==TRUE) {
  264. m_c3DHelper.DrawVisibilityCube(pDC, bAxes , bCoords);
  265. }
  266. // cDC will be automatically destruced 
  267. #undef V
  268. #undef Vx
  269. #undef Vy
  270. #undef Vxy
  271. }
  272. void CMy3DHelperDemoDlg::initialize()
  273. {
  274. #ifdef _USE_NET_DISPLAY_
  275. m_iXSize = 50;
  276. m_iYSize = 50;
  277. #else
  278. m_iXSize = 70;
  279. m_iYSize = 70;
  280. #endif
  281. if(m_pVectorData!=NULL) {
  282. delete m_pVectorData;
  283. }
  284. // Allocate memory needed for 100x100 vectors
  285. m_pVectorData = new DATA3D[m_iXSize*m_iYSize];
  286. ZeroMemory((void*)m_pVectorData, m_iXSize*m_iXSize*sizeof(DATA3D));
  287. CWnd *pTarget = GetDlgItem(IDC_STATIC_PLACEHOLDER);
  288. if(pTarget==NULL) {
  289. return;
  290. }
  291. m_c3DHelper.Initialize(pTarget->GetDC(), NeHe::Vector(-1.0f, -1.0f, -1.0f), NeHe::Vector(1.0f,1.0f,1.0f), TRUE);
  292. m_c3DHelper.Rotate(45.0f, 10.0f, 0.0f, TRUE);
  293. SetTimer(ID_TIMER_REDRAW, TIMER_REDRAW_INTERVAL, NULL);
  294. }
  295. void CMy3DHelperDemoDlg::OnOK() 
  296. {
  297. // TODO: Add extra validation here
  298. cleanup();
  299. CDialog::OnOK();
  300. }
  301. void CMy3DHelperDemoDlg::OnCancel() 
  302. {
  303. // TODO: Add extra cleanup here
  304. cleanup();
  305. CDialog::OnCancel();
  306. }
  307. void CMy3DHelperDemoDlg::cleanup()
  308. {
  309. try {
  310. if(m_pVectorData!=NULL) {
  311. delete m_pVectorData;
  312. m_pVectorData = NULL;
  313. }
  314. } catch(...) {
  315. return;
  316. }
  317. }
  318. void CMy3DHelperDemoDlg::OnCheckVisibilityCube() 
  319. {
  320. // TODO: Add your control notification handler code here
  321. BOOL bEnabled = (1==m_ctrlVisibilityCube.GetCheck());
  322. m_ctrlCoordinates.EnableWindow(bEnabled);
  323. m_ctrlAxes.EnableWindow(bEnabled);
  324. }