MeshView.cpp
Upload User: hcfgz168
Upload Date: 2011-09-11
Package Size: 116k
Code Size: 13k
Category:

OpenGL program

Development Platform:

WINDOWS

  1. // MeshView.cpp : implementation of the CMeshView class
  2. //
  3. #include "stdafx.h"
  4. #include "Mesh.h"
  5. #include "MeshDoc.h"
  6. #include "MeshView.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. /////////////////////////////////////////////////////////////////////////////
  13. // CMeshView
  14. IMPLEMENT_DYNCREATE(CMeshView, CView)
  15. BEGIN_MESSAGE_MAP(CMeshView, CView)
  16. //{{AFX_MSG_MAP(CMeshView)
  17. ON_WM_PAINT()
  18. ON_WM_DESTROY()
  19. ON_WM_SIZE()
  20. ON_WM_LBUTTONDOWN()
  21. ON_WM_LBUTTONUP()
  22. ON_WM_RBUTTONDOWN()
  23. ON_WM_RBUTTONUP()
  24. ON_WM_MOUSEMOVE()
  25. ON_WM_ERASEBKGND()
  26. ON_WM_CREATE()
  27. ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
  28. //}}AFX_MSG_MAP
  29. // Standard printing commands
  30. ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
  31. ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
  32. ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
  33. END_MESSAGE_MAP()
  34. /////////////////////////////////////////////////////////////////////////////
  35. // CMeshView construction/destruction
  36. CMeshView::CMeshView()
  37. {
  38. // OpenGL
  39. m_hGLContext = NULL;
  40. m_GLPixelIndex = 0;
  41. // Mouse
  42. m_LeftButtonDown = FALSE;
  43. m_RightButtonDown = FALSE;
  44. // Colors
  45. m_ClearColorRed   = 0.0f;
  46. m_ClearColorGreen = 0.0f;
  47. m_ClearColorBlue  = 0.2f;
  48. // Animation
  49. m_StepRotationX = 0.0f;
  50. m_StepRotationY = 5.0f;
  51. m_StepRotationZ = 0.0f;
  52. InitGeometry();
  53. }
  54. CMeshView::~CMeshView()
  55. {
  56. }
  57. //********************************************
  58. // InitGeometry
  59. //********************************************
  60. void CMeshView::InitGeometry(void)
  61. {
  62. m_xRotation = 0.0f;
  63. m_yRotation = 0.0f;
  64. m_zRotation = 0.0f;
  65. m_xTranslation = 0.0f;
  66. m_yTranslation = 0.0f;
  67. m_zTranslation = -5.0f;
  68. m_xScaling = 1.0f;
  69. m_yScaling = 1.0f;
  70. m_zScaling = 1.0f;
  71. m_SpeedRotation = 1.0f / 3.0f;
  72. m_SpeedTranslation = 1.0f / 50.0f;
  73. m_xyRotation = 1;
  74. }
  75. BOOL CMeshView::PreCreateWindow(CREATESTRUCT& cs)
  76. {
  77. return CView::PreCreateWindow(cs);
  78. }
  79. /////////////////////////////////////////////////////////////////////////////
  80. // CMeshView drawing
  81. void CMeshView::OnDraw(CDC* pDC)
  82. {
  83. CMeshDoc* pDoc = GetDocument();
  84. ASSERT_VALID(pDoc);
  85. // TODO: add draw code for native data here
  86. }
  87. /////////////////////////////////////////////////////////////////////////////
  88. // CMeshView printing
  89. BOOL CMeshView::OnPreparePrinting(CPrintInfo* pInfo)
  90. {
  91. // default preparation
  92. return DoPreparePrinting(pInfo);
  93. }
  94. void CMeshView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  95. {
  96. }
  97. void CMeshView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  98. {
  99. }
  100. /////////////////////////////////////////////////////////////////////////////
  101. // CMeshView diagnostics
  102. #ifdef _DEBUG
  103. void CMeshView::AssertValid() const
  104. {
  105. CView::AssertValid();
  106. }
  107. void CMeshView::Dump(CDumpContext& dc) const
  108. {
  109. CView::Dump(dc);
  110. }
  111. CMeshDoc* CMeshView::GetDocument() // non-debug version is inline
  112. {
  113. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMeshDoc)));
  114. return (CMeshDoc*)m_pDocument;
  115. }
  116. #endif //_DEBUG
  117. //////////////////////////////////////////////
  118. //////////////////////////////////////////////
  119. // OPENGL
  120. //////////////////////////////////////////////
  121. //////////////////////////////////////////////
  122. //********************************************
  123. // OnCreate
  124. // Create OpenGL rendering context 
  125. //********************************************
  126. int CMeshView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  127. {
  128. if(CView::OnCreate(lpCreateStruct) == -1)
  129. return -1;
  130. HWND hWnd = GetSafeHwnd();
  131. HDC hDC = ::GetDC(hWnd);
  132. if(SetWindowPixelFormat(hDC)==FALSE)
  133. return 0;
  134. if(CreateViewGLContext(hDC)==FALSE)
  135. return 0;
  136. //::ReleaseDC(hWnd,hDC);
  137. // Default mode
  138. glPolygonMode(GL_FRONT,GL_FILL);
  139. glPolygonMode(GL_BACK,GL_FILL);
  140.   glShadeModel(GL_SMOOTH);
  141. glEnable(GL_NORMALIZE);
  142. // Lights properties
  143.   float ambientProperties[]  = {0.7f, 0.7f, 0.7f, 1.0f};
  144. float diffuseProperties[]  = {0.8f, 0.8f, 0.8f, 1.0f};
  145.   float specularProperties[] = {1.0f, 1.0f, 1.0f, 1.0f};
  146.   glLightfv( GL_LIGHT0, GL_AMBIENT, ambientProperties);
  147.   glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuseProperties);
  148.   glLightfv( GL_LIGHT0, GL_SPECULAR, specularProperties);
  149.   glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, 1.0);
  150. glClearColor(m_ClearColorRed,m_ClearColorGreen,m_ClearColorBlue,1.0f);
  151.   glClearDepth(1.0f);
  152. glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
  153. // Perspective
  154. CRect rect;
  155. GetClientRect(&rect);
  156. double aspect = (rect.Height() == 0) ? rect.Width() : (double)rect.Width()/(double)rect.Height();
  157. gluPerspective(45,aspect,0.1,1000.0);
  158. //glPolygonMode(GL_FRONT,GL_FILL);
  159. //glPolygonMode(GL_BACK,GL_POINT);
  160. // Default : lighting
  161. glEnable(GL_LIGHT0);
  162. glEnable(GL_LIGHTING);
  163. // Default : blending
  164. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  165. glEnable(GL_BLEND);
  166. // Default : material
  167.   float MatAmbient[]  = {0.0f, 0.33f, 0.50f, 1.0f};
  168.   float MatDiffuse[]  = {0.5f, 0.5f, 0.5f, 1.0f};
  169.   float MatSpecular[]  = {0.1f, 0.1f, 0.1f, 1.0f};
  170.   float MatShininess[]  = { 84 };
  171.   float MatEmission[]  = {0.0f, 0.0f, 0.0f, 1.0f};
  172. // Back : green
  173.   float MatAmbientBack[]  = {0.0f, 0.5f, 0.0f, 1.0f};
  174. glEnable(GL_DEPTH_TEST);
  175. //glDepthFunc(Gl_LESS);
  176. // Modulate : texture lighting
  177.   glEnable(GL_TEXTURE_2D);
  178. TRACE("Texture parameters...n");
  179.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  180.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  181.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  182.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  183.   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  184. return 1;
  185. }
  186. /////////////////////////////////////////////////////////////////////////////
  187. // CMeshView message handlers
  188. void CMeshView::OnPaint() 
  189. {
  190. // Device context for painting
  191. CPaintDC dc(this); 
  192. // Model is stored in Document
  193. CMeshDoc *pDoc = (CMeshDoc *)GetDocument();
  194. //ASSERT_VALID(pDoc);
  195. // Useful in multidoc templates
  196. HWND hWnd = GetSafeHwnd();
  197. HDC hDC = ::GetDC(hWnd);
  198. wglMakeCurrent(hDC,m_hGLContext);
  199. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  200. glPushMatrix();
  201. // Position / translation / scale
  202. glTranslated(m_xTranslation,m_yTranslation,m_zTranslation);
  203. glRotatef(m_xRotation, 1.0, 0.0, 0.0);
  204. glRotatef(m_yRotation, 0.0, 1.0, 0.0);
  205. glRotatef(m_zRotation, 0.0, 0.0, 1.0);
  206. glScalef(m_xScaling,m_yScaling,m_zScaling);
  207. // Start rendering...
  208. pDoc->RenderScene();
  209. glPopMatrix();
  210. // Double buffer
  211. SwapBuffers(dc.m_ps.hdc);
  212. glFlush();
  213. // Release
  214. ::ReleaseDC(hWnd,hDC);
  215. }
  216. //********************************************
  217. // SetWindowPixelFormat
  218. //********************************************
  219. BOOL CMeshView::SetWindowPixelFormat(HDC hDC)
  220. {
  221. PIXELFORMATDESCRIPTOR pixelDesc;
  222. pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
  223. pixelDesc.nVersion = 1;
  224. pixelDesc.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
  225. PFD_DOUBLEBUFFER | PFD_STEREO_DONTCARE;
  226. pixelDesc.iPixelType = PFD_TYPE_RGBA;
  227. pixelDesc.cColorBits = 32;
  228. pixelDesc.cRedBits = 8;
  229. pixelDesc.cRedShift = 16;
  230. pixelDesc.cGreenBits = 8;
  231. pixelDesc.cGreenShift = 8;
  232. pixelDesc.cBlueBits = 8;
  233. pixelDesc.cBlueShift = 0;
  234. pixelDesc.cAlphaBits = 0;
  235. pixelDesc.cAlphaShift = 0;
  236. pixelDesc.cAccumBits = 64;
  237. pixelDesc.cAccumRedBits = 16;
  238. pixelDesc.cAccumGreenBits = 16;
  239. pixelDesc.cAccumBlueBits = 16;
  240. pixelDesc.cAccumAlphaBits = 0;
  241. pixelDesc.cDepthBits = 32;
  242. pixelDesc.cStencilBits = 8;
  243. pixelDesc.cAuxBuffers = 0;
  244. pixelDesc.iLayerType = PFD_MAIN_PLANE;
  245. pixelDesc.bReserved = 0;
  246. pixelDesc.dwLayerMask = 0;
  247. pixelDesc.dwVisibleMask = 0;
  248. pixelDesc.dwDamageMask = 0;
  249. m_GLPixelIndex = ChoosePixelFormat(hDC,&pixelDesc);
  250. if(m_GLPixelIndex == 0) // Choose default
  251. {
  252. m_GLPixelIndex = 1;
  253. if(DescribePixelFormat(hDC,m_GLPixelIndex,
  254. sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)==0)
  255. return FALSE;
  256. }
  257. if(!SetPixelFormat(hDC,m_GLPixelIndex,&pixelDesc))
  258. return FALSE;
  259. // CListBox
  260. return TRUE;
  261. }
  262. //********************************************
  263. // CreateViewGLContext
  264. // Create an OpenGL rendering context
  265. //********************************************
  266. BOOL CMeshView::CreateViewGLContext(HDC hDC)
  267. {
  268. m_hGLContext = wglCreateContext(hDC);
  269. if(m_hGLContext==NULL)
  270. return FALSE;
  271. if(wglMakeCurrent(hDC,m_hGLContext)==FALSE)
  272. return FALSE;
  273. return TRUE;
  274. }
  275. void CMeshView::OnDestroy() 
  276. {
  277. if(wglGetCurrentContext() != NULL)
  278. wglMakeCurrent(NULL,NULL);
  279. if(m_hGLContext != NULL)
  280. {
  281. wglDeleteContext(m_hGLContext);
  282. m_hGLContext = NULL;
  283. }
  284. CView::OnDestroy();
  285. }
  286. void CMeshView::OnSize(UINT nType, int cx, int cy) 
  287. {
  288. CView::OnSize(nType, cx, cy);
  289. HWND hWnd = GetSafeHwnd();
  290. HDC hDC = ::GetDC(hWnd);
  291. //TRACE("Activate view, set active OpenGL rendering context...n");
  292. wglMakeCurrent(hDC,m_hGLContext);
  293. // Set OpenGL perspective, viewport and mode
  294. double aspect = (cy == 0) ? cx : (double)cx/(double)cy;
  295. glViewport(0,0,cx,cy);
  296. glMatrixMode(GL_PROJECTION);
  297. glLoadIdentity();
  298. gluPerspective(45,aspect,0.1,1000.0);
  299. glMatrixMode(GL_MODELVIEW);
  300. glLoadIdentity();
  301. glDrawBuffer(GL_BACK);
  302. // Release
  303. ::ReleaseDC(hWnd,hDC);
  304. }
  305. void CMeshView::OnLButtonDown(UINT nFlags, CPoint point) 
  306. {
  307. m_LeftButtonDown = TRUE;
  308. m_LeftDownPos = point;
  309. SetCapture();
  310. CView::OnLButtonDown(nFlags, point);
  311. }
  312. void CMeshView::OnLButtonUp(UINT nFlags, CPoint point) 
  313. {
  314. m_RightButtonDown = FALSE;
  315. m_LeftButtonDown = FALSE;
  316. ReleaseCapture();
  317. CView::OnLButtonUp(nFlags, point);
  318. }
  319. void CMeshView::OnRButtonDown(UINT nFlags, CPoint point) 
  320. {
  321. m_RightButtonDown = TRUE;
  322. m_RightDownPos = point;
  323. SetCapture();
  324. CView::OnRButtonDown(nFlags, point);
  325. }
  326. void CMeshView::OnRButtonUp(UINT nFlags, CPoint point) 
  327. {
  328. m_RightButtonDown = FALSE;
  329. m_LeftButtonDown = FALSE;
  330. ReleaseCapture();
  331. CView::OnRButtonUp(nFlags, point);
  332. }
  333. void CMeshView::OnMouseMove(UINT nFlags, CPoint point) 
  334. {
  335. // Both : rotation
  336. if(m_LeftButtonDown && m_RightButtonDown)
  337. {
  338. if(m_xyRotation)
  339. {
  340. m_yRotation -= (float)(m_LeftDownPos.x - point.x) * m_SpeedRotation;
  341. m_xRotation -= (float)(m_LeftDownPos.y - point.y) * m_SpeedRotation;
  342. }
  343. else
  344. {
  345. m_zRotation -= (float)(m_LeftDownPos.x - point.x) * m_SpeedRotation;
  346. m_xRotation -= (float)(m_LeftDownPos.y - point.y) * m_SpeedRotation;
  347. }
  348. m_LeftDownPos = point;
  349. m_RightDownPos = point;
  350. InvalidateRect(NULL,FALSE);
  351. }
  352. else
  353. // Left : x / y translation
  354. if(m_LeftButtonDown)
  355. {
  356. m_xTranslation -= (float)(m_LeftDownPos.x - point.x) * m_SpeedTranslation;
  357. m_yTranslation += (float)(m_LeftDownPos.y - point.y) * m_SpeedTranslation;
  358. m_LeftDownPos = point;
  359. InvalidateRect(NULL,FALSE);
  360. }
  361. else
  362. // Right : z translation
  363. if(m_RightButtonDown)
  364. {
  365. m_zTranslation += (float)(m_RightDownPos.y - point.y) * m_SpeedTranslation;
  366. m_RightDownPos = point;
  367. InvalidateRect(NULL,FALSE);
  368. }
  369. /*
  370. TRACE("nPositionn");
  371. TRACE("Translation : %g %g %gn",m_xTranslation,m_yTranslation,m_zTranslation);
  372. TRACE("Rotation    : %g %g %gn",m_xRotation,m_yRotation,m_zRotation);
  373. */
  374. CView::OnMouseMove(nFlags, point);
  375. }
  376. BOOL CMeshView::OnEraseBkgnd(CDC* pDC) 
  377. {
  378. return TRUE;
  379. return CView::OnEraseBkgnd(pDC);
  380. }
  381. void CMeshView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView) 
  382. {
  383. HWND hWnd = GetSafeHwnd();
  384. HDC hDC = ::GetDC(hWnd);
  385. wglMakeCurrent(hDC,m_hGLContext);
  386. ::ReleaseDC(hWnd,hDC);
  387. CView::OnActivateView(bActivate, pActivateView, pDeactiveView);
  388. }
  389. void CMeshView::OnEditCopy() 
  390. {
  391.   // Clean clipboard of contents, and copy the DIB.
  392.   if(OpenClipboard())
  393.    {
  394.     BeginWaitCursor();
  395. // Snap
  396. CSize size;
  397. unsigned char *pixel = SnapClient(&size);
  398. // Image
  399. CTexture image;
  400. // Link image - buffer
  401. int success = 0;
  402. VERIFY(image.ReadBuffer(pixel,size.cx,size.cy,24));
  403. // Cleanup memory
  404. delete [] pixel;
  405.     EmptyClipboard();
  406.     SetClipboardData(CF_DIB,image.ExportHandle());
  407.     CloseClipboard();
  408.     EndWaitCursor();
  409.    }
  410. }
  411. // Hand-made client snapping
  412. unsigned char *CMeshView::SnapClient(CSize *pSize)
  413. {
  414. BeginWaitCursor();
  415. // Client zone
  416. CRect rect;
  417. GetClientRect(&rect);
  418. //CSize size(CTexture::LowerPowerOfTwo(rect.Width()),rect.Height());
  419. CSize size(rect.Width(),rect.Height());
  420. *pSize = size;
  421. ASSERT(size.cx > 0);
  422. ASSERT(size.cy > 0);
  423. // Alloc
  424. unsigned char *pixel = new unsigned char[3*size.cx*size.cy];
  425. ASSERT(pixel != NULL);
  426. // Capture frame buffer
  427. TRACE("Start reading client...n");
  428. TRACE("Client : (%d,%d)n",size.cx,size.cy);
  429. CRect ClientRect,MainRect;
  430. this->GetWindowRect(&ClientRect);
  431. CWnd *pMain = AfxGetApp()->m_pMainWnd;
  432. CWindowDC dc(pMain);
  433. pMain->GetWindowRect(&MainRect);
  434. int xOffset = ClientRect.left - MainRect.left;
  435. int yOffset = ClientRect.top - MainRect.top;
  436. for(int j=0;j<size.cy;j++)
  437. for(int i=0;i<size.cx;i++)
  438. {
  439. COLORREF color = dc.GetPixel(i+xOffset,j+yOffset);
  440. pixel[3*(size.cx*(size.cy-1-j)+i)] = (BYTE)GetBValue(color);
  441. pixel[3*(size.cx*(size.cy-1-j)+i)+1] = (BYTE)GetGValue(color);
  442. pixel[3*(size.cx*(size.cy-1-j)+i)+2] = (BYTE)GetRValue(color);
  443. }
  444. EndWaitCursor();
  445. return pixel;
  446. }