• MFC下的OpenGL


    序:因为要做个2d地图编辑器,决定采用MFC,但是GDI不是很熟,google下终于完成基本MFC下的OpenGL

    1.首先建个MFC单文档

    2.加入外部库:opengl32.lib glu32.lib    在XXView.cpp加入头文件 gl.h, glu.h

    3.在XXView.h加入如下代码:  

    protected:
      CDC    *m_pDC;
      HGLRC  m_hRC;
    protected:
      BOOL InitOpenGL();             # 初始化opengl
      BOOL SetPixelFormat();       # 设置像素格式
      void   RenderScene();          # 绘制
    

    4.首先重载OnCreate消息

    int CXXView::OnCreate(LPCREATESTRUCT lpCreateStrcut)
    {
      if (CView::OnCreate(lpCreateStruct) == -1)
        return -1;
    
      // 初始化OpenGL
      InitOpenGL();
     
      return 0;
    }
    

    5.现在完成初始化OpenGL的代码

    BOOL CXXView::InitializeOpenGL()
    {
            // 创建设备上下文
    	m_pDC = new CClientDC(this);
    	if (m_pDC == NULL)
    	{
    		MessageBox("错误: 无法创建设备上下文");
    		return FALSE;
    	}
    
            // 设置像素格式
    	if (!SetPixelFormat())
    		return FALSE;
    
            // 创建绘制环境
    	m_hRC = wglCreateContext(m_pDC->GetSafeHdc());
    	if (m_hRC == NULL)
    	{
    		MessageBox("错误: 无法创建绘制环境");
    		return FALSE;
    	}
    
    	if (wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC) == FALSE)
    	{
    		MessageBox("错误: 无法作为当前RC");
    		return FALSE;
    	}
    
    	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    	glClearDepth(1.0f);
    	glEnable(GL_DEPTH_TEST);
    
    	return TRUE;
    }
    

    6. 如上5中提到的设置像素格式

    BOOL CXXView::SetPixelFormat()
    {
    	//定义窗口的像素格式
    	PIXELFORMATDESCRIPTOR pfd=
    	{
    		sizeof(PIXELFORMATDESCRIPTOR),
    		1,
    		PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
    		PFD_DOUBLEBUFFER|PFD_TYPE_RGBA,
    		24,
    		0,0,0,0,0,0,
    		0,
    		0,
    		0,
    		0,0,0,0,
    		16,
    		0,
    		0,
    		PFD_MAIN_PLANE,
    		0,
    		0,0,0
    	};
    
    	int m_nPixelFormat = ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd);
    	if (m_nPixelFormat == 0)
    	{
    		return FALSE;
    	}
    
    	if (SetPixelFormat(m_pDC->GetSafeHdc(), m_nPixelFormat, &pfd) == FALSE)
    	{
    		return FALSE;
    	}
    
    	return TRUE;
    }
    

    7.当然是视图,并且包括窗口改变时重新设置视图

    void CXXView::OnSize(UINT nType, int cx, int cy)
    {
    	CView::OnSize(nType, cx, cy);
    
    	// TODO: 在此处添加消息处理程序代码
    	if ( 0 >= cx || 0 >= cy)
    		return;
    
    	glViewport(0, 0, cx, cy);
    	GLdouble aspect_ratio = (GLdouble)cx / (GLdouble)cy;
    	
    	glMatrixMode(GL_PROJECTION);
    	glLoadIdentity();
    	gluPerspective(45.0f, aspect_ratio, 0.01f, 200.0f);
    	glMatrixMode(GL_MODELVIEW);
    	glLoadIdentity();
    }
    

    8.既然基本都完成,我们在哪里绘制我们图像呢?--》OnDraw

    void CXXView::OnDraw(CDC* pDC)
    {
    	CMfcOpenglDoc* pDoc = GetDocument();
    	ASSERT_VALID(pDoc);
    	if (!pDoc)
    		return;
    
    	// TODO: 在此处为本机数据添加绘制代码
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    	// 我们绘制图像的代码就放在这里
            RenderScene();
    	glFinish();
    	SwapBuffers(pDC->GetSafeHdc());
    }
    

    9.开始绘制图像,这里就绘制一个方块

    void CXXView::RenderScene( GLvoid )
    {
    	glLoadIdentity();  
    	glTranslatef(0.0f, 0.0f, -6.0f);
    	glBegin(GL_TRIANGLES);                    
    	glBegin(GL_QUADS);                            //  绘制正方形
    	   glColor3f(255.0f,0.0f,0.0f);
    	   glVertex3f(-1.0f, 1.0f, 0.0f);                    // 左上
    	   glColor3f(0.0f,255.0f,0.0f);
    	   glVertex3f( 1.0f, 1.0f, 0.0f);                    // 右上
    	   glColor3f(0.0f,0.0f,255.0f);
    	   lVertex3f( 1.0f,-1.0f, 0.0f);                      // 左下
    	   glColor3f(255.255f,255.0f,255.0f);
    	   glVertex3f(-1.0f,-1.0f, 0.0f);                    // 右下
    	glEnd();                              
    }
    

    10.退出程序的时候记得要销毁创建的DC, RC

    void CXXView::OnDestroy()
    {
    	CView::OnDestroy();
    
    	// TODO: 在此处添加消息处理程序代码
    	if(wglGetCurrentContext()!=NULL)
    		wglMakeCurrent(0, 0);
    	if(m_hRC != NULL)
    		wglDeleteContext(m_hRC);
    	if (m_pDC)
            {
    		delete m_pDC;
    	        m_pDC = NULL;
            }
    }
    

    如果没有问题,你将看到如下的结果:

  • 相关阅读:
    Vue 2.0学习(三)指令与事件
    Vue 2.0学习(二)数据绑定
    Vue 2.0学习(一)简介
    大数据入门学习(一):初识大数据
    Knockout.js(四):自定义绑定
    03 Python基础
    02 测试环境的搭建
    01 自动化测试基础
    第29章 项目10:DIY街机游戏
    第27章 项目8:使用XML-RPC进行文件共享
  • 原文地址:https://www.cnblogs.com/shadow21/p/2004112.html
Copyright © 2020-2023  润新知