基于对话框的Opengl框架

来源:互联网 发布:c语言期末考试题库 编辑:程序博客网 时间:2024/06/10 04:17

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

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

2、配置opengl环境

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


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

////////////opengl头文件/////////////////////#include "gl\GLUT.H"#include "gl\GLAUX.H"#include <stdio.h>#include <math.h>

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

4、添加消息相应函数

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

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

public:HGLRC m_hRC;//着色描述表CDC *m_pDC;//设备描述表BOOL InitOpengl();//初始化openglBOOL SetupPixelFormat();//设置图片控件的像素格式void RenderScene();//绘制图像
6、初始化opengl

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

// TODO: 在此添加额外的初始化代码InitOpengl();//初始化openglreturn TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
对应的InitOpengl()代码如下:

BOOL CMFC_DlgDlg::InitOpengl(){//获取图片控件DCm_pDC=new CClientDC(GetDlgItem(IDC_PIC));if(m_pDC==NULL)return FALSE;//设置图片控件像素if (!SetupPixelFormat())return FALSE;//创建兼容RCm_hRC=wglCreateContext(m_pDC->GetSafeHdc());if (m_hRC==0){return FALSE;}//激活RCif (wglMakeCurrent(m_pDC->GetSafeHdc(),m_hRC)==FALSE){return FALSE;}//设置投影模式GLdouble aspect_ratio;GLsizei width,height;CRect rect;CWnd *pWnd=NULL;pWnd=GetDlgItem(IDC_PIC);pWnd->GetClientRect(rect);width=rect.right-rect.left;height=rect.bottom-rect.top;glViewport(0,0,width,height);aspect_ratio=(GLdouble)width/(GLdouble)height;glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(45.0f,aspect_ratio,0.1,200.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();glClearColor(0.0f,0.0f,0.0f,0.0f);glClearDepth(1.0f);glEnable(GL_DEPTH_TEST);return TRUE;}
7、在上述函数中调用了像素初始化函数SetupPixelFormat()对picture控件的像素进行初始化,其代码如下:

BOOL CMFC_DlgDlg::SetupPixelFormat(){static 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)//设置picture控件的像素格式{return FALSE;}return TRUE;}
8、通过上面两步,就完成了初始化,下面开始绘图。为了保证图形在重绘时仍然存在,在对话框的OnPaint()函数中通过调用RenderScene()实现绘图操作,将代码添加到else块中

else{RenderScene();//向缓冲区绘图SwapBuffers(m_pDC->GetSafeHdc());//交换缓冲区CDialogEx::OnPaint();}
其中,RenderScene()代码如下:

void CMFC_DlgDlg::RenderScene(){glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);glLoadIdentity();glTranslatef(0.0f,0.0f,-5.0f);glBegin(GL_TRIANGLES);glColor3f(1.0f,0.0f,0.0f);glVertex3f(0.0f,1.0f,1.0f);glColor3f(0.0f,1.0f,0.0f);glVertex3f(-1.5f,-1.0f,0.0f);glColor3f(0.0f,0.0f,1.0f);glVertex3f(1.5f,-1.0f,0.0f);glEnd();}
这里为了简单,只画了一个三角形。

9、释放资源

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

void CMFC_DlgDlg::OnDestroy(){CDialogEx::OnDestroy();// TODO: 在此处添加消息处理程序代码if (wglMakeCurrent(NULL,NULL)==FALSE)//释放RC{MessageBox("无法释放RC");}if (wglDeleteContext(m_hRC)==FALSE)//删除RC{MessageBox("无法删除RC");}if (m_pDC){delete m_pDC;}m_pDC=NULL;}

运行效果如下:


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


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


参考: MFC单文档框架下的opengl

     Nehe中文教程

原创粉丝点击