加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

MFC中使用openGL

(2011-10-31 18:10:25)
标签:

杂谈


新建一个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;
}

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

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有