DialogGLDlg.cpp
上传用户:tengyuc
上传日期:2007-08-14
资源大小:722k
文件大小:12k
源码类别:

OpenGL

开发平台:

Visual C++

  1. // DialogGLDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "DialogGL.h"
  5. #include "DialogGLDlg.h"
  6. #include "math.h"
  7. #include "mmsystem.h"
  8. #include "resource.h"
  9. #ifdef _DEBUG
  10. #define new DEBUG_NEW
  11. #undef THIS_FILE
  12. static char THIS_FILE[] = __FILE__;
  13. #endif
  14. /////////////////////////////////////////////////////////////////////////////
  15. // CAboutDlg dialog used for App About
  16. class CAboutDlg : public CDialog
  17. {
  18. public:
  19. CAboutDlg();
  20. // Dialog Data
  21. //{{AFX_DATA(CAboutDlg)
  22. enum { IDD = IDD_ABOUTBOX };
  23. //}}AFX_DATA
  24. // ClassWizard generated virtual function overrides
  25. //{{AFX_VIRTUAL(CAboutDlg)
  26. protected:
  27. virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  28. //}}AFX_VIRTUAL
  29. // Implementation
  30. protected:
  31. //{{AFX_MSG(CAboutDlg)
  32. //}}AFX_MSG
  33. DECLARE_MESSAGE_MAP()
  34. };
  35. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  36. {
  37. //{{AFX_DATA_INIT(CAboutDlg)
  38. //}}AFX_DATA_INIT
  39. }
  40. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  41. {
  42. CDialog::DoDataExchange(pDX);
  43. //{{AFX_DATA_MAP(CAboutDlg)
  44. //}}AFX_DATA_MAP
  45. }
  46. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  47. //{{AFX_MSG_MAP(CAboutDlg)
  48. //}}AFX_MSG_MAP
  49. END_MESSAGE_MAP()
  50. /////////////////////////////////////////////////////////////////////////////
  51. // CDialogGLDlg dialog
  52. CDialogGLDlg::CDialogGLDlg(CWnd* pParent /*=NULL*/)
  53. : CDialog(CDialogGLDlg::IDD, pParent)
  54. {
  55. //{{AFX_DATA_INIT(CDialogGLDlg)
  56. // NOTE: the ClassWizard will add member initialization here
  57. //}}AFX_DATA_INIT
  58. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  59. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  60. m_hGLContext = NULL;
  61. m_GLPixelIndex = 0;
  62. m_xRotate = 0;
  63. m_yRotate = 0;
  64. m_Rotate = FALSE;
  65. m_ScaleX = 1.0f;
  66. m_ScaleY = 1.0f;
  67. m_ScaleZ = 1.0f;
  68. m_size = 1.5;
  69. m_exp = 9;
  70. m_RightButtonDown = FALSE;
  71. m_LeftButtonDown = FALSE;
  72. m_Antialias  = TRUE;
  73. }
  74. void CDialogGLDlg::DoDataExchange(CDataExchange* pDX)
  75. {
  76. CDialog::DoDataExchange(pDX);
  77. //{{AFX_DATA_MAP(CDialogGLDlg)
  78. // NOTE: the ClassWizard will add DDX and DDV calls here
  79. //}}AFX_DATA_MAP
  80. }
  81. BEGIN_MESSAGE_MAP(CDialogGLDlg, CDialog)
  82. ON_WM_CONTEXTMENU()
  83. //{{AFX_MSG_MAP(CDialogGLDlg)
  84. ON_WM_SYSCOMMAND()
  85. ON_WM_PAINT()
  86. ON_WM_QUERYDRAGICON()
  87. ON_WM_CREATE()
  88. ON_WM_DESTROY()
  89. ON_WM_SIZE()
  90. ON_WM_LBUTTONDOWN()
  91. ON_WM_LBUTTONUP()
  92. ON_WM_MOUSEMOVE()
  93. ON_WM_TIMER()
  94. ON_COMMAND(ID_POPUP_ROTATE, OnPopupRotate)
  95. ON_COMMAND(ID_POPUP_SIZE_DECREASE, OnPopupSizeDecrease)
  96. ON_COMMAND(ID_POPUP_SIZE_INCREASE, OnPopupSizeIncrease)
  97. ON_WM_KEYDOWN()
  98. ON_COMMAND(ID_POPUP_ANTIALIASING, OnPopupAntialiasing)
  99. //}}AFX_MSG_MAP
  100. END_MESSAGE_MAP()
  101. /////////////////////////////////////////////////////////////////////////////
  102. // CDialogGLDlg message handlers
  103. BOOL CDialogGLDlg::OnInitDialog()
  104. {
  105. CDialog::OnInitDialog();
  106. // Add "About..." menu item to system menu.
  107. // IDM_ABOUTBOX must be in the system command range.
  108. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  109. ASSERT(IDM_ABOUTBOX < 0xF000);
  110. CMenu* pSysMenu = GetSystemMenu(FALSE);
  111. if (pSysMenu != NULL)
  112. {
  113. CString strAboutMenu;
  114. strAboutMenu.LoadString(IDS_ABOUTBOX);
  115. if (!strAboutMenu.IsEmpty())
  116. {
  117. pSysMenu->AppendMenu(MF_SEPARATOR);
  118. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  119. }
  120. }
  121. // Set the icon for this dialog.  The framework does this automatically
  122. //  when the application's main window is not a dialog
  123. SetIcon(m_hIcon, TRUE); // Set big icon
  124. SetIcon(m_hIcon, FALSE); // Set small icon
  125. // TODO: Add extra initialization here
  126. return TRUE;  // return TRUE  unless you set the focus to a control
  127. }
  128. void CDialogGLDlg::OnSysCommand(UINT nID, LPARAM lParam)
  129. {
  130. if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  131. {
  132. CAboutDlg dlgAbout;
  133. dlgAbout.DoModal();
  134. }
  135. else
  136. {
  137. CDialog::OnSysCommand(nID, lParam);
  138. }
  139. }
  140. // If you add a minimize button to your dialog, you will need the code below
  141. //  to draw the icon.  For MFC applications using the document/view model,
  142. //  this is automatically done for you by the framework.
  143. void CDialogGLDlg::OnPaint() 
  144. {
  145. if (IsIconic())
  146. {
  147. CPaintDC dc(this); // device context for painting
  148. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  149. // Center icon in client rectangle
  150. int cxIcon = GetSystemMetrics(SM_CXICON);
  151. int cyIcon = GetSystemMetrics(SM_CYICON);
  152. CRect rect;
  153. GetClientRect(&rect);
  154. int x = (rect.Width() - cxIcon + 1) / 2;
  155. int y = (rect.Height() - cyIcon + 1) / 2;
  156. // Draw the icon
  157. dc.DrawIcon(x, y, m_hIcon);
  158. }
  159. else
  160. {
  161. CPaintDC dc(this); // device context for painting
  162. RenderScene();
  163. SwapBuffers(dc.m_ps.hdc);
  164. CDialog::OnPaint();
  165. }
  166. }
  167. // The system calls this to obtain the cursor to display while the user drags
  168. //  the minimized window.
  169. HCURSOR CDialogGLDlg::OnQueryDragIcon()
  170. {
  171. return (HCURSOR) m_hIcon;
  172. }
  173. BOOL CDialogGLDlg::SetWindowPixelFormat(HDC hDC)
  174. {
  175. PIXELFORMATDESCRIPTOR pixelDesc = { 
  176.     sizeof(PIXELFORMATDESCRIPTOR),    // pfd结构的大小 
  177.     1,                                // 版本号 
  178.     PFD_DRAW_TO_WINDOW |              // 支持在窗口中绘图 
  179.     PFD_SUPPORT_OPENGL |              // 支持 OpenGL 
  180.     PFD_DOUBLEBUFFER,                 // 双缓存模式 
  181.     PFD_TYPE_RGBA,                    // RGBA 颜色模式 
  182.     24,                               // 24 位颜色深度 
  183.     0, 0, 0, 0, 0, 0,                 // 忽略颜色位 
  184.     0,                                // 没有非透明度缓存 
  185.     0,                                // 忽略移位位 
  186.     0,                                // 无累加缓存 
  187.     0, 0, 0, 0,                       // 忽略累加位 
  188.     32,                               // 32 位深度缓存     
  189.     0,                                // 无模板缓存 
  190.     0,                                // 无辅助缓存 
  191.     PFD_MAIN_PLANE,                   // 主层 
  192.     0,                                // 保留 
  193.     0, 0, 0                           // 忽略层,可见性和损毁掩模 
  194. }; 
  195. m_GLPixelIndex = ChoosePixelFormat(hDC,&pixelDesc);
  196. if(m_GLPixelIndex==0) 
  197. {
  198. m_GLPixelIndex = 1;
  199. if(DescribePixelFormat(hDC,m_GLPixelIndex,
  200. sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)==0)
  201. {
  202. return FALSE;
  203. }
  204. }
  205. if(SetPixelFormat(hDC,m_GLPixelIndex,&pixelDesc)==FALSE)
  206. {
  207. return FALSE;
  208. }
  209. return TRUE;
  210. }
  211. BOOL CDialogGLDlg::CreateViewGLContext(HDC hDC)
  212. {
  213. m_hGLContext = wglCreateContext(hDC);
  214. if(m_hGLContext==NULL)
  215. return FALSE;
  216. if(wglMakeCurrent(hDC,m_hGLContext)==FALSE)
  217. return FALSE;
  218. return TRUE;
  219. }
  220. int CDialogGLDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  221. {
  222. if (CDialog::OnCreate(lpCreateStruct) == -1)
  223. return -1;
  224. HWND hWnd = GetSafeHwnd();
  225. HDC hDC = ::GetDC(hWnd);
  226. if(SetWindowPixelFormat(hDC)==FALSE)
  227. return 0;
  228. if(CreateViewGLContext(hDC)==FALSE)
  229. return 0;
  230. glClearColor(0.0,0.0,0.0,1.0);
  231. glPolygonMode(GL_FRONT,GL_LINE);
  232. glPolygonMode(GL_BACK,GL_LINE);
  233. // 反走样操作
  234. glEnable(GL_LINE_SMOOTH);
  235. glEnable(GL_BLEND);
  236. glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  237. glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);
  238. glLineWidth(1.5);
  239. BuildList();
  240. SetTimer(0,10,NULL);
  241. return 0;
  242. }
  243. void CDialogGLDlg::OnDestroy() 
  244. {
  245. CDialog::OnDestroy();
  246. if(wglGetCurrentContext() != NULL)
  247. wglMakeCurrent(NULL,NULL);
  248. if(m_hGLContext != NULL)
  249. {
  250. wglDeleteContext(m_hGLContext);
  251. m_hGLContext = NULL;
  252. }
  253. }
  254. void CDialogGLDlg::OnSize(UINT nType, int cx, int cy) 
  255. {
  256. CDialog::OnSize(nType, cx, cy);
  257. GLsizei width,height;
  258. GLdouble aspect;
  259. width = cx;
  260. height = cy;
  261. if(cy==0)
  262. aspect = (GLdouble)width;
  263. else
  264. aspect = (GLdouble)width/(GLdouble)height;
  265. glViewport(0,0,width,height);
  266. glMatrixMode(GL_PROJECTION);
  267. glLoadIdentity();
  268. gluPerspective(45,aspect,1,100.0);
  269. glMatrixMode(GL_MODELVIEW);
  270. glLoadIdentity();
  271. glDrawBuffer(GL_BACK);
  272. glEnable(GL_DEPTH_TEST);
  273. }
  274. void CDialogGLDlg::RenderScene()
  275. {
  276. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  277. glPushMatrix();
  278. glTranslated(0.0,0.0,-8.0);
  279. glRotated(m_xRotate, 1.0, 0.0, 0.0);
  280. glRotated(m_yRotate, 0.0, 1.0, 0.0);
  281. glScalef(m_ScaleX,m_ScaleY,m_ScaleZ);
  282.   
  283. ::glCallList(1);
  284. glPopMatrix();
  285. }
  286. void CDialogGLDlg::OnLButtonDown(UINT nFlags, CPoint point) 
  287. {
  288. m_LeftButtonDown = TRUE;
  289. m_LeftDownPos = point;
  290. KillTimer(0);
  291. CDialog::OnLButtonDown(nFlags, point);
  292. }
  293. void CDialogGLDlg::OnLButtonUp(UINT nFlags, CPoint point) 
  294. {
  295. m_LeftButtonDown = FALSE;
  296. CDialog::OnLButtonUp(nFlags, point);
  297. }
  298. void CDialogGLDlg::OnMouseMove(UINT nFlags, CPoint point) 
  299. {
  300. if(m_LeftButtonDown)
  301. {
  302. CSize rotate = m_LeftDownPos - point;
  303. m_LeftDownPos = point;
  304. m_yRotate -= rotate.cx;
  305. m_xRotate -= rotate.cy;
  306. InvalidateRect(NULL,FALSE);
  307. }
  308. CDialog::OnMouseMove(nFlags, point);
  309. }
  310. void CDialogGLDlg::OnContextMenu(CWnd*, CPoint point)
  311. {
  312. if (point.x == -1 && point.y == -1)
  313. { CRect rect; GetClientRect(rect); ClientToScreen(rect); point = rect.TopLeft(); point.Offset(5, 5); } CMenu menu; VERIFY(menu.LoadMenu(CG_IDR_POPUP_DIALOG_GLDLG)); CMenu* pPopup = menu.GetSubMenu(0); ASSERT(pPopup != NULL); CWnd* pWndPopupOwner = this; while (pWndPopupOwner->GetStyle() & WS_CHILD) pWndPopupOwner = pWndPopupOwner->GetParent(); pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, pWndPopupOwner); }
  314. void CDialogGLDlg::Rotate()
  315. {
  316. m_yRotate -= 2;
  317. InvalidateRect(NULL,FALSE);
  318. }
  319. void CDialogGLDlg::OnTimer(UINT nIDEvent) 
  320. {
  321. m_yRotate -= 3;
  322. m_xRotate -= 2;
  323. InvalidateRect(NULL,FALSE);
  324. CDialog::OnTimer(nIDEvent);
  325. }
  326. void CDialogGLDlg::OnPopupRotate() 
  327. {
  328. SetTimer(0,10,NULL);
  329. }
  330. void CDialogGLDlg::OnPopupSizeDecrease() 
  331. {
  332. m_ScaleX /= 1.1f;
  333. m_ScaleY /= 1.1f;
  334. m_ScaleZ /= 1.1f;
  335. InvalidateRect(NULL,FALSE);
  336. }
  337. void CDialogGLDlg::OnPopupSizeIncrease() 
  338. {
  339. m_ScaleX *= 1.1f;
  340. m_ScaleY *= 1.1f;
  341. m_ScaleZ *= 1.1f;
  342. InvalidateRect(NULL,FALSE);
  343. }
  344. //  创建显示列表
  345. void CDialogGLDlg::BuildList()
  346. {
  347. ::glNewList(1,GL_COMPILE_AND_EXECUTE);
  348.     glShadeModel(GL_SMOOTH);
  349.     glColor3ub(255,255,255);
  350. float x = m_size;
  351. float xt = 5.0f;
  352. glBegin(GL_POLYGON);
  353. glVertex3d( x,  x, x);
  354. glVertex3d( x, -x, x);
  355. glVertex3d(-x, -x, x);
  356. glVertex3d(-x,  x, x);
  357. glEnd();
  358. glBegin(GL_POLYGON);
  359. glVertex3d(-x,  x, -x);
  360. glVertex3d(-x, -x, -x);
  361. glVertex3d( x, -x, -x);
  362. glVertex3d( x,  x, -x);
  363. glEnd();
  364. glBegin(GL_POLYGON);
  365. glVertex3d( x,  x,  x);
  366. glVertex3d( x,  x, -x);
  367. glVertex3d( x, -x, -x);
  368. glVertex3d( x, -x,  x);
  369. glEnd();
  370. glBegin(GL_POLYGON);
  371. glVertex3d(-x,  x,  x);
  372. glVertex3d(-x,  x, -x);
  373. glVertex3d(-x, -x, -x);
  374. glVertex3d(-x, -x,  x);
  375. glEnd();
  376. glBegin(GL_POLYGON);
  377. glVertex3d(-x, -x,  x);
  378. glVertex3d( x, -x,  x);
  379. glVertex3d( x, -x, -x);
  380. glVertex3d(-x, -x, -x);
  381. glEnd();
  382. glBegin(GL_POLYGON);
  383. glVertex3d(-x,  x,  x);
  384. glVertex3d( x,  x,  x);
  385. glVertex3d( x,  x, -x);
  386. glVertex3d(-x,  x, -x);
  387. glEnd();
  388. ::glEndList();
  389. }
  390. void CDialogGLDlg::OnKeyDown(UINT nChar,UINT nRepCnt,UINT nFlags) 
  391. {
  392. switch(nChar)
  393. {
  394. case VK_ADD:
  395. m_ScaleX *= 1.1f;
  396. m_ScaleY *= 1.1f;
  397. m_ScaleZ *= 1.1f;
  398. InvalidateRect(NULL,FALSE);
  399. break;
  400. case VK_SUBTRACT:
  401. m_ScaleX /= 1.1f;
  402. m_ScaleY /= 1.1f;
  403. m_ScaleZ /= 1.1f;
  404. InvalidateRect(NULL,FALSE);
  405. break;
  406. default :
  407. {}
  408. }
  409. CDialog::OnKeyDown(nChar, nRepCnt, nFlags);
  410. }
  411. void CDialogGLDlg::OnPopupAntialiasing() 
  412. {
  413. m_Antialias = !m_Antialias;
  414. if(m_Antialias)
  415. {
  416. glEnable(GL_LINE_SMOOTH);
  417. glEnable(GL_BLEND);
  418. glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  419. glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);
  420. glLineWidth(10);
  421. }
  422. else
  423. {
  424. glDisable(GL_LINE_SMOOTH);
  425. glDisable(GL_BLEND);
  426. glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  427. glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);
  428. glLineWidth(10);
  429. }
  430. InvalidateRect(NULL,FALSE); 
  431. }