Test1View.cpp
上传用户:wangdan
上传日期:2022-06-30
资源大小:739k
文件大小:24k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. // Test1View.cpp : implementation of the CTest1View class
  2. //
  3. #include "stdafx.h"
  4. #include "Test1.h"
  5. #include "Test1Doc.h"
  6. #include "Test1View.h"
  7. #include "MainFrm.h"
  8. #include "ControlWnd.h"
  9. #include "ProjectView.h"
  10. #include "math.h"
  11. #ifdef _DEBUG
  12. #define new DEBUG_NEW
  13. #undef THIS_FILE
  14. static char THIS_FILE[] = __FILE__;
  15. #endif
  16. GLfloat Databuf[ArrayOne][ArrayTwo];
  17. GLfloat  xrof,yrof,zrof;//各坐标轴倾角
  18. /////////////////////////////////////////////////////////////////////////////
  19. // CTest1View
  20. extern bool   gbIsGetData;
  21. extern bool   gbDataIsEmpty;
  22. IMPLEMENT_DYNCREATE(CTest1View, CView)
  23. BEGIN_MESSAGE_MAP(CTest1View, CView)
  24. //{{AFX_MSG_MAP(CTest1View)
  25. ON_WM_CREATE()
  26. ON_WM_DESTROY()
  27. ON_WM_SIZE()
  28. ON_COMMAND(IDC_TURNX, OnTurnx)
  29. ON_COMMAND(IDC_TURNY, OnTurny)
  30. ON_COMMAND(IDC_TURNZ, OnTurnz)
  31. ON_WM_ERASEBKGND()
  32. ON_COMMAND(IDC_RESUME, OnResume)
  33. ON_WM_MOUSEWHEEL()
  34. ON_WM_LBUTTONDOWN()
  35. ON_WM_LBUTTONUP()
  36. ON_WM_MOUSEMOVE()
  37. ON_WM_CONTEXTMENU()
  38. ON_WM_KILLFOCUS()
  39. //}}AFX_MSG_MAP
  40. // Standard printing commands
  41. ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
  42. ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
  43. ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
  44. END_MESSAGE_MAP()
  45. /////////////////////////////////////////////////////////////////////////////
  46. // CTest1View construction/destruction
  47. CTest1View::CTest1View()
  48. {
  49. m_pDC = NULL;
  50. nWithy = 0;
  51. m_Prox = 60;
  52. m_Proy = 5;
  53. m_Proz = 10;
  54. m_First = 1;
  55. m_Second = 2;
  56. m_Third = 3;
  57. m_bDown = false;
  58. m_bIsMove = true;
  59. m_bGetFileSuccess = true;
  60. m_pFr = NULL;
  61. m_FileName = "data/t56a.3DSF";
  62. m_nMinDepth = 520.00f; 
  63. m_nMaxDepth = 3299.875 ;
  64. m_bMoveSel = false;
  65. m_SelType = 0; 
  66. m_Zoom = 0;
  67. m_xMove = m_yMove = m_zMove = 0;
  68. m_bLighting = false;
  69. }
  70. CTest1View::~CTest1View()
  71. {
  72. if (m_pDC)
  73. {
  74. delete m_pDC;
  75. m_pDC = NULL;
  76. }
  77. }
  78. BOOL CTest1View::PreCreateWindow(CREATESTRUCT& cs)
  79. {
  80. // TODO: Modify the Window class or styles here by modifying
  81. //  the CREATESTRUCT cs
  82. return CView::PreCreateWindow(cs);
  83. }
  84. /////////////////////////////////////////////////////////////////////////////
  85. // CTest1View drawing
  86. void CTest1View::OnDraw(CDC* pDC)
  87. {
  88. CTest1Doc* pDoc = GetDocument();
  89. ASSERT_VALID(pDoc);
  90. //清除颜色缓冲和深度缓冲
  91. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  92. //用单位矩阵替换当前矩阵
  93. glLoadIdentity();
  94. //旋转角度
  95. glRotatef(xrof,1.0f,0.0f,0.0f);//x轴
  96. glRotatef(yrof,0.0f,1.0f,0.0f);//y轴
  97. glRotatef(zrof,0.0f,0.0f,1.0f);//z轴
  98. //选择框
  99. if( this->m_pFr->m_pCtrlWnd->m_bShowConsult)
  100. this->Draw3DRect();
  101. //画点
  102. this->PutPoint();
  103. //坐标系和文字
  104. if (this->m_pFr->m_pCtrlWnd->m_bShowCoordinate)
  105. {
  106. this->DrawLines();
  107. this->DrawText();
  108. }
  109. //强制绘图完成
  110. glFinish();
  111. //交换缓冲区数据
  112. SwapBuffers(wglGetCurrentDC());
  113. //画选中区域
  114. this->DrawSelArea(pDC);
  115. }
  116. /////////////////////////////////////////////////////////////////////////////
  117. // CTest1View printing
  118. BOOL CTest1View::OnPreparePrinting(CPrintInfo* pInfo)
  119. {
  120. // default preparation
  121. return DoPreparePrinting(pInfo);
  122. }
  123. void CTest1View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  124. {
  125. // TODO: add extra initialization before printing
  126. }
  127. void CTest1View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  128. {
  129. // TODO: add cleanup after printing
  130. }
  131. /////////////////////////////////////////////////////////////////////////////
  132. // CTest1View diagnostics
  133. #ifdef _DEBUG
  134. void CTest1View::AssertValid() const
  135. {
  136. CView::AssertValid();
  137. }
  138. void CTest1View::Dump(CDumpContext& dc) const
  139. {
  140. CView::Dump(dc);
  141. }
  142. CTest1Doc* CTest1View::GetDocument() // non-debug version is inline
  143. {
  144. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTest1Doc)));
  145. return (CTest1Doc*)m_pDocument;
  146. }
  147. #endif //_DEBUG
  148. /////////////////////////////////////////////////////////////////////////////
  149. // CTest1View message handlers
  150. int CTest1View::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  151. {
  152. if (CView::OnCreate(lpCreateStruct) == -1)
  153. return -1;
  154. return 0;
  155. }
  156. //在此释放OpenGL使用的设备环境
  157. void CTest1View::OnDestroy() 
  158. {
  159. CView::OnDestroy();
  160. HGLRC   hrc;
  161. hrc = ::wglGetCurrentContext();
  162. ::wglMakeCurrent(NULL,  NULL);
  163. if (hrc)
  164. ::wglDeleteContext(hrc);
  165. }
  166. //设置视口
  167. void CTest1View::OnSize(UINT nType, int cx, int cy) 
  168. {
  169. CView::OnSize(nType, cx, cy);
  170. SetViewPort(cx,cy);
  171. }
  172. void CTest1View::SetViewPort(int cx, int cy)
  173. {
  174. this->m_xRect = cx;
  175. this->m_yRect = cy;
  176. //避免除数为0
  177. if(m_yRect==0)
  178. m_yRect=1;
  179. glViewport(0,0,m_xRect,m_yRect);
  180. glMatrixMode(GL_PROJECTION);
  181. glLoadIdentity();
  182. if(m_xRect>=m_yRect)
  183. {
  184. glOrtho(-20.0,20.0,-20.0*(GLfloat)m_yRect/(GLfloat)m_xRect, 20.0*(GLfloat)m_yRect/(GLfloat)m_xRect,-50.0,50.0);
  185. }
  186. else
  187. {
  188. glOrtho(-20.0*(GLfloat)m_xRect/(GLfloat)m_yRect,20.0*(GLfloat)m_xRect/(GLfloat)m_yRect,-20.0,20.0,-50.0,50.0);
  189. }
  190. glMatrixMode(GL_MODELVIEW);
  191. glLoadIdentity();
  192. }
  193. //从文件中读取数据
  194. bool CTest1View::GetFileData(CString filename)
  195. {
  196. ::gbIsGetData = true;
  197. ::gbDataIsEmpty = true;
  198. ::SendMessage(this->m_pFr->m_pCtrlWnd->m_hWnd,MESSAGE_DISABLEBTN,0,0);
  199. this->ZeroArray();
  200. this->m_pFr->InvalidateAllWnd();//Invalidate();
  201. FILE *stream;
  202. GLfloat Num;
  203. if( (stream = fopen( filename, "r+t" )) != NULL )
  204. {
  205. int n = 0,m = 0;
  206. for (int i=0; i<ArrayOne; i++)
  207. {
  208. if (n == 0 || n == 200)
  209. {   
  210. m ++;
  211. ::SendMessage(this->m_pFr->m_hWnd,MESSAGE_STEPPRO,m,0);
  212. n = 0;
  213. }
  214. n++;
  215. for(int j=0; j<ArrayTwo; j++)
  216. {
  217. fscanf(stream,"%f",&Num);
  218. Databuf[i][j]=Num;
  219. }
  220. }
  221. fclose( stream );
  222. ::gbIsGetData = false;
  223. m_bGetFileSuccess = true;
  224. ::gbDataIsEmpty = false;
  225. ::SendMessage(this->m_pFr->m_pCtrlWnd->m_hWnd,MESSAGE_ENABLEBTN,0,0);
  226. ::SendMessage(this->m_pFr->m_pCtrlWnd->m_hWnd,MESSAGE_GETDATAFINISHED,0,0);
  227. }
  228. else
  229. m_bGetFileSuccess = false;
  230. return m_bGetFileSuccess;
  231. }
  232. //设置适于OpenGL使用的像素格式
  233. bool CTest1View::bSetPixelFormat()
  234. {
  235. //定义一种像素格式
  236. static PIXELFORMATDESCRIPTOR pfd =
  237. {   
  238. sizeof(PIXELFORMATDESCRIPTOR),  // size of this pfd
  239. 1,  // version number
  240. PFD_DRAW_TO_WINDOW |// support window
  241. PFD_SUPPORT_OPENGL |  // support OpenGL  支持OpenGL
  242. PFD_DOUBLEBUFFER, // double buffered 支持又缓冲
  243. PFD_TYPE_RGBA,  // RGBA type使用RGBA模式,不用调色板
  244. 24, // 24-bit color depth  使用24位真彩色
  245. 0, 0, 0, 0, 0, 0,   // color bits ignored
  246. 0,  // no alpha buffer
  247. 0,  // shift bit ignored
  248. 0,  // no accumulation buffer
  249. 0, 0, 0, 0, // accum bits ignored
  250. 32, // 32-bit z-buffer   32位Z轴缓冲
  251. 0,  // no stencil buffer
  252. 0,  // no auxiliary buffer
  253. PFD_MAIN_PLANE, // main layer
  254. 0,  // reserved
  255. 0, 0, 0 // layer masks ignored
  256. };
  257. int pixelformat;
  258. //如果可以得到指定的
  259. if ( (pixelformat = ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd)) == FALSE )
  260. {
  261. AfxMessageBox("ChoosePixelFormat failed");
  262. return false;
  263. }
  264. //用上面取到的格式设置设备环境
  265. if (SetPixelFormat(m_pDC->GetSafeHdc(), pixelformat, &pfd) == FALSE)
  266. {
  267. AfxMessageBox("SetPixelFormat failed");
  268. return false;
  269. }
  270. return true;
  271. }
  272. //初始化OpenGL环境
  273. void CTest1View::IniOpenGL()
  274. {
  275. m_pDC = new CClientDC(this);
  276. PIXELFORMATDESCRIPTOR pfd;
  277. int n;
  278. //定义一个绘制上下文的句柄
  279. HGLRC   hrc;
  280. //初始化过程中主要就是初始化了一个客户区的设备环境指针
  281. ASSERT(m_pDC != NULL);
  282. //建立应用所需的像素格式,并与当前设备上下文相关连
  283. if (!bSetPixelFormat())
  284. return;
  285. //得到指定设备环境的象素模式索引
  286. n = ::GetPixelFormat(m_pDC->GetSafeHdc());
  287. //根据上面得到的索引值来声明一个象素模式
  288. ::DescribePixelFormat(m_pDC->GetSafeHdc(), n, sizeof(pfd), &pfd);
  289. //创建一个上下文设备环境
  290. hrc = wglCreateContext(m_pDC->GetSafeHdc());
  291. //将刚生成的设备上下文指针设为当前环境
  292. wglMakeCurrent(m_pDC->GetSafeHdc(), hrc);
  293. //置黑背景
  294. glClearColor(0.0,0.0,0.0,0.0);
  295. glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  296. glShadeModel(GL_SMOOTH);
  297. // 设置混色函数取得半透明效果
  298. glBlendFunc(GL_SRC_ALPHA,GL_ONE); 
  299. glEnable(GL_BLEND); 
  300. //平滑线条
  301.     glEnable (GL_LINE_SMOOTH);
  302.     glEnable (GL_BLEND);
  303. //初始化反走样为 RGBA 模式,同时包括 alpha 混合、提示的设置
  304. // glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  305. // glEnable (GL_BLEND);
  306. // 真正精细的透视修正
  307.   //  glHint (GL_POLYGON_SMOOTH_HINT|GL_LINE_SMOOTH_HINT, GL_NICEST);
  308. //充许深度测试
  309. glEnable(GL_DEPTH_TEST);
  310. glDepthFunc(GL_LEQUAL); 
  311. }
  312. //设为绕X轴旋转
  313. void CTest1View::OnTurnx() 
  314. {
  315. nWithy = 0;
  316. CButton *btn = (CButton*)this->m_pFr->m_pCtrlWnd->GetDlgItem(IDC_RADIOTURNX);
  317. btn->SetCheck(1);
  318. btn = (CButton*)this->m_pFr->m_pCtrlWnd->GetDlgItem(IDC_RADIOTURNY);
  319. btn->SetCheck(0);
  320. btn = (CButton*)this->m_pFr->m_pCtrlWnd->GetDlgItem(IDC_RADIOTURNZ);
  321. btn->SetCheck(0);
  322. }
  323. //设为绕Y轴旋转
  324. void CTest1View::OnTurny() 
  325. {
  326. nWithy = 1;
  327. CButton *btn = (CButton*)this->m_pFr->m_pCtrlWnd->GetDlgItem(IDC_RADIOTURNX);
  328. btn->SetCheck(0);
  329. btn = (CButton*)this->m_pFr->m_pCtrlWnd->GetDlgItem(IDC_RADIOTURNY);
  330. btn->SetCheck(1);
  331. btn = (CButton*)this->m_pFr->m_pCtrlWnd->GetDlgItem(IDC_RADIOTURNZ);
  332. btn->SetCheck(0);
  333. }
  334. //设为绕Z轴旋转
  335. void CTest1View::OnTurnz() 
  336. {
  337. nWithy = 2;
  338. CButton *btn = (CButton*)this->m_pFr->m_pCtrlWnd->GetDlgItem(IDC_RADIOTURNX);
  339. btn->SetCheck(0);
  340. btn = (CButton*)this->m_pFr->m_pCtrlWnd->GetDlgItem(IDC_RADIOTURNY);
  341. btn->SetCheck(0);
  342. btn = (CButton*)this->m_pFr->m_pCtrlWnd->GetDlgItem(IDC_RADIOTURNZ);
  343. btn->SetCheck(1);
  344. }
  345. //不重画背景
  346. BOOL CTest1View::OnEraseBkgnd(CDC* pDC) 
  347. {
  348. return TRUE;
  349. }
  350. void CTest1View::OnResume() 
  351. {
  352. xrof = 0;
  353. yrof = 0;
  354. zrof = 0;
  355. m_Prox = 60;
  356. m_Proy = 5;
  357. m_Proz = 10;
  358. this->m_pFr->InvalidateAllWnd();
  359. }
  360. //处理鼠标滚轴消息
  361. BOOL CTest1View::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) 
  362. {
  363. if (this->m_bIsMove)
  364. {
  365. switch (nWithy)
  366. {
  367. case 0:
  368. {
  369. xrof -= zDelta/20;
  370. if (xrof > -360 || xrof < 360)
  371. xrof = ::xrof;
  372. else
  373. xrof = (int)xrof%360; 
  374. }
  375. break;
  376. case 1:
  377. {
  378. yrof -= zDelta/20;
  379. if (yrof >= -360 || yrof < 360)
  380. yrof = ::yrof;
  381. else
  382. yrof = (int)yrof%360; 
  383. }
  384. break;
  385. case 2:
  386. {
  387. zrof -= zDelta/20;
  388. if (zrof >=-360 || zrof< 360)
  389. zrof = ::zrof;
  390. else
  391. zrof = (int)zrof%360; 
  392. }
  393. break;
  394. default:
  395. break;
  396. }
  397. ::SendMessage(this->m_pFr->m_pProView->m_hWnd, MESSAGE_ANGLECHANGING, 0, 0);
  398. this->Invalidate();
  399. }
  400. return CView::OnMouseWheel(nFlags, zDelta, pt);
  401. }
  402. //画坐标系
  403. void CTest1View::DrawLines()
  404. {
  405. //Draw Lines
  406. glBegin(GL_LINES);
  407. //X
  408. glColor3f(0.0f,1.0f,0.0f);
  409. glVertex3f(-10.0f-m_Zoom,0.0f,0.0f);
  410. glVertex3f(10.0f+m_Zoom,0.0f,0.0f);
  411. //Arrow
  412. glVertex3f(9.60f+m_Zoom,0.3f,0.0f);
  413. glVertex3f(10.0f+m_Zoom,0.0f,0.0f);
  414. glVertex3f(9.60f+m_Zoom,-0.3f,0.0f);
  415. glVertex3f(10.0f+m_Zoom,0.0f,0.0f);
  416. glVertex3f(9.60f+m_Zoom,0.0f,0.3f);
  417. glVertex3f(10.0f+m_Zoom,0.0f,0.0f);
  418. glVertex3f(9.60f+m_Zoom,0.0f,-0.3f);
  419. glVertex3f(10.0f+m_Zoom,0.0f,0.0f);
  420. //Y
  421. glColor3f(1.0f,0.0f,0.0f);
  422. glVertex3f(0.0f,-10.0f-m_Zoom,0.0f);
  423. glVertex3f(0.0f,10.0f+m_Zoom,0.0f);
  424. //Arrow
  425. glVertex3f(-0.3f,9.6f+m_Zoom,0.0f);
  426. glVertex3f(0.0f,10.0f+m_Zoom,0.0f);
  427. glVertex3f(0.3f,9.6F+m_Zoom,0.0f);
  428. glVertex3f(0.0f,10.0f+m_Zoom,0.0f);
  429. glVertex3f(0.0f,9.6f+m_Zoom,-0.3f);
  430. glVertex3f(0.0f,10.0f+m_Zoom,0.0f);
  431. glVertex3f(0.0f,9.6F+m_Zoom,0.3f);
  432. glVertex3f(0.0f,10.0f+m_Zoom,0.0f);
  433. //Z
  434. glColor3f(0.0f,0.0f,1.0f);
  435. glVertex3f(0.0f,0.0f,-10.0f-m_Zoom);
  436. glVertex3f(0.0f,0.0f,10.0f+m_Zoom);
  437. //Arrow
  438. glVertex3f(0.3f,0.0f,9.60f+m_Zoom);
  439. glVertex3f(0.0f,0.0f,10.0f+m_Zoom);
  440. glVertex3f(-0.3f,0.0f,9.60f+m_Zoom);
  441. glVertex3f(0.0f,0.0f,10.0f+m_Zoom);
  442. glVertex3f(0.0f,0.3f,9.60f+m_Zoom);
  443. glVertex3f(0.0f,0.0f,10.0f+m_Zoom);
  444. glVertex3f(0.0f,-0.3f,9.60f+m_Zoom);
  445. glVertex3f(0.0f,0.0f,10.0f+m_Zoom);
  446. glEnd();
  447. glBegin(GL_POINTS); 
  448. glColor3f(1.0f, 1.0f, 1.0f);
  449. glVertex3f(6.5f,0.0f,0.0f);
  450. glVertex3f(-6.5f,0.0f,0.0f);
  451. glVertex3f(0.0f,6.5f,0.0f);
  452. glVertex3f(0.0f,-6.5f,0.0f);
  453. glVertex3f(0.0f,0.0f,6.5f);
  454. glVertex3f(0.0f,0.0f,-6.5f);
  455. glEnd();
  456. }
  457. //画点
  458. void CTest1View::PutPoint()
  459. {
  460. if (::gbIsGetData)
  461. return;
  462. if (::gbDataIsEmpty)
  463. return;
  464. //为了将点移到坐标中间向各个方向平移坐标系
  465. glTranslatef(-5.0f/*-m_Zoom*/,0.0f,0.0f);
  466. glTranslatef(0.0f,-5.0f-2*m_Zoom,0.0f);
  467. glTranslatef(0.0f,0.0f,-22.0f-2*m_Zoom);
  468. //Put Points
  469. glBegin(GL_POINTS); 
  470. for (int i=0; i<ArrayOne; i++)
  471. {
  472. glColor3f((GLfloat)Databuf[i][m_First]/(GLfloat)625.0,
  473. (GLfloat)Databuf[i][m_Second]/(GLfloat)48.0,
  474. 0.0);
  475. if ((GLfloat)Databuf[i][0] >= this->m_nMinDepth && (GLfloat)Databuf[i][0] <= this->m_nMaxDepth )
  476. glVertex3f((GLfloat)(Databuf[i][m_First]/(m_Prox-m_Zoom)),
  477. (GLfloat)(Databuf[i][m_Second]/(m_Proy-m_Zoom)),
  478. (GLfloat)(Databuf[i][m_Third]*(m_Proz+m_Zoom)));
  479. glEnd();
  480. //将坐标系移回原点
  481. glTranslatef(5.0f/*+m_Zoom*/,0.0f,0.0f);
  482. glTranslatef(0.0f,5.0f+2*m_Zoom,0.0f);
  483. glTranslatef(0.0f,0.0f,22.0f+2*m_Zoom);
  484. }
  485. //将取到的数据进行重新排序,当前系统中没有调用该函数
  486. void CTest1View::ResortData()
  487. {
  488. //重排声波
  489. GLfloat t;
  490. for(int j=0;j<ArrayOne; j++)
  491. {
  492. for (int i=0; i<ArrayOne;i++)
  493. {
  494. if (Databuf[i][1]>Databuf[i+1][1])
  495. {
  496. t = Databuf[i][1];
  497. Databuf[i][1] = Databuf[i+1][1];
  498. Databuf[i+1][1] = t;
  499. }
  500. }
  501. }
  502. //重排中子
  503. for( j=0;j<ArrayOne; j++)
  504. {
  505. for (int i=0; i<ArrayOne;i++)
  506. {
  507. if (Databuf[i][2]>Databuf[i+1][2])
  508. {
  509. t = Databuf[i][2];
  510. Databuf[i][2] = Databuf[i+1][2];
  511. Databuf[i+1][2] = t;
  512. }
  513. }
  514. }
  515. //重排密度
  516. for( j=0;j<ArrayOne; j++)
  517. {
  518. for (int i=0; i<ArrayOne;i++)
  519. {
  520. if (Databuf[i][3]>Databuf[i+1][3])
  521. {
  522. t = Databuf[i][3];
  523. Databuf[i][3] = Databuf[i+1][3];
  524. Databuf[i+1][3] = t;
  525. }
  526. }
  527. }
  528. }
  529. void CTest1View::OnLButtonDown(UINT nFlags, CPoint point) 
  530. {
  531. this->m_bDown = true;
  532. this->m_xM = point.x;
  533. this->m_yM = point.y;
  534. m_MouseDown = point;
  535. CView::OnLButtonDown(nFlags, point);
  536. }
  537. void CTest1View::OnLButtonUp(UINT nFlags, CPoint point) 
  538. {
  539. this->m_bDown = false;
  540. CRect rect  =  m_SelRect;
  541. rect.left = rect.left+5;
  542. rect.top = rect.top+64;
  543. rect.bottom = rect.bottom+62;
  544. //将选中的区域做成位图
  545. m_hBmp = CopySelArearToBitmap(rect);
  546. ::SendMessage(this->m_pFr->m_pProView->m_hWnd,MESSAGE_BMPHASBECOPIED,0,0);
  547. CView::OnLButtonUp(nFlags, point);
  548. }
  549. void CTest1View::OnMouseMove(UINT nFlags, CPoint point) 
  550. {
  551. if (!m_bDown)
  552. return;
  553. m_MouseMove = point;
  554. if (!this->IsMouseInWndRect(point))
  555. this->m_bDown = false;
  556. if (this->m_bIsMove )
  557. {
  558. m_bMoveSel = false;
  559. //设置一个范围,保证能正常的上下或左右转动坐标系5个像素
  560. if (this->m_yM - point.y > 5 || this->m_yM - point.y < -5)
  561. ::xrof = xrof - (this->m_yM - point.y)/20;
  562. if (::xrof >=-360 || ::xrof< 360)
  563. ::xrof = ::xrof;
  564. else
  565. ::xrof = (int)::xrof%360;
  566. if ( this->m_xM - point.x > 5 || this->m_xM - point.x < -5 )
  567. ::yrof = yrof - (this->m_xM - point.x)/20;
  568. if (::yrof > -360 || ::yrof< 360)
  569. ::yrof = ::yrof;
  570. else
  571. ::yrof = (int)::yrof%360;
  572. ::SendMessage(this->m_pFr->m_pProView->m_hWnd, MESSAGE_ANGLECHANGING, 0, 0);
  573. this->Invalidate();
  574. }
  575. else
  576. {
  577. m_bMoveSel = true;
  578. m_SelRect = CRect(m_MouseDown, m_MouseMove);
  579. this->Invalidate();
  580. }
  581. CView::OnMouseMove(nFlags, point);
  582. }
  583. void CTest1View::ZeroArray()
  584. {
  585. for (int i=0; i<ArrayTwo; i++)
  586. for (int j=0; j<ArrayOne; j++)
  587. Databuf[i][j] = 0;
  588. }
  589. UINT CTest1View::ReadFile(LPVOID lp)
  590. {
  591. CTest1View *pThis = (CTest1View*)lp;
  592. pThis->GetFileData(pThis->m_FileName);
  593. return 0L;
  594. }
  595. void CTest1View::OnInitialUpdate() 
  596. {
  597. CView::OnInitialUpdate();
  598. m_pFr = (CMainFrame*)AfxGetApp()->m_pMainWnd;
  599. this->IniOpenGL();
  600. //启动加载数据的线程
  601. // AfxBeginThread(CTest1View::ReadFile,this);
  602. }
  603. //判断当前鼠标是否在客户区中
  604. bool CTest1View::IsMouseInWndRect(CPoint point)
  605. {
  606. bool bInWnd = true;
  607. if ( point.x <= 10 || point.x >= this->m_xRect-10 || point.y <= 10 || point.y >= this->m_yRect-10 )
  608. bInWnd = false;
  609. return bInWnd;
  610. }
  611. GLfloat CTest1View::GetMaxDepth()
  612. {
  613. GLfloat glfMaxDepth = 0.0f;
  614. glfMaxDepth = Databuf[0][0];
  615. for(int i=0; i<ArrayOne; i++)
  616. {
  617. if (Databuf[i][0] >= glfMaxDepth)
  618. {
  619. glfMaxDepth = Databuf[i][0];
  620. }
  621. else
  622. NULL;
  623. }
  624. return glfMaxDepth;
  625. }
  626. GLfloat CTest1View::GetMinDepth()
  627. {
  628. GLfloat glfMinDepth = 0.0f;
  629. glfMinDepth = Databuf[0][0];
  630. for(int i=0; i<ArrayOne; i++)
  631. {
  632. if (Databuf[i][0] <= glfMinDepth)
  633. {
  634. glfMinDepth = Databuf[i][0];
  635. }
  636. else
  637. NULL;
  638. }
  639. return glfMinDepth;
  640. }
  641. void CTest1View::DrawSelArea(CDC *pDC)
  642. {
  643. if (this->m_bMoveSel)
  644. {
  645. if (this->m_SelType == 0)
  646. {
  647. pDC->Draw3dRect(this->m_SelRect,BLUE,BLUE);
  648. //pDC->InvertRect(this->m_SelRect);
  649. }
  650. if (this->m_SelType == 1)
  651. pDC->Ellipse(this->m_SelRect);
  652. }
  653. }
  654. void CTest1View::DrawText()
  655. {
  656. glPushMatrix();
  657. glColor3f(1.0f,1.0f,1.0f);
  658. wglUseFontBitmaps(wglGetCurrentDC(),0,255,100);
  659. glListBase(100);
  660. glRasterPos3f(10.20f+m_Zoom,-0.5f,0.0f);
  661. glCallLists(2,GL_UNSIGNED_BYTE,_T("+x")); 
  662. glRasterPos3f(-0.5,10.2f+m_Zoom,0.0f);
  663. glCallLists(2,GL_UNSIGNED_BYTE,_T("+y")); 
  664. glRasterPos3f(-0.5,0.0f,10.2f+m_Zoom);
  665. glCallLists(2,GL_UNSIGNED_BYTE,_T("+z")); 
  666. glRasterPos3f(0.0,0.0f,0.0f);
  667. glCallLists(6,GL_UNSIGNED_BYTE,_T("Center")); 
  668. glPopMatrix();
  669. }
  670. //画参照立方体
  671. void CTest1View::Draw3DRect()
  672. {
  673. //特别注意该函数
  674. glColor3f(1.0f,1.0f,1.0f);
  675. //加入光照
  676. glEnable (GL_LIGHTING);
  677. glEnable(GL_LIGHT0);
  678. glPushMatrix ();
  679. //设置立方体大小
  680. auxWireCube(13.0+m_Zoom);
  681. //取消光照
  682. if (!m_bLighting)
  683. {
  684. glDisable(GL_LIGHTING);
  685. glDisable(GL_LIGHT0);
  686. }
  687. //将当前矩阵出栈
  688. glPopMatrix ();
  689. }
  690. void CTest1View::OnContextMenu(CWnd* pWnd, CPoint point) 
  691. {
  692. CMenu m_XpMenu;
  693. //电话本
  694. m_XpMenu.LoadMenu(IDR_MYMENU);
  695. CMenu *psub = (CMenu *)m_XpMenu.GetSubMenu(0);
  696. psub->TrackPopupMenu(TPM_LEFTALIGN,point.x,point.y,this);
  697. m_XpMenu.DestroyMenu();
  698. }
  699. //lpRect 代表选定区域
  700. HBITMAP CTest1View::CopySelArearToBitmap(LPRECT lpRect)
  701. {
  702. HDC hScrDC, hMemDC;      
  703. // 屏幕和内存设备描述表
  704. HBITMAP hBitmap, hOldBitmap;   
  705. // 位图句柄
  706. int nX, nY, nX2, nY2;      
  707. // 选定区域坐标
  708. int nWidth, nHeight;      
  709. // 位图宽度和高度
  710. int xScrn, yScrn;         
  711. // 屏幕分辨率
  712. // 确保选定区域不为空矩形
  713. if (IsRectEmpty(lpRect))
  714. return NULL;
  715. //为屏幕创建设备描述表
  716. hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
  717. //为屏幕设备描述表创建兼容的内存设备描述表
  718. hMemDC = CreateCompatibleDC(hScrDC);
  719. // 获得选定区域坐标
  720. nX = lpRect->left;
  721. nY = lpRect->top;
  722. nX2 = lpRect->right;
  723. nY2 = lpRect->bottom;
  724. // 获得屏幕分辨率
  725. xScrn = GetDeviceCaps(hScrDC, HORZRES);
  726. yScrn = GetDeviceCaps(hScrDC, VERTRES);
  727. //确保选定区域是可见的
  728. if (nX < 0)
  729. nX = 0;
  730. if (nY < 0)
  731. nY = 0;
  732. if (nX2 > xScrn)
  733. nX2 = xScrn;
  734. if (nY2 > yScrn)
  735. nY2 = yScrn;
  736. nWidth = (nX2 - nX);
  737. nHeight = (nY2 - nY);
  738. //创建一个与屏幕设备描述表兼容的位图
  739. hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);
  740. //把新位图选到内存设备描述表中
  741. hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
  742. // 把屏幕设备描述表拷贝到内存设备描述表中
  743. BitBlt(hMemDC, 0, 0, nWidth, nHeight,hScrDC, nX, nY, SRCCOPY);
  744. //得到屏幕位图的句柄
  745. hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
  746. //清除 
  747. DeleteDC(hScrDC);
  748. DeleteDC(hMemDC);
  749. // 返回位图句柄
  750. return hBitmap;
  751. }
  752. //将选中区域保存成位图
  753. BOOL CTest1View::SaveBitmapToFile(HBITMAP hBitmap, LPSTR lpFileName)
  754. {
  755. //lpFileName 为位图文件名
  756. HDC hDC;         
  757.     //设备描述表
  758. int iBits;      
  759. //当前显示分辨率下每个像素所占字节数
  760. WORD wBitCount;   
  761.     //位图中每个像素所占字节数
  762. //定义调色板大小, 位图中像素字节大小 ,位图文件大小 , 写入文件字节数
  763. DWORD dwPaletteSize=0, dwBmBitsSize, dwDIBSize, dwWritten;
  764. BITMAP Bitmap;        
  765. //位图属性结构
  766. BITMAPFILEHEADER   bmfHdr;        
  767. //位图文件头结构
  768. BITMAPINFOHEADER   bi;            
  769. //位图信息头结构 
  770. LPBITMAPINFOHEADER lpbi;          
  771. //指向位图信息头结构
  772. HANDLE fh, hDib, hPal,hOldPal=NULL;
  773. //定义文件,分配内存句柄,调色板句柄
  774. //计算位图文件每个像素所占字节数
  775. hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
  776. iBits = GetDeviceCaps(hDC, BITSPIXEL) * 
  777. GetDeviceCaps(hDC, PLANES);
  778. DeleteDC(hDC);
  779. if (iBits <= 1)
  780. wBitCount = 1;
  781. else if (iBits <= 4)
  782. wBitCount = 4;
  783. else if (iBits <= 8)
  784. wBitCount = 8;
  785. else if (iBits <= 24)
  786. wBitCount = 24;
  787. //计算调色板大小
  788. if (wBitCount <= 8)
  789. dwPaletteSize = (1 <<  wBitCount) * sizeof(RGBQUAD);
  790. //设置位图信息头结构
  791. GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
  792. bi.biSize            = sizeof(BITMAPINFOHEADER);
  793. bi.biWidth           = Bitmap.bmWidth;
  794. bi.biHeight          = Bitmap.bmHeight;
  795. bi.biPlanes          = 1;
  796. bi.biBitCount         = wBitCount;
  797. bi.biCompression      = BI_RGB;
  798. bi.biSizeImage        = 0;
  799. bi.biXPelsPerMeter     = 0;
  800. bi.biYPelsPerMeter     = 0;
  801. bi.biClrUsed         = 0;
  802. bi.biClrImportant      = 0;
  803. dwBmBitsSize = ((Bitmap.bmWidth *
  804. wBitCount+31)/32)* 4
  805. *Bitmap.bmHeight ;
  806. //为位图内容分配内存
  807. hDib  = GlobalAlloc(GHND,dwBmBitsSize+
  808. dwPaletteSize+sizeof(BITMAPINFOHEADER));
  809. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
  810. *lpbi = bi;
  811. // 处理调色板   
  812. hPal = GetStockObject(DEFAULT_PALETTE);
  813. if (hPal)
  814. {
  815. hDC  = ::GetDC(NULL);
  816. hOldPal = SelectPalette(hDC, (HPALETTE)hPal, FALSE);
  817. RealizePalette(hDC);
  818. }
  819. // 获取该调色板下新的像素值
  820. GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,
  821. (LPSTR)lpbi + sizeof(BITMAPINFOHEADER) +dwPaletteSize,
  822. (BITMAPINFO *)lpbi, DIB_RGB_COLORS);
  823. //恢复调色板   
  824. if (hOldPal)
  825. {
  826. SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
  827. RealizePalette(hDC);
  828. ::ReleaseDC(NULL, hDC);
  829. }
  830. //创建位图文件    
  831. fh = CreateFile(lpFileName, GENERIC_WRITE, 
  832. 0, NULL, CREATE_ALWAYS,
  833. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  834. if (fh == INVALID_HANDLE_VALUE)
  835. return FALSE;
  836. // 设置位图文件头
  837. bmfHdr.bfType = 0x4D42;  // "BM"
  838. dwDIBSize    = sizeof(BITMAPFILEHEADER) 
  839. + sizeof(BITMAPINFOHEADER)
  840. + dwPaletteSize + dwBmBitsSize;  
  841. bmfHdr.bfSize = dwDIBSize;
  842. bmfHdr.bfReserved1 = 0;
  843. bmfHdr.bfReserved2 = 0;
  844. bmfHdr.bfOffBits = (DWORD)sizeof
  845. (BITMAPFILEHEADER) 
  846. + (DWORD)sizeof(BITMAPINFOHEADER)
  847. + dwPaletteSize;
  848. // 写入位图文件头
  849. WriteFile(fh, (LPSTR)&bmfHdr, sizeof
  850. (BITMAPFILEHEADER), &dwWritten, NULL);
  851. // 写入位图文件其余内容
  852. WriteFile(fh, (LPSTR)lpbi, dwDIBSize, 
  853. &dwWritten, NULL);
  854. //清除   
  855. GlobalUnlock(hDib);
  856. GlobalFree(hDib);
  857. CloseHandle(fh);
  858. return TRUE;
  859. }
  860. void CTest1View::OnKillFocus(CWnd* pNewWnd) 
  861. {
  862. CView::OnKillFocus(pNewWnd);
  863. this->m_bDown = false;
  864. }
  865. GLfloat CTest1View::GetMidXPoint()
  866. {
  867. GLfloat glMid,glMin,glMax;
  868. glMax = glMin = glMid =Databuf[0][1];
  869. for(int i=0; i<ArrayOne; i++)
  870. {
  871. if (Databuf[i][1] > glMax)
  872. glMax = Databuf[i][1];
  873. if (Databuf[i][1] < glMin)
  874. glMin = Databuf[i][1];
  875. }
  876. if (glMax < 0.0f)
  877. glMax = -glMax;
  878. if (glMin > 0.0f)
  879. glMin = -glMin;
  880. return (glMax + glMin)/2;
  881. }
  882. GLfloat CTest1View::GetMidYPoint()
  883. {
  884. GLfloat glMid,glMin,glMax;
  885. glMax = glMin = glMid =Databuf[0][2];
  886. for(int i=0; i<ArrayOne; i++)
  887. {
  888. if (Databuf[i][2] > glMax)
  889. glMax = Databuf[i][2];
  890. if (Databuf[i][2] < glMin)
  891. glMin = Databuf[i][2];
  892. }
  893. if (glMax < 0.0f)
  894. glMax = -glMax;
  895. if (glMin > 0.0f)
  896. glMin = -glMin;
  897. return (glMax + glMin)/2;
  898. }
  899. GLfloat CTest1View::GetMidZPoint()
  900. {
  901. GLfloat glMid,glMin,glMax;
  902. glMax = glMin = glMid =Databuf[0][3];
  903. for(int i=0; i<ArrayOne; i++)
  904. {
  905. if (Databuf[i][3] > glMax)
  906. glMax = Databuf[i][3];
  907. if (Databuf[i][3] < glMin)
  908. glMin = Databuf[i][3];
  909. }
  910. if (glMax < 0.0f)
  911. glMax = -glMax;
  912. if (glMin > 0.0f)
  913. glMin = -glMin;
  914. return (glMax + glMin)/2;
  915. }
  916. bool CTest1View::IsMouseinSelRect(CRect rect,CPoint point)
  917. {
  918. bool bIn = false;
  919. int cx = point.x;
  920. int cy = point.y;
  921. if (cx >= rect.left && cx <= rect.right && cy >= rect.top && cy <= rect.bottom)
  922. bIn = true;
  923. return bIn;
  924. }