1、外部图形的加载、旋转和平移 1、 实验目的和要求 外部图形的的加载、旋转和平移 2、 实验内容 用MFC方法和OpengL知识来实现位图和.cur格式图形文件的的加载、旋转和平移。 3、 实验步骤 1) 程序设计 Camera.cpp 实现照相机模型与变换。 CoordinateAxis.cpp 实现图中的向量绘制和标注。 MFCGL.cpp 实现的功能相当于主函数调用的功能。 MFCGLView.cpp 主干文件,对图形的编辑的具体实现。 2) 程序调试、测试与运行结果分析 (1) X视图 Y视图 Z视图 旋转功能 平移共能 功
2、能选择键,依次为选择、旋转、平移和三种视图。 (2) 功能上实现的感觉还可以,基本上已经达到要求,但由于图形文件是从网上下来的,不是自己编辑设计的,而且也不是cad文件,是没有达到题目要求,Win7不能安装CAD软件,这是我自己考虑不周,实验结果还是比较满意的。 4、 实验总结 此次课程设计,对我的很有挑战。在课上对文件加载这部分知识没有过多的领会,导致我在网上找了很长时间的加载函数。后来网上有了个用MFC加载图形的例子,根据它的截图和关键算法的代码实现,再加上以前对MFC稍微有点了解,知道函数该添加在什么位置,花了将近一个下午的时间将在RES文件夹中的文件进行了加载、旋转和平移,代码看
3、的不是特别懂,有点糊里糊涂,而且可能对MFC了解的也不是特别深,致使我在编译时错误不断,有时甚至达到了115个错误。后来原因只是因为一个符号错了,看来还得再细节上多多注意,还有头一次用MFC实现OpengL方法的编程,感觉还好,最起码有结果出来了。MFC的优点就是框架已经搭建好了,不用在费事去做过多与需求功能无关的事,很多文件都是直接生成的,只需加几个头文件就行了,还有就是添加功能函数。总体讲收获很大,对自己的编程能力又多了一点自信。 5、 附录 res/rc2:包含项目使用的附加资源的脚本文件。 1)MFCGLView.cpp文件代码: // MFCGLView.cpp : impl
4、ementation of the CMFCGLView class
//
#include "stdafx.h"
#include "MFCGL.h"
#include "MainFrm.h"
#include "MFCGLDoc.h"
#include "MFCGLView.h"
#include "CoordinateAxis.h"
#include
5、dif GLfloat ambientLight[] = { 0.3f, 0.3f,0.3f, 1.0f }; GLfloat diffuseLight[] = { 0.7f, 0.7f,0.7f, 1.0f }; GLfloat lightPos[] = {-50.0f, 50.0f,100.0f, 1.0f }; ///////////////////////////////////////////////////////////////////////////// // CMFCGLView IMPLEMENT_DYNCREATE(CMFCGLView, CV
6、iew) BEGIN_MESSAGE_MAP(CMFCGLView, CView) //{{AFX_MSG_MAP(CMFCGLView) ON_WM_CREATE() ON_WM_DESTROY() ON_WM_SIZE() ON_WM_TIMER() ON_WM_ERASEBKGND() ON_COMMAND(C_PAN, OnCameraPan) ON_UPDATE_COMMAND_UI(C_PAN, OnUpdateCameraPan) ON_COMMAND(SELECTMODE, OnSELECTMODE) ON_UPDATE_COMMA
7、ND_UI(SELECTMODE, OnUpdateSELECTMODE) ON_WM_MOUSEMOVE() ON_WM_KEYDOWN() ON_WM_LBUTTONDOWN() ON_WM_RBUTTONDOWN() ON_COMMAND(C_ROTATE, OnSceneRotate) ON_UPDATE_COMMAND_UI(C_ROTATE, OnUpdateSceneRotate) ON_WM_PAINT() ON_COMMAND(ID_ORTHO, OnOrtho) ON_UPDATE_COMMAND_UI(ID_ORTHO, OnUpdat
8、eOrtho) ON_COMMAND(ID_PERSPECTIVE, OnPerspective) ON_UPDATE_COMMAND_UI(ID_PERSPECTIVE, OnUpdatePerspective) ON_COMMAND(ID_X_VIEW, OnXView) ON_COMMAND(ID_Y_VIEW, OnYView) ON_COMMAND(ID_Z_VIEW, OnZView) ON_COMMAND(ID_FREE_VIEW, OnFreeView) ON_UPDATE_COMMAND_UI(ID_X_VIEW, OnUpdateXView)
9、 ON_UPDATE_COMMAND_UI(ID_Y_VIEW, OnUpdateYView) ON_UPDATE_COMMAND_UI(ID_Z_VIEW, OnUpdateZView) ON_UPDATE_COMMAND_UI(ID_FREE_VIEW, OnUpdateFreeView) ON_COMMAND(ID_SHOW_COORDINATE_AXIS, OnShowCoordinateAxis) ON_UPDATE_COMMAND_UI(ID_SHOW_COORDINATE_AXIS, OnUpdateShowCoordinateAxis) ON_COMMAND
10、ID_DRAWMODE_SOLID, OnDrawmodeSolid) ON_UPDATE_COMMAND_UI(ID_DRAWMODE_SOLID, OnUpdateDrawmodeSolid) ON_COMMAND(ID_DRAWMODE_WIRE, OnDrawmodeWire) ON_UPDATE_COMMAND_UI(ID_DRAWMODE_WIRE, OnUpdateDrawmodeWire) ON_WM_SETCURSOR() ON_COMMAND(ID_DRAWMODE_POINTS, OnDrawmodePoints) ON_UPDATE_COMMA
11、ND_UI(ID_DRAWMODE_POINTS, OnUpdateDrawmodePoints) ON_COMMAND(ID_DRAWMODE_SILHOUETTE, OnDrawmodeSilhouette) ON_UPDATE_COMMAND_UI(ID_DRAWMODE_SILHOUETTE, OnUpdateDrawmodeSilhouette) ON_COMMAND(ID_DRAWMODE_ORIENTATION_INSIDE, OnDrawmodeOrientationInside) ON_UPDATE_COMMAND_UI(ID_DRAWMODE_ORIENTA
12、TION_INSIDE, OnUpdateDrawmodeOrientationInside) ON_COMMAND(ID_DRAWMODE_ORIENTATION_OUTSIDE, OnDrawmodeOrientationOutside) ON_UPDATE_COMMAND_UI(ID_DRAWMODE_ORIENTATION_OUTSIDE, OnUpdateDrawmodeOrientationOutside) ON_COMMAND(ID_DRAWMODE_SHADING_FLAT, OnDrawmodeShadingFlat) ON_UPDATE_COMMAND_UI
13、ID_DRAWMODE_SHADING_FLAT, OnUpdateDrawmodeShadingFlat) ON_COMMAND(ID_DRAWMODE_SHADING_NONE, OnDrawmodeShadingNone) ON_UPDATE_COMMAND_UI(ID_DRAWMODE_SHADING_NONE, OnUpdateDrawmodeShadingNone) ON_COMMAND(ID_DRAWMODE_SHADING_SMOOTH, OnDrawmodeShadingSmooth) ON_UPDATE_COMMAND_UI(ID_DRAWMODE_SHA
14、DING_SMOOTH, OnUpdateDrawmodeShadingSmooth) //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) END_MESSAGE_MAP() /////////////
15、//////////////////////////////////////////////////////////////// // CMFCGLView construction/destruction CMFCGLView::CMFCGLView() { // TODO: add construction code here m_pShape = gluNewQuadric(); m_fLineWidth = 0.05; m_hGLContext = NULL; m_GLPixelIndex = 0; m_Action = SEL
16、ECT; m_RotateAxis = AXIS_Z; m_bBuildList = FALSE; m_bOrtho = FALSE; m_ViewMode = FREE_VIEW; m_bShowAxis = TRUE; m_bSelection = FALSE; m_nDrawMode = SOLID; m_nDrawOrient = OUTSIDE; m_nShading = SMOOTH; } CMFCGLView::~CMFCGLView() { gluDeleteQuadric(m_pShape); }
17、 BOOL CMFCGLView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying cs.style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS); return CView::PreCreateWindow(cs); } ///////////////////////////////////////////////////////////////////////////// // CM
18、FCGLView drawing void CMFCGLView::OnDraw(CDC* pDC) { CMFCGLDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here } ///////////////////////////////////////////////////////////////////////////// // CMFCGLView printing BOOL CMFCGLView::OnPreparePri
19、nting(CPrintInfo* pInfo) { // default preparation return DoPreparePrinting(pInfo); } void CMFCGLView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add extra initialization before printing } void CMFCGLView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { //
20、 TODO: add cleanup after printing } ///////////////////////////////////////////////////////////////////////////// // CMFCGLView diagnostics #ifdef _DEBUG void CMFCGLView::AssertValid() const { CView::AssertValid(); } void CMFCGLView::Dump(CDumpContext& dc) const { CView::Dump(dc);
21、 } CMFCGLDoc* CMFCGLView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMFCGLDoc))); return (CMFCGLDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CMFCGLView message handl
22、ers BOOL CMFCGLView::SetWindowPixelFormat(HDC hDC) { PIXELFORMATDESCRIPTOR pixelDesc; pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR); pixelDesc.nVersion = 1; pixelDesc.dwFlags =PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_STEREO_DONTCARE| PFD_DOUBLE
23、BUFFER; pixelDesc.iPixelType = PFD_TYPE_RGBA; pixelDesc.cColorBits = 32; pixelDesc.cRedBits = 8; pixelDesc.cRedShift = 16; pixelDesc.cGreenBits =8; pixelDesc.cGreenShift =8; pixelDesc.cBlueBits = 8; pixelDesc.cBlueShift = 0; pixelDesc.cAlphaBits = 0; pixelDes
24、c.cAlphaShift = 0; pixelDesc.cAccumBits = 64; pixelDesc.cAccumRedBits = 16; pixelDesc.cAccumGreenBits = 16; pixelDesc.cAccumBlueBits = 16; pixelDesc.cAccumAlphaBits = 0; pixelDesc.cDepthBits = 32; pixelDesc.cStencilBits = 8; pixelDesc.cAuxBuffers = 0; pixelDesc.iLayerType =
25、 PFD_MAIN_PLANE; pixelDesc.bReserved = 0; pixelDesc.dwLayerMask = 0; pixelDesc.dwVisibleMask = 0; pixelDesc.dwDamageMask = 0; m_GLPixelIndex = ChoosePixelFormat( hDC, &pixelDesc); if (m_GLPixelIndex==0) { m_GLPixelIndex = 1; if (DescribePixelFormat(hDC, m_GLPixelI
26、ndex, sizeof(PIXELFORMATDESCRIPTOR), &pixelDesc)==0) { return FALSE; } } if (SetPixelFormat( hDC, m_GLPixelIndex, &pixelDesc)==FALSE) { return FALSE; } return TRUE; } int CMFCGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CV
27、iew::OnCreate(lpCreateStruct) == -1) return -1; HWND hWnd = GetSafeHwnd(); HDC hDC = ::GetDC(hWnd); if (SetWindowPixelFormat(hDC)==FALSE) return 0; if (CreateViewGLContext(hDC)==FALSE) return 0; SetTimer(0,100,NULL); return 0; } BOOL CMFCGLView::CreateViewGLC
28、ontext(HDC hDC) { m_hGLContext = wglCreateContext(hDC); if (m_hGLContext == NULL) { return FALSE; } if (wglMakeCurrent(hDC, m_hGLContext)==FALSE) { return FALSE; } return TRUE; } void CMFCGLView::OnDestroy() { if(wglGetCurrentContext()!=NULL) { wglMakeCurre
29、nt(NULL, NULL) ; } if (m_hGLContext!=NULL) { wglDeleteContext(m_hGLContext); m_hGLContext = NULL; } CView::OnDestroy(); } void CMFCGLView::OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); GLsizei width, height; GLdouble aspect; width
30、 cx; height = cy; if (cy==0) aspect = (GLdouble)width; else aspect = (GLdouble)width/(GLdouble)height; m_WHRatio=aspect; glViewport(0, 0, width, height); InitOpenGL(); } void CMFCGLView::OnTimer(UINT nIDEvent) { CView::OnTimer(nIDEvent);
31、 } //override the virtual function to prevent the window redraw the window client BOOL CMFCGLView::OnEraseBkgnd(CDC* pDC) { return FALSE; } void CMFCGLView::OnCameraPan() { m_Action = CAMERA_PAN; m_bSelection = FALSE; } void CMFCGLView::OnUpdateCameraPan(CCmd
32、UI* pCmdUI) { pCmdUI->SetCheck(m_Action==CAMERA_PAN); pCmdUI->Enable(m_ViewMode==FREE_VIEW); } void CMFCGLView::OnSELECTMODE() { m_Action = SELECT; m_bSelection = TRUE; } void CMFCGLView::OnUpdateSELECTMODE(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_Action==SELE
33、CT); pCmdUI->Enable(m_ViewMode==FREE_VIEW); } void CMFCGLView::OnMouseMove(UINT nFlags, CPoint point) { DisplayWorldCoord(point); if(nFlags==MK_LBUTTON) { int rx = point.x-m_OldPoint.x; int ry = point.y-m_OldPoint.y; switch(m_Action) { case CAMER
34、A_PAN: m_Camera.Offset(rx/100.0,-ry/100.0,0); break; case SCENE_ROTATE: m_Scene.RotateRoundAxis(rx/10,m_RotateAxis); break; } m_OldPoint=point; Invalidate(); } if(nFlags==MK_RBUTTON) { int rx=point.x-m_OldPoint.x;
35、 switch(m_Action) { case CAMERA_PAN: m_Camera.Offset(0,0,rx/100.0); HCURSOR hCursor = NULL; CWinApp *cWinApp = AfxGetApp (); hCursor = cWinApp->LoadCursor (IDC_CUR_ZOOM); ::SetCursor(hCursor); break; } m_OldPoint=point; Invalidate(); } //DisplayWorl
36、dCoord(point); CView::OnMouseMove(nFlags, point); } void CMFCGLView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { if(nChar == VK_TAB && m_Action == SCENE_ROTATE) m_RotateAxis = (m_RotateAxis+1) %3; CView::OnKeyDown(nChar, nRepCnt, nFlags); } void CMFCGLView::OnL
37、ButtonDown(UINT nFlags, CPoint point) { m_OldPoint = point; UINT xPos = point.x; WORD yPos = point.y; if(m_bSelection == TRUE) { ProcessSelection(xPos, yPos); } CView::OnLButtonDown(nFlags, point); } void CMFCGLView::OnRButtonDown(UINT nFlags, CPoint point) { m_
38、OldPoint = point; HCURSOR hCursor = NULL; CWinApp *cWinApp = AfxGetApp (); if(m_Action == CAMERA_PAN){ hCursor = cWinApp->LoadCursor (IDC_CUR_ZOOM); ::SetCursor(hCursor); } CView::OnRButtonDown(nFlags, point); } void CMFCGLView::OnSceneRotate() { m_Action
39、 = SCENE_ROTATE; m_bSelection = FALSE; } void CMFCGLView::OnUpdateSceneRotate(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_Action == SCENE_ROTATE); pCmdUI->Enable(m_ViewMode==FREE_VIEW); } void CMFCGLView::OnPaint() { CPaintDC dc(this); glLoadIdentity();
40、 glClearColor(0.0,0.0,0.0,1); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); CheckOrtho(); SetViewMode(); if(m_bShowAxis) { glDisable(GL_DEPTH_TEST); CCoordinateAxis(2,2,2).Display(); glEnable(GL_DEPTH_TEST); } RenderScene(); SwapBuffers(dc
41、m_ps.hdc); } void CMFCGLView::OnOrtho() { if(m_bOrtho) return; else { m_bOrtho=TRUE; Invalidate(); } } void CMFCGLView::OnUpdateOrtho(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_bOrtho); } void CMFCGLView::OnPerspective() { if(!m_bOrtho) return; else {
42、m_bOrtho=FALSE; Invalidate(); } } void CMFCGLView::OnUpdatePerspective(CCmdUI* pCmdUI) { pCmdUI->SetCheck(!m_bOrtho); } void CMFCGLView::InitOpenGL() { glLineWidth(m_fLineWidth); glEnable(GL_LINE_SMOOTH); glFrontFace(GL_CW); glEnable(GL_CULL_FACE); glCullF
43、ace(GL_FRONT); glEnable(GL_LIGHTING); glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight); glLightfv(GL_LIGHT0, GL_POSITION, lightPos); glEnable(GL_LIGHT0); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE); gl
44、DepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); } void CMFCGLView::OnXView() { m_ViewMode = X_VIEW; m_bOrtho = TRUE; Invalidate(); } void CMFCGLView::OnYView() { m_ViewMode = Y_VIEW; m_bOrtho = TRUE; Invalidate(); } void CMFCGLVie
45、w::OnZView() { m_ViewMode = Z_VIEW; m_bOrtho = TRUE; Invalidate(); } void CMFCGLView::OnFreeView() { m_ViewMode = FREE_VIEW; m_bOrtho = FALSE; Invalidate(); } void CMFCGLView::OnUpdateXView(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_ViewMode == X_VIEW); } void
46、 CMFCGLView::OnUpdateYView(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_ViewMode == Y_VIEW); } void CMFCGLView::OnUpdateZView(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_ViewMode == Z_VIEW); } void CMFCGLView::OnUpdateFreeView(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_ViewMode == FREE_VIEW);
47、 } void CMFCGLView::SetViewMode() { glMatrixMode(GL_MODELVIEW); switch(m_ViewMode) { case X_VIEW: gluLookAt(100,0,0,0,0,0,0,0,1); break; case Y_VIEW: gluLookAt(0,100,0,0,0,0,0,0,1); break; case Z_VIEW: gluLookAt(0,0,100,0,0,0,0,1,0); break;
48、 case FREE_VIEW: m_Camera.Apply(); gluLookAt(5,5,2,0,0,0,0,0,1); m_Scene.Apply(); break; } } void CMFCGLView::CheckOrtho() { if(!m_bOrtho) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(35,m_WHRatio,1,1000); glMa
49、trixMode(GL_MODELVIEW); } else { glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-3*m_WHRatio,3*m_WHRatio,-3,3,-1000,1000); glMatrixMode(GL_MODELVIEW); } } void CMFCGLView::OnShowCoordinateAxis() { m_bShowAxis =! m_bShowAxis; Invalidate(); } void CMFCGLView::O
50、nUpdateShowCoordinateAxis(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_bShowAxis); } void CMFCGLView::OnDrawmodeSolid() { // TODO: Add your command handler code here m_nDrawMode = SOLID; InvalidateRect(NULL); } void CMFCGLView::OnUpdateDrawmodeSolid(CCmdUI* pCmdUI) { // TODO: A






