代码之家  ›  专栏  ›  技术社区  ›  NeomerArcana

为什么我没有WGL\u ARB\u create\u上下文扩展?

  •  5
  • NeomerArcana  · 技术社区  · 9 年前

    具体来说,我是:

    1. 使用此OpenGL上下文加载OpenGL函数指针
    2. 通过这些函数指针,我尝试使用 wglCreateContextAttribsARB 在第二个窗口中使用核心配置文件创建第二个上下文。

    WNDCLASSW wcDummy = {0};
    wcDummy.lpfnWndProc     = +[](HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){return DefWindowProcW(hWnd, message, wParam, lParam);};
    wcDummy.hInstance       = GetModuleHandle(0);
    wcDummy.hbrBackground   = (HBRUSH)(COLOR_BACKGROUND);
    wcDummy.lpszClassName   = L"Dummy";
    wcDummy.style           = CS_OWNDC;
    
    if(!RegisterClassW(&wcDummy))
    {
        get_and_print_error();
        return false;
    }
    
    HWND windowDummy = CreateWindowW(wcDummy.lpszClassName, title.c_str(), WS_DISABLED, 0, 0, 640, 480, 0, 0, wcDummy.hInstance, NULL);
    if(windowDummy == NULL)
    {
        get_and_print_error();
        return false;
    }
    
    PIXELFORMATDESCRIPTOR pfdDummy =
    {
        sizeof(PIXELFORMATDESCRIPTOR),
        1,
        PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
        PFD_TYPE_RGBA,
        32,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        24,
        8,
        0, 0, 0, 0, 0, 0
    };
    
    HDC dummyDrawingContext = GetDC(windowDummy);
    
    INT pixelFormatDummy = ChoosePixelFormat(dummyDrawingContext, &pfdDummy);
    SetPixelFormat(dummyDrawingContext, pixelFormatDummy, &pfdDummy);
    
    HGLRC dummyContext = wglCreateContext(dummyDrawingContext);
    wglMakeCurrent(dummyDrawingContext, dummyContext);
    
    if(wglGetCurrentContext() != NULL)
    {
        load_gl_functions();
    }
    else
        return false;
    
    PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = nullptr;
    
    GLint64 numExtensions;
    glGetInteger64v(GL_NUM_EXTENSIONS, &numExtensions);
    std::cout << "Available Extensions:\n";
    for(GLint64 i = 0; i < numExtensions; ++i)
    {
        const GLubyte* extensionName = glGetStringi(GL_EXTENSIONS, i);
    
        std::cout << "\n\t" << (const char*)extensionName;
    
        if(std::strcmp((const char*)extensionName, "WGL_ARB_create_context") == 0)
        {
            wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
        }
    }
    std::cout << std::endl;
    
    wglDeleteContext(dummyContext);
    DestroyWindow(windowDummy);
    
    WNDCLASSW wc = {0};
    wc.lpfnWndProc      = Window::WndProc;
    wc.hInstance        = GetModuleHandle(0);
    wc.hbrBackground    = (HBRUSH)(COLOR_BACKGROUND);
    wc.lpszClassName    = title.c_str();
    wc.style = CS_OWNDC;
    
    if(!RegisterClassW(&wc))
    {
        get_and_print_error();
        return false;
    }
    
    HWND window = CreateWindowW(wc.lpszClassName, title.c_str(), WS_OVERLAPPED|WS_VISIBLE|WS_SYSMENU ,0,0,640,480,0,0,wc.hInstance,this);
    if(window == NULL)
    {
        get_and_print_error();
        return false;
    }
    
    PIXELFORMATDESCRIPTOR pfd =
    {
        sizeof(PIXELFORMATDESCRIPTOR),
        1,
        PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
        PFD_TYPE_RGBA,
        32,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        24,
        8,
        0, 0, 0, 0, 0, 0
    };
    
    HDC m_drawingContext = GetDC(window);
    
    INT pixelFormat = ChoosePixelFormat(m_drawingContext, &pfd);
    SetPixelFormat(m_drawingContext, pixelFormat, &pfd);
    
    const GLint attribList[] =
    {
        WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
        WGL_CONTEXT_MINOR_VERSION_ARB, 4,
        WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
        0
    };
    
    m_glRenderContext = wglCreateContextAttribsARB(m_drawingContext, 0, attribList);
    
    wglMakeCurrent(m_drawingContext, m_glRenderContext);
    
    if(wglGetCurrentContext() != NULL)
    {
        load_gl_functions();
    }
    else
        return false;
    
    const GLubyte* driver = glGetString(GL_RENDERER);
    const GLubyte* version = glGetString(GL_VERSION);
    const GLubyte* glslVersion = glGetString(GL_SHADING_LANGUAGE_VERSION);
    
    std::wcout << "Device:       " << std::wstring(convert_gl_string_to_win32_string(driver)) << std::endl;
    std::wcout << "GL Version:   " << std::wstring(convert_gl_string_to_win32_string(version)) << std::endl;
    std::wcout << "GLSL Version: " << std::wstring(convert_gl_string_to_win32_string(glslVersion)) << std::endl;
    std::wcout << std::endl;
    

    问题是 WGL_ARB_create_context

    但是,如果我忘记检查扩展列表,即放弃循环,只需:

    wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
    

    我最终得到了一个函数指针,一切正常。

    字符串,即使扩展名存在?

    编辑

    3 回复  |  直到 9 年前
        1
  •  8
  •   derhass    9 年前

    为什么我的可用扩展列表没有提供 WGL_ARB_create_context 字符串,即使扩展名存在?

    WGL公司 扩展是 需要通过 德国劳埃德船级社 WGL_ARB_extension_string

    应用程序应调用 wglGetProcAddress wglGetExtensionsStringARB 支持。如果支持,则可以使用它来确定设备支持哪些WGL扩展。

    NULL .

    请注意,以前通过 glGetString (例如,掉期间隔延长)应继续 在那里发布广告,使现有应用程序不会中断。他们 也应通过 太新了 应用程序可以进行一次调用以找出哪些WGL扩展是 支持。

    旁注:

    您的总账扩展查询机制使用 glGetStringi glGetInteger64v 和 glGetStringi公司

        2
  •  3
  •   BDL Vyxzl    9 年前

    延期的原因 WGL_ARB_create_context 不在支持的扩展列表中是因为从技术上讲,它不是OpenGL扩展,而是WGL扩展。 glGetStringi 仅返回OpenGL扩展,但不返回WGL扩展 1. .

    要查询WGL扩展,请使用 WGL_ARB_extensions_string 必须使用扩展来提供 wglGetExtensionsStringARB 方法检查此扩展是否可用的唯一方法是查询 看看它是否返回0。

    应用程序应调用wglGetProcAddress以查看是否 支持wglGetExtensionsStringARB。

    WGL\u ARB\u create\u上下文 wglCreateContextARB 并检查结果。


    由于历史原因,有一些例外。扩展描述说明:

    在那里发布广告,使现有应用程序不会中断。他们 也应该通过wglGetExtensionsStringARB进行广告 应用程序可以进行一次调用以找出哪些WGL扩展是 支持。

        3
  •  -1
  •   Ripi2 user10587824    9 年前

    glGetInteger64v 检索扩展的数量。但该函数不是由Windows提供的,它必须作为OpenGL 1.1之后的任何gl命令分配一个指针
    glGetStringi . 两者都是OGL>=3.0功能。
    因此,你的循环是无用的。我甚至不知道代码可以编译。您没有显示的内容可能会为这些函数分配指针。

    wglCreateContextAttribsARB 确实存在于Windows中,因此您可以在不检查其扩展名的情况下获取指针。

    wglGetExtensionsStringARB 或 wglGetExtensionsStringEXT wglGetProcAddress .

    推荐文章