zoukankan      html  css  js  c++  java
  • 基于对话框的Opengl框架

    转自:http://blog.csdn.net/longxiaoshi/article/details/8238933
     
     分类:
     

    这里,我主要是利用opengl在一个picture控件中绘图,绘制的是一个静态图片,如果想实现动画,可以利用ontimer函数实现。编译器为vs2010。

    1、首先创建一个基于对话框的MFC程序,我这里命名为MFC_Dlg。

    2、配置opengl环境

    首先添加链接库,在菜单栏 项目->属性->配置属性->链接器->输入->附加依赖项,添加glut32.lib,glaux.lib。如图:

    然后,在stdafx.h里面添加opengl的头文件,如下:

    [cpp] view plain copy
     
    1. ////////////opengl头文件/////////////////////  
    2. #include "glGLUT.H"  
    3. #include "glGLAUX.H"  
    4. #include <stdio.h>  
    5. #include <math.h>  

    3、为对话框添加一个picture控件,ID为IDC_PIC。

    4、添加消息相应函数

    这里主要是为了在窗口销毁时释放DC和RC资源,为对话框添加了WM_DESTORY消息的相应函数。

    5、在对话框头文件中添加相应的成员函数以及数据成员,如下:

    [cpp] view plain copy
     
    1. public:  
    2.     HGLRC m_hRC;                    //着色描述表  
    3.     CDC *m_pDC;                     //设备描述表  
    4.     BOOL InitOpengl();              //初始化opengl  
    5.     BOOL SetupPixelFormat();        //设置图片控件的像素格式  
    6.     void RenderScene();             //绘制图像  
    6、初始化opengl

    在对话框的OnInitDialog()中调用了InitOpengl()对opengl进行初始化

    [cpp] view plain copy
     
    1. // TODO: 在此添加额外的初始化代码  
    2.   
    3. InitOpengl();       //初始化opengl  
    4.   
    5. return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE  
    对应的InitOpengl()代码如下:
    [cpp] view plain copy
     
    1. BOOL CMFC_DlgDlg::InitOpengl()  
    2. {  
    3.     //获取图片控件DC  
    4.     m_pDC=new CClientDC(GetDlgItem(IDC_PIC));  
    5.     if(m_pDC==NULL)  
    6.         return FALSE;  
    7.     //设置图片控件像素  
    8.     if (!SetupPixelFormat())  
    9.         return FALSE;  
    10.     //创建兼容RC  
    11.     m_hRC=wglCreateContext(m_pDC->GetSafeHdc());  
    12.     if (m_hRC==0)  
    13.     {  
    14.         return FALSE;  
    15.     }  
    16.     //激活RC  
    17.     if (wglMakeCurrent(m_pDC->GetSafeHdc(),m_hRC)==FALSE)  
    18.     {  
    19.         return FALSE;  
    20.     }  
    21.   
    22.     //设置投影模式  
    23.     GLdouble aspect_ratio;  
    24.     GLsizei width,height;  
    25.     CRect rect;  
    26.     CWnd *pWnd=NULL;  
    27.     pWnd=GetDlgItem(IDC_PIC);  
    28.     pWnd->GetClientRect(rect);  
    29.     width=rect.right-rect.left;  
    30.     height=rect.bottom-rect.top;  
    31.   
    32.     glViewport(0,0,width,height);  
    33.     aspect_ratio=(GLdouble)width/(GLdouble)height;  
    34.     glMatrixMode(GL_PROJECTION);  
    35.     glLoadIdentity();  
    36.     gluPerspective(45.0f,aspect_ratio,0.1,200.0);  
    37.     glMatrixMode(GL_MODELVIEW);  
    38.     glLoadIdentity();  
    39.   
    40.     glClearColor(0.0f,0.0f,0.0f,0.0f);  
    41.     glClearDepth(1.0f);  
    42.     glEnable(GL_DEPTH_TEST);  
    43.   
    44.     return TRUE;  
    45. }  
    7、在上述函数中调用了像素初始化函数SetupPixelFormat()对picture控件的像素进行初始化,其代码如下:
    [cpp] view plain copy
     
    1. BOOL CMFC_DlgDlg::SetupPixelFormat()  
    2. {  
    3.     static PIXELFORMATDESCRIPTOR pfd=  
    4.     {  
    5.         sizeof(PIXELFORMATDESCRIPTOR),  
    6.         1,  
    7.         PFD_DRAW_TO_WINDOW|  
    8.         PFD_SUPPORT_OPENGL|  
    9.         PFD_DOUBLEBUFFER,  
    10.         PFD_TYPE_RGBA,  
    11.         24,  
    12.         0,0,0,0,0,0,  
    13.         0,  
    14.         0,  
    15.         0,  
    16.         0,0,0,0,  
    17.         16,  
    18.         0,  
    19.         0,  
    20.         PFD_MAIN_PLANE,  
    21.         0,  
    22.         0,0,0  
    23.     };  
    24.     int m_nPixelFormat=ChoosePixelFormat(m_pDC->GetSafeHdc(),&pfd);//在窗口找查找该像素格式  
    25.     if (m_nPixelFormat==0)  
    26.     {  
    27.         return FALSE;  
    28.     }  
    29.     if (SetPixelFormat(m_pDC->GetSafeHdc(),m_nPixelFormat,&pfd)==FALSE)//设置picture控件的像素格式  
    30.     {  
    31.         return FALSE;  
    32.     }  
    33.     return TRUE;  
    34. }  
    8、通过上面两步,就完成了初始化,下面开始绘图。为了保证图形在重绘时仍然存在,在对话框的OnPaint()函数中通过调用RenderScene()实现绘图操作,将代码添加到else块中
    [cpp] view plain copy
     
    1. else  
    2. {  
    3.     RenderScene();                          //向缓冲区绘图  
    4.     SwapBuffers(m_pDC->GetSafeHdc());        //交换缓冲区  
    5.   
    6.     CDialogEx::OnPaint();  
    7. }  
    其中,RenderScene()代码如下:
    [cpp] view plain copy
     
    1. void CMFC_DlgDlg::RenderScene()  
    2. {  
    3.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);  
    4.     glLoadIdentity();  
    5.       
    6.     glTranslatef(0.0f,0.0f,-5.0f);  
    7.     glBegin(GL_TRIANGLES);  
    8.         glColor3f(1.0f,0.0f,0.0f);  
    9.         glVertex3f(0.0f,1.0f,1.0f);  
    10.         glColor3f(0.0f,1.0f,0.0f);  
    11.         glVertex3f(-1.5f,-1.0f,0.0f);  
    12.         glColor3f(0.0f,0.0f,1.0f);  
    13.         glVertex3f(1.5f,-1.0f,0.0f);  
    14.     glEnd();  
    15. }  
    这里为了简单,只画了一个三角形。

    9、释放资源

    在写程序,如果忘记释放DC和RC,将会导致内存泄露,随着程序运行次数的增多,内存占有量越来越大。这里在WM_DESTORY的消息响应函数中释放资源,

    [cpp] view plain copy
     
    1. void CMFC_DlgDlg::OnDestroy()  
    2. {  
    3.     CDialogEx::OnDestroy();  
    4.   
    5.     // TODO: 在此处添加消息处理程序代码  
    6.     if (wglMakeCurrent(NULL,NULL)==FALSE)       //释放RC  
    7.     {  
    8.         MessageBox("无法释放RC");  
    9.     }  
    10.     if (wglDeleteContext(m_hRC)==FALSE)         //删除RC  
    11.     {  
    12.         MessageBox("无法删除RC");  
    13.     }  
    14.     if (m_pDC)  
    15.     {  
    16.         delete m_pDC;  
    17.     }  
    18.     m_pDC=NULL;  
    19. }  

    运行效果如下:

    到此,整个框架就建立起来了,其他的绘图操作都可以在RenderScene()中实现。如果想实现动画效果,只需要设置一个定时器,并在WM_TIMER消息响应函数中改变图形位置并调用RenderScene()即可,并且在OnDestroy中killtimer。

    我也是初学者,有什么不对,大家请指正!

  • 相关阅读:
    burpsuite-小结
    docker化安装apollo
    Linux Shell基础篇——变量
    Linux 用户篇——用户管理命令之id、whoami、su、chage
    Linux 用户篇——用户管理命令之useradd、passwd、userdel、usermod
    Linux 用户篇——用户管理的配置文件
    Linux 基础——常用的Linux网络命令
    Linux 基础——关机重启命令shutdown、reboot等
    Linux 基础——文件搜索命令find
    Linux 基础——权限管理命令chown、chgrp
  • 原文地址:https://www.cnblogs.com/hjlweilong/p/5672245.html
Copyright © 2011-2022 走看看