MFC搭建OpenGL框架示例

来源:互联网 发布:mysql 外键 编辑:程序博客网 时间:2024/06/11 03:00

本文以SDI文档结构为例,列出绘制OpenGL图形的关键步骤;

(1)在单文档窗口的创建过程中设置好显示的像素格式,并按OpengL的要求设置好窗口的属性和风格

(2)获得Windows设备描述表CDC的成员变量,然后将其与OpengL的绘制描述表RC联系起来

(3)调用OpenGL命令进行图形绘制

(4)退出OpengL图形窗口时,释放OpengL的绘制描述表RC和Windows设备描述表DC

手动添加的代码用magenta表示。这里先叙述一下创建步骤:

1.新建一个MFC向导程序,命名为GLFrame,单文档,去除打印支持,其余默认,生成一个OpenGL框架.

2.得到简单的窗口风格.

在CMianFrame中添加PreCreateWindow的代码:

   BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
 if( !CFrameWnd::PreCreateWindow(cs) )
  return FALSE;

 cs.cx =500;
 cs.cy =400;
 cs.lpszName =_T("OpenGL 框架程序");
 cs.style &=~FWS_ADDTOTITLE;//不把标题加到标题栏
 return TRUE;
}

3.添加OpenGL支持:

在CGLFrameView.h中添加头文件如下:

#include "gl\gl.h"
#include "gl\glu.h"
#include "gl\glaux.h"

在工程->设置->Project Settings对话框话中选择Link选项卡,在对象模块库中加入glaux.lib  glu32.lib opengl32.lib .

(TIP:当然,你也可以选择工程->添加到工程->添加文件命令,弹出的Insert Files into Project对话框中,转换到VC98\lib目录下面,选中glaux.lib , glu32.lib, opengl32.lib 这几个文件,按下OK,把它们添加到项目文件.)

以下操作均在CGLFrameView中进行

4.给视图添加一个RC句柄和DC句柄,一个protected的变量

class CGLFrameView:public CView

{

protected:

   ...//其他变量

 HGLRC     m_hrc; 
 CClientDC    *m_pDC;

   ...//其他变量

}

5.给视图添加消息处理:

添加WM_CREATE,WM_DESTROY,WM_SIZE,WM_PAINT,WM_ERASEBKGND 这5个消息的处理函数.

6.修改CGFrameView的PreCreateWindow() 函数如下:

BOOL CGLFrameView::PreCreateWindow(CREATESTRUCT& cs)
{
 // TODO: Modify the Window class or styles here by modifying
 //  the CREATESTRUCT cs

 cs.style |=WS_CLIPSIBLINGS|WS_CLIPCHILDREN; //不要画到兄弟窗口或子窗口
 return CView::PreCreateWindow(cs);
}

7.修改CGFrameView的OnCreate()函数如下:  ------------作用是设置RC的像素格式

int CGLFrameView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
 if (CView::OnCreate(lpCreateStruct) == -1)
  return -1;
//=================================== 
  int pixelformat;
  m_pDC = new CClientDC(this);//在客户区作图,获得设备描述表DC
 ASSERT(m_pDC != NULL);


 static PIXELFORMATDESCRIPTOR pfd =
 {
        sizeof(PIXELFORMATDESCRIPTOR),  //固定值
   1,                              //固定值
   PFD_DRAW_TO_WINDOW |            // support window
   PFD_SUPPORT_OPENGL |            // support OpenGL
   PFD_TYPE_RGBA,                  // RGBA模式,不用调色板
   16,                             //程序在16位色彩下运行

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,                     // accum bits ignored
   32,                             // 32-bit z-buffer
   0,                              // no stencil buffer
   0,                              // no auxiliary buffer
   PFD_MAIN_PLANE,                 // main layer
   0,                              // reserved
   0, 0, 0                         // layer masks ignored
    };
  
 if ( (pixelformat = ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd)) == 0 ) //测试硬件是否支持该pdf
    {
        MessageBox("在该DC上找不到与PFD接近的位图结构");
        return -1;
    }
 
 if (SetPixelFormat(m_pDC->GetSafeHdc(), pixelformat, &pfd) == FALSE)//测试硬件是否支持该pdf
    {
        MessageBox("无法在该DC上设置位图结构");
        return -1;
    }

  m_hrc = wglCreateContext(m_pDC->GetSafeHdc());//将RC与DC联系起来
    wglMakeCurrent(m_pDC->GetSafeHdc(), m_hrc);
 
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
 
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);

 return 0; //OpenGL窗口构造成功

}
8.修改CGFrameView的OnDestroy()函数如下:

void CGLFrameView::OnDestroy() 
{
 CView::OnDestroy();
 
 // TODO: Add your message handler code here
 if(wglGetCurrentContext()!=NULL) //释放RC以及DC
  ::wglMakeCurrent(NULL,  NULL);
 if (m_hrc)
        ::wglDeleteContext(m_hrc);
 if (m_pDC)
        delete m_pDC;}

9.修改CGFrameView的OnSize()函数如下:

void CGLFrameView::OnSize(UINT nType, int cx, int cy) 
{
 CView::OnSize(nType, cx, cy);

if(cy > 0)
    {    
        glViewport(0, 0, cx, cy);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
  if (cx <= cy)
    glOrtho(-3.0,3.0,-3.0 * (GLfloat)cx/(GLfloat)cy,
 3.0 * (GLfloat)cx/(GLfloat)cy,-3.0,3.0);
  else
   glOrtho(-3.0,3.0,-3.0 * (GLfloat)cy/(GLfloat)cx,
   3.0 * (GLfloat)cy/(GLfloat)cx,-3.0,3.0);
  glMatrixMode(GL_MODELVIEW);
  } 
}

10.修改CGFrameView的OnPaint()函数如下

void CGLFrameView::OnPaint() 
{
 CPaintDC dc(this); // device context for painting
 GLfloat light_position[]={2.0f,0.0f,4.0f,0.0f};

 // TODO: Add your message handler code here
 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glPushMatrix();
  glTranslatef(0.0f, 0.0f, -2.0f);
 glLightfv(GL_LIGHT0,GL_POSITION,light_position);
 glEnable(GL_LIGHTING);
 glEnable(GL_LIGHT0);
 glDepthFunc(GL_LESS);
 glEnable(GL_DEPTH_TEST);
 auxSolidSphere(1.0);
  glPopMatrix();
  glFinish();
 // Do not call CView::OnPaint() for painting messages
}

11.修改CGFrameView的OnEraseBkgnd()函数如下

BOOL CGLFrameView::OnEraseBkgnd(CDC* pDC) 
{
 // TODO: Add your message handler code here and/or call default
 return TRUE; //消除屏幕闪烁
 //return CView::OnEraseBkgnd(pDC);
}

以上是用OpenGL编程所必须做好的基本工作^_*,希望对大家有帮助!


0 0
原创粉丝点击