【问题标题】:MFC and OpenGL CView, C++, initialising OpenGL after GLEWMFC 和 OpenGL CView,C++,在 GLEW 之后初始化 OpenGL
【发布时间】:2014-02-17 09:25:36
【问题描述】:

我对使用 C++ 的 MFC 比较陌生(阅读:非常) - 我通常只担心 OpenGL。

据我所知,使用 OGL 编写 C++ Win32,我需要在初始化 OpenGL 和创建窗口之前初始化 GLEW,这需要使用虚拟窗口。酷,不知道。

在 MFC 中,我派生了一个 CView 类,它包含一个成员 OpenGL 类。

我已经使用 OnPreCreateWindow 中的临时窗口成功初始化了 GLEW,我还成功初始化了 OpenGL,但是可惜的是,使用了错误的 HWND/HDC.. 确实调试告诉我作为 OpenGL 类中的成员持有的 HDC 是不是我从 CDC 获得的 OnDraw 吗?

我的 OpenGL 正确 HDC 在哪里? - 我需要一些 MFC 帮助!我是否需要不时更新此 DC?

看来我可以选择 OnInitialUpdate、OnPreCreateWindow 和 OnDraw(CDC*) 来使用正确的 DC 初始化/更新 OpenGL。

void CJesseView::OnInitialUpdate()
{
    CView::OnInitialUpdate();
    HDC hDC = GetDC()->m_hDC;
}

这可以工作并初始化 GLEW - 我应该在其他地方做吗?

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

    /* modify the style of the view / window */
    cs.dwExStyle |= CS_OWNDC;

    /*  OpenGL Set up
        1. Create a faux window
    */
    CString m_ClassName("JesseGLView");

    HWND hwnd = CreateWindowEx(WS_EX_APPWINDOW, m_ClassName, m_ClassName, 
                    WS_POPUP, 0, 0, 640, 480, NULL, NULL, cs.hInstance, NULL);

    ::ShowWindow(hwnd, SW_HIDE);    // Don't show the window.

    /* OpenGL Set up    
       2. Initialise Glews extension Library to give us access to OpenGL 4.1 Core
    */
    m_OpenGL = new OpenGL();

    if( ! m_OpenGL->PreInjectGLEW( hwnd ) )
        MessageBox(_T("No OpenGL Niceties - Couldn't initialise GLEW!"), _T("CJesseView"));

    ::DestroyWindow( hwnd );    //Destroy Window now that the extensions are loaded
    hwnd = NULL;

    //..
    return CView::PreCreateWindow(cs);
}

void CJesseView::OnDraw(CDC* pCDC)
{
    CJesseDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);

    // TODO: add draw code for native data here

    BeginScene(0.4, 0.4, 0.8, 1.0);
    // Draw something!
    EndScene();

    //..
    ::SwapBuffers( pCDC->GetSafeHdc() );
}

int CJesseView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CView::OnCreate(lpCreateStruct) == -1)
        return -1;

    // TODO:  Add your specialized creation code here
    m_OpenGL->Create( AfxGetApp()->GetMainWnd()->GetSafeHwnd(), 
                true, 800, 600, 0.1f, 60000.0f ); // VSYNC, 0.1, 60k for near and far

    return 0;
}

最后是我的 OpenGL::Create() 函数,错误与 HWND 有关

bool OpenGL::InitOpenGL( HWND hWnd, int sW, int sH, float nearP, float farP, bool vsync )
{
    bool bOk = false;
    bool error = false;

    m_Context = GetDC( hWnd );

    //do some PIXELFORMATDESCRIPTOR and context attrib setup

    bOk = bOk && (m_Renderer = wglCreateContextAttribsARB(m_Context, 0, actualContextAttribs));

    if( ! bOk )
        return false;

    if(! wglMakeCurrent(m_Context, m_Renderer) ) {    
        wglDeleteContext(m_Renderer);
        return false;
    }

    //... other stuff
}

【问题讨论】:

    标签: c++ opengl mfc gdi cview


    【解决方案1】:

    我需要在初始化 OpenGL 之前初始化 GLEW

    没有。 GLEW 需要将现有的 OpenGL 上下文设为当前才能正确初始化。这在 GLEW 手册中也有明确说明。所以请继续阅读精美手册 (RTFM)。

    现在,对于创建高级 OpenGL 上下文,GLEW 帮助不大。您需要首先创建一个代理 OpenGL 上下文,用于获取指向扩展 wgl… 函数的函数指针。不要在这里为 MFC 烦恼。为此使用普通的 Win32 函数。这里解释的很好:http://www.opengl.org/wiki/Creating_an_OpenGL_Context_(WGL)#Proper_Context_Creation

    获得正确的 OpenGL 上下文后,您就可以使用 GLEW。

    【讨论】:

    • “我已经使用 OnPreCreateWindow 中的临时窗口成功初始化了 GLEW,我也成功初始化了 OpenGL,但是唉,使用错误的 HWND / HDC.. 确实调试告诉我 HDC 作为我的 OpenGL 课程中的成员不是我从 CDC 获得的 OnDraw 成员吗?”自从发布此消息后,我现在可以看到我为 glClearColour 设置的蓝色。我通过 Google 找到了一个叫 Eric Idelson 的人的工作代码示例,并意识到在设置高级上下文时我得到了错误的 HDC。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多