VS2012 +MFC+ OPenGL环境搭建

来源:互联网 发布:淘宝哪里能买到真蜂蜜 编辑:程序博客网 时间:2024/05/21 17:11

这里以MFC单文档程序为例。框架的代码是基于NEHE的OPenGL教程的,应该放在负责视图的View.cpp中,笔者的项目名叫迷宫,故类名为C迷宫View,下面是主要步骤:

一. 在MFC中的View.cpp中添加函数BOOL SetupPixelFormat(void)来设置像素格式:

BOOL C迷宫View::SetupPixelFormat(void){static PIXELFORMATDESCRIPTOR pfd = {sizeof(PIXELFORMATDESCRIPTOR),  // pfd结构的大小 1,                              // 版本号 PFD_DRAW_TO_WINDOW |            // 支持在窗口中绘图 PFD_SUPPORT_OPENGL |            // 支持 OpenGL PFD_DOUBLEBUFFER,               // 双缓存模式 PFD_TYPE_RGBA,                  // RGBA 颜色模式 24,                             // 24 位颜色深度 0, 0, 0, 0, 0, 0,               // 忽略颜色位 0,                              // 没有非透明度缓存 0,                              // 忽略移位位 0,                              // 无累计缓存 0, 0, 0, 0,                     // 忽略累计位 32,                             // 32 位深度缓存     0,                              // 无模板缓存 0,                              // 无辅助缓存 PFD_MAIN_PLANE,                 // 主层 0,                              // 保留 0, 0, 0                         // 忽略层,可见性和损毁掩模 };int pixelFormat;// 为设备描述表得到最匹配的像素格式 if((pixelFormat = ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd)) == 0){MessageBox( _T("ChoosePixelFormat failed") );return FALSE;}// 设置最匹配的像素格式为当前的像素格式 if(SetPixelFormat(m_pDC->GetSafeHdc(), pixelFormat, &pfd) == FALSE){MessageBox( _T("SetPixelFormat failed") );return FALSE;}return TRUE;}

二.添加函数BOOL InitializeOpenGL(void)函数初始化OpenGL环境,InitializeOpenGL()中调用了SetupPixelFormat():

BOOL C迷宫View::InitializeOpenGL(void){PIXELFORMATDESCRIPTOR pfd;int n;m_pDC=new CClientDC(this);ASSERT(m_pDC != NULL);// 设置当前的绘图像素格式if(!SetupPixelFormat()){return FALSE;}n=::GetPixelFormat(m_pDC->GetSafeHdc());::DescribePixelFormat(m_pDC->GetSafeHdc(), n,sizeof(pfd),&pfd);// 创建绘图描述表m_hRC=wglCreateContext(m_pDC->GetSafeHdc());if(m_hRC == NULL){MessageBox( _T("创建RC失败") );return FALSE;}// 使绘图描述表为当前调用现程的当前绘图描述表if( wglMakeCurrent(m_pDC->GetSafeHdc(),m_hRC) == FALSE){MessageBox( _T("使绘图描述表为当前调用现程的当前绘图描述表失败") );return FALSE;}if (!LoadGLTextures())// 调用纹理载入子例程{return FALSE;// 如果未能载入,返回FALSE}glEnable(GL_TEXTURE_2D);// 启用纹理映射glShadeModel(GL_SMOOTH);// 启用阴影平滑glClearColor(0.0f, 0.0f, 0.0f, 0.0f);// 黑色背景glClearDepth(1.0f);// 设置深度缓存glEnable(GL_DEPTH_TEST);// 启用深度测试glDepthFunc(GL_LEQUAL);// 所作深度测试的类型glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);// 告诉系统对透视进行修正return TRUE;}

三.重载MFC中的WM_CRATE消息响应函数int OnCreate(LPCREATESTRUCT lpCreateStruct):

int C迷宫View::OnCreate(LPCREATESTRUCT lpCreateStruct){if (CView::OnCreate(lpCreateStruct) == -1)return -1;// TODO:  在此添加您专用的创建代码InitializeOpenGL(); //初始化OpenGL环境return 0;}


四.重载MFC中的WM_SIZE消息响应函数void OnSize(UINTnType,intcx, int cy),设置显示尺寸:
void C迷宫View::OnSize(UINT nType, int cx, int cy){CView::OnSize(nType, cx, cy);// TODO: 在此处添加消息处理程序代码m_width = cx;    //m_width为在C迷宫View类中添加的表示视口宽度的成员变量  m_height = cy;  //m_height为在C迷宫View类中添加的表示视口高度的成员变量  if (m_height==0)// 防止被零除{m_height=1;// 将Height设为1}glViewport(0, 0, m_width, m_height);// 重置当前的视口glMatrixMode(GL_PROJECTION);// 选择投影矩阵glLoadIdentity();// 重置投影矩阵// 设置视口的大小gluPerspective(45.0f,(GLfloat)m_width/(GLfloat)m_height,0.1f,200.0f);glMatrixMode(GL_MODELVIEW);// 选择模型观察矩阵glLoadIdentity();// 重置模型观察矩阵 }


五.添加void RenderScene(void)作为绘图主函数,绘制场景的代码都写在这里,之后重载MFC中的WM_TIMER消息响应函数void OnTimer(UINT_PTRnIDEvent)实时刷新画面:

void C迷宫View::OnTimer(UINT_PTR nIDEvent){// TODO: 在此添加消息处理程序代码和/或调用默认值RenderScene();   //重新绘制CView::OnTimer(nIDEvent);}

在需要开始OpenGL显示时开启定时器即可:SetTimer(1,1,NULL);


六.人机交互代码需要重载MFC的WM_KEYDOWN消息响应函数void OnKeyDown(UINTnChar,UINTnRepCnt,UINTnFlags)函数,在里边分按键处理,例如:

void C迷宫View::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags){// TODO: 在此添加消息处理程序代码和/或调用默认值switch(nChar)     //对按下的符号进行判断{//上方向键处理case VK_UP:{   }//下方向键处理case VK_DOWN:{ }//左方向键处理case VK_LEFT:{ }//右方向键处理case VK_RIGHT:{  }//PageUp键处理case VK_PRIOR:{  }//PageDown键处理case VK_NEXT:{ }}}


七.重载MFC的voidC迷宫View::OnDestroy()作为窗口销毁后的后续处理:

oid C迷宫View::OnDestroy(){CView::OnDestroy();// TODO: 在此处添加消息处理程序代码if (m_hRC)// 我们拥有OpenGL渲染描述表吗?{if (!wglMakeCurrent(NULL,NULL))// 我们能否释放DC和RC描述表?{MessageBox(NULL,_T("释放DC或RC失败。"));}if (!wglDeleteContext(m_hRC))// 我们能否删除RC?{MessageBox(NULL,_T("释放RC失败。"));}m_hRC=NULL;// 将RC设为 NULL}if (m_pDC && !ReleaseDC(m_pDC))// 我们能否释放 DC?{MessageBox(NULL,_T("释放DC失败。"));m_pDC=NULL;// 将 DC 设为 NULL}KillTimer(1);                       //关闭定时器}

注:在VS2012中,添加MFC消息响应函数十分方便,只需点击项目-》类向导,点击对话框中间的消息,选择添加到View类并选择消息添加处理程序即可,如图:






0 0
原创粉丝点击