在MFC中的picture control 中使用opengl作图

转载自:http://blog.sina.com.cn/s/blog_8e6bfecf0100uuwy.html,觉得这个写的详细一些,自己测试也成功,在此基础上做了点修改,收藏记录分享下。。。

新建一个MFC的dialog工程(eg,C++MFC工程openGlMFC)。

为了方便进行字符串CString与其它格式的转换,在工程属性的Configuration Properties -> General -> Character Set中,不使用默认的Use Unicode Character Set,改为Use Multi-Byte Character Set

在项目属性的linker->input->additional dependencies中加入:opengl32.lib;glu32.lib;glut32.lib;glaux.lib

在MFC组件中添加一个Picture Control组件,将组件ID改为IDC_RENDER

在stdafx.h的末尾加入:("#include< afxcontrolbars.h>"之后加入)
    #include< GL/glut.h>
    #include< GL/glaux.h>    

在??Dlg.h的 "enum { IDD = IDD_??_DIALOG };" 下加入:
    BOOL SetWindowPixelFormat(HDC hDC);                    // 设定像素格式
    BOOL CreateViewGLContext(HDC hDC);                    // view GL Context
    void RenderScene();                                                    // 绘制场景
    HDC hrenderDC;                                                            // DC
    HGLRC hrenderRC;                                                        // RC
    int PixelFormat;                                                        // 像素格式

在??Dlg.h的"DECLARE_MESSAGE_MAP()"下加入:
    afx_msg void OnTimer(UINT nIDEvent);                // 重载OnTimer函数

在??Dlg.cpp的"BEGIN_MESSAGE_MAP(CCOpenGLDlg, CDialog)...END_MESSAGE_MAP()"中加入:(注意不要加错了地方
    ON_WM_TIMER()

在??Dlg.cpp的OnInitDialog()中加入OpenGL的初始化声明etc:
    CWnd* wnd = GetDlgItem(IDC_RENDER);                                        // 初始化MFC中的OpenGL设置
    hrenderDC = ::GetDC(wnd->m_hWnd);
    if(SetWindowPixelFormat(hrenderDC) == FALSE) {                // 设置hDC的像素格式
        return 0;
    }
    if(CreateViewGLContext(hrenderDC) == FALSE) {                    // 由hDC转换得到hRC
        return 0;
    }
    // openGL的初始化设置
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_SMOOTH);
    //glViewport(0, 0, 200, 200);
    glMatrixMode(GL_PROJECTION);
    gluPerspective(45, 1, 0.1, 100.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    // 设置计时器,10ms刷新一次
    SetTimer(1, 10, 0);

SetWindowPixelFormat()(设置像素格式的函数):
BOOL CCOpenGLDlg::SetWindowPixelFormat(HDC hDC) {// CCOpenGLDlg改为你自己创建的MFC类名
第一种写法:  

/*  PIXELFORMATDESCRIPTOR pixelDesc;
    pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
    pixelDesc.nVersion = 1;
    pixelDesc.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_TYPE_RGBA;
    pixelDesc.iPixelType = PFD_TYPE_RGBA;
    pixelDesc.cColorBits = 32;
    pixelDesc.cRedBits = 0;
    pixelDesc.cRedShift = 0;
    pixelDesc.cGreenBits = 0;
    pixelDesc.cGreenShift = 0;
    pixelDesc.cBlueBits = 0;
    pixelDesc.cBlueShift = 0;
    pixelDesc.cAlphaBits = 0;
    pixelDesc.cAlphaShift = 0;
    pixelDesc.cAccumBits = 0;
    pixelDesc.cAccumRedBits = 0;
    pixelDesc.cAccumGreenBits = 0;
    pixelDesc.cAccumBlueBits = 0;
    pixelDesc.cAccumAlphaBits = 0;
    pixelDesc.cDepthBits = 0;
    pixelDesc.cStencilBits = 1;
    pixelDesc.cAuxBuffers = 0;
    pixelDesc.iLayerType = PFD_MAIN_PLANE;
    pixelDesc.bReserved = 0;
    pixelDesc.dwLayerMask = 0;
    pixelDesc.dwVisibleMask = 0;
    pixelDesc.dwDamageMask = 0;

    PixelFormat = ChoosePixelFormat(hDC, &pixelDesc);
    if(PixelFormat == 0) {
        PixelFormat = 1;
        if(DescribePixelFormat(hDC, PixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pixelDesc) == 0) {
            return FALSE;
        }
    }
    if(SetPixelFormat(hDC, PixelFormat,& pixelDesc) == FALSE) {
        return FALSE;
    }
    return TRUE;*/


第二种写法:

/*

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  iPixelFormat;

 // 为设备描述表得到最匹配的像素格式

 if ((iPixelFormat = ChoosePixelFormat(hdc, &pfd)) == 0)

 {

  MessageBox(_T("ChoosePixelFormat Failed"), NULL, MB_OK);

  return 0;

 }

 // 设置最匹配的像素格式为当前的像素格式

 if (SetPixelFormat(hdc, iPixelFormat, &pfd) == FALSE)

 {

  MessageBox(_T("SetPixelFormat Failed"), NULL, MB_OK);

  return 0;

 }
 return 1;

*/
}

CreateViewGLContext()(由HDC转化得到HRC的函数):
BOOL CCOpenGLDlg::CreateViewGLContext(HDC hDC) {
    hrenderRC = wglCreateContext(hDC);
    if(hrenderRC == NULL) {
        return FALSE;
    }
    if(wglMakeCurrent(hDC, hrenderRC) == FALSE) {
        return FALSE;
    }
    return TRUE;
}

实现OpenGL绘图的RenderScene函数:
void CCOpenGLDlg::RenderScene() {
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0, 1.0, 1.0);
    glLoadIdentity();
    glTranslatef(0.0, 0.0, -5.0);
    glBegin(GL_TRIANGLES);
        glVertex3f(0.0, 1.0, 0.0);
        glVertex3f(-1.0, -1.0, 0.0);
        glVertex3f(1.0, -1.0, 0.0);
    glEnd();
    SwapBuffers(hrenderDC);    // 使用glFlush()没有显示?
}

实现实时绘制场景的OnTimer函数是:
void CCOpenGLDlg::OnTimer(UINT nIDEvent) {
    RenderScene();
    CDialog::OnTimer(nIDEvent);
}

附上效果图:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值