建立一个SDI 的MFC工程,然后按freeglut 在mfc 下的编译_leon_zeng0的博客-CSDN博客
一文设置好include lib 路径
在view 中建立这2个函数:
// Standard OpenGL Init Stuff BOOL CmfcOpenglDemoView::SetupPixelFormat() { static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd 1, // version number PFD_DRAW_TO_WINDOW | // support window PFD_SUPPORT_OPENGL | // support OpenGL PFD_DOUBLEBUFFER, // double buffered PFD_TYPE_RGBA, // RGBA type 24, // 24-bit color depth 0, 0, 0, 0, 0, 0, // color bits ignored 0, // no alpha buffer 0, // shift bit ignored 0, // no accumulation buffer 0, 0, 0, 0, // accumulation bits ignored 16, // 16-bit z-buffer 0, // no stencil buffer 0, // no auxiliary buffer PFD_MAIN_PLANE, // main layer 0, // reserved 0, 0, 0 // layer masks ignored }; int m_nPixelFormat = ::ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd); if (m_nPixelFormat == 0) return FALSE; return ::SetPixelFormat(m_pDC->GetSafeHdc(), m_nPixelFormat, &pfd); } BOOL CmfcOpenglDemoView::InitOpenGL() { TRACE(L"InitOpenGL()\n"); //Get a DC for the Client Area m_pDC = new CClientDC(this); //Failure to Get DC if (m_pDC == NULL) return FALSE; if (!SetupPixelFormat()) return FALSE; //Create Rendering Context m_hRC = ::wglCreateContext(m_pDC->GetSafeHdc()); //Failure to Create Rendering Context if (m_hRC == 0) return FALSE; //Make the RC Current if (::wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC) == FALSE) return FALSE; // Usual OpenGL stuff glClearColor(0.0f, 0.0f, 0.3f, 0.0f); glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); //glDisable( GL_DEPTH_TEST ); //glEnable( GL_TEXTURE_2D ); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // glDepthMask(GL_FALSE); glLineWidth(1.0f); glPointSize(1.0f); // for test m_RenderScene = render; return TRUE; } void CmfcOpenglDemoView::RenderScene() { if (m_RenderScene != NULL) m_RenderScene((CmfcOpenglDemoDoc*)(GetDocument())); else glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); }利用class wizard 建立几个message:
OnCreate(LPCREATESTRUCT lpCreateStruct)
OnDestroy()
OnSize(UINT nType, int cx, int cy)
OnEraseBkgnd(CDC* pDC)
int CmfcOpenglDemoView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; // TODO: Add your specialized creation code here if (!InitOpenGL()) { MessageBox(L"Error setting up OpenGL!", L"Init Error!", MB_OK | MB_ICONERROR); return -1; } COLORREF color = ::GetSysColor(COLOR_3DFACE); glClearColor(0.0, 0, 0.25, 1.0); glPolygonMode(GL_FRONT, GL_FILL); glPolygonMode(GL_BACK, GL_FILL); glEnable(GL_DEPTH_TEST); // Antialiasing glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glLineWidth(1.0); return 0; } void CmfcOpenglDemoView::OnDestroy() { CView::OnDestroy(); // TODO: Add your message handler code here wglMakeCurrent(0, 0); wglDeleteContext(m_hRC); if (m_pDC) { delete m_pDC; } m_pDC = NULL; } void CmfcOpenglDemoView::OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); // TODO: Add your message handler code here Resize(cx,cy); RenderScene();// OnPaint(); } BOOL CmfcOpenglDemoView::OnEraseBkgnd(CDC* pDC) { // TODO: Add your message handler code here and/or call default TRACE("COpem:OnEraseBkgnd--\n"); return CView::OnEraseBkgnd(pDC); } void CmfcOpenglDemoView::Resize(int cx,int cy) { // TODO: Add your implementation code here. GLsizei width, height; GLdouble aspect; width = cx; height = cy; if (cy == 0) aspect = (GLdouble)width; else aspect = (GLdouble)width / (GLdouble)height; glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-1.0f,1.0,-1.0f,1.0f); //glOrtho(-4.0 * aspect - pDoc->m_transX, 4.0 * aspect - pDoc->m_transX, -4 - pDoc->m_transY, 4 - pDoc->m_transY, -10, 10);//aspect=cx/cy glMatrixMode(GL_MODELVIEW); //glMatrixMode( GL_PROJECTION ); }Resize 可以参考下面代码,设置立体图,上面代码只是正面的平面图。
width = m_sizeCx; height = m_sizeCy; if(m_sizeCy==0) aspect = (GLdouble)width; else aspect = (GLdouble)width/(GLdouble)height; glViewport(0,0,width,height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(pDoc->m_ViewSelect==0) gluPerspective(45,aspect,1,100.0); else //gluOrtho2D(0.0f,aspect,0.0f,1.0f); glOrtho(-4.0*aspect-pDoc->m_transX, 4.0*aspect-pDoc->m_transX, -4-pDoc->m_transY,4-pDoc->m_transY, -10, 10);//aspect=cx/cy glMatrixMode(GL_MODELVIEW);glOtho2D 参看
https://registry.khronos.org/OpenGL-Refpages/gl2.1/xhtml/glOrtho.xml C Specification void glOrtho(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top,GLdouble nearVal,GLdouble farVal);Parametersleft, right
Specify the coordinates for the left and right vertical clipping planes.
bottom, top
Specify the coordinates for the bottom and top horizontal clipping planes.
nearVal, farVal
Specify the distances to the nearer and farther depth clipping planes. These values are negative if the plane is to be behind the viewer.
DescriptionglOrtho describes a transformation that produces a parallel projection. The current matrix (see glMatrixMode) is multiplied by this matrix and the result replaces the current matrix, as if glMultMatrix were called with the following matrix as its argument:
2right-left00��02top-bottom0��00-2farVal-nearVal��0001
where
��=-right+leftright-left
��=-top+bottomtop-bottom
��=-farVal+nearValfarVal-nearVal
Typically, the matrix mode is GL_PROJECTION, and leftbottom-nearVal and righttop-nearVal specify the points on the near clipping plane that are mapped to the lower left and upper right corners of the window, respectively, assuming that the eye is located at (0, 0, 0). -farVal specifies the location of the far clipping plane. Both nearVal and farVal can be either positive or negative.
Use glPushMatrix and glPopMatrix to save and restore the current matrix stack.
ErrorsGL_INVALID_VALUE is generated if left = right, or bottom = top, or near = far.
GL_INVALID_OPERATION is generated if glOrtho is executed between the execution of glBegin and the corresponding execution of glEnd.
在.h 文件中加这几个函数
void SetRenderFunc(void (*func) (CmfcOpenglDemoDoc*)) { m_RenderScene = func; } void RenderScene(); // Each viewport uses its own context // so we need to make sure the correct // context is set whenever we make an // OpenGL command. void SetContext() { wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC); } void SwapGLBuffers() { SwapBuffers(m_pDC->GetSafeHdc()); }添加一个画图函数,不是类里的,独立的
void render(CmfcOpenglDemoDoc* pdoc) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBegin(GL_TRIANGLE_STRIP); glColor3f(0.0f, 0.5f, 0.0f); glVertex2f(0.0f, -0.0f); glVertex2f(0.0f, 0.3f); glVertex2f(0.4f, 0.0f); glEnd(); }在init里有这一句:
m_RenderScene = render;在.h 文件中有:
// Attributes public: CmfcOpenglDemoDoc* GetDocument() const; //------------------ void (*m_RenderScene) (CmfcOpenglDemoDoc* doc); // void function pointer to the rendering // function. Used to change to easily // change what a viewport displays. protected: HGLRC m_hRC; //Rendering Context CDC* m_pDC; //Device Context // Operations public: // OpenGL init stuff BOOL SetupPixelFormat(); BOOL InitOpenGL();这样就构造了一个基本的mfc 下的opengl 工程