opengl 为什么我没有WGL_ARB_create_context扩展?

xoshrz7s  于 2023-03-18  发布在  其他
关注(0)|答案(3)|浏览(321)

我正在执行以下代码来创建一个核心配置文件OpenGL上下文。
具体而言,我是:
1.创建虚拟窗口
1.使用这个虚拟窗口请求OpenGL上下文(我假设它是硬件加速的,但我不确定这是否重要)
1.使用此OpenGL上下文加载OpenGL函数指针
1.有了这些函数指针,我就可以尝试使用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");

最后我得到了一个函数指针,一切都正常工作。
为什么我的可用扩展列表不提供WGL_ARB_create_context字符串,即使该扩展存在?

编辑我有AMD Radeon HD 7900系列

bkkx9g8r

bkkx9g8r1#

为什么我的可用扩展列表不提供WGL_ARB_create_context字符串,即使该扩展存在?
因为 WGL 扩展 * 不 * 需要通过 GL 扩展字符串进行通告。有WGL_ARB_extension_string扩展控制WGL扩展的通告。引用该规范:
应用程序应调用wglGetProcAddress以查看是否支持wglGetExtensionsStringARB。如果支持,则可用于确定设备支持哪些WGL扩展。
因此,为了不产生任何递归问题,如果函数指针不是NULL,则保证它有效。
如果您想知道为什么一些WGL扩展名仍然在GL扩展名字符串中:这又是一个遗留问题。再次引用扩展规范中的问题1:
请注意,先前通过glGetString通告的扩展(例如,交换间隔扩展)应继续在那里通告,以便现有应用不会中断。它们还应通过wglGetExtensionsStringARB通告,以便新应用可以进行一次调用来找出支持哪些WGL扩展。
旁注:
使用glGetStringi的GL扩展查询机制只能从GL 3.0开始使用。glGetInteger64vglGetStringi可能都不可用,如果在一些较旧的GPU上运行,或者当回退到Microsoft的GL 1.1渲染器时,此代码很可能会崩溃。

oug3syen

oug3syen2#

扩展名WGL_ARB_create_context不在支持的扩展名列表中的原因是,从技术上讲,它不是OpenGL扩展名,而是WGL扩展名。glGetStringi只返回OpenGL扩展名,而不返回WGL扩展名1。
要查询WGL扩展,必须使用WGL_ARB_extensions_string扩展,该扩展提供wglGetExtensionsStringARB方法。检查此扩展是否可用的唯一方法是查询wglGetExtensionsStringARB的地址并查看它是否返回0。
应用程序应调用wglGetProcAddress以查看是否支持wglGetExtensionsStringARB。
请注意,如果您只想知道WGL_ARB_create_context是否是,查询wglCreateContextARB的地址并检查结果会更容易。
1由于历史原因,有一些例外。扩展描述如下:
注意,先前通过glGetString通告的扩展(例如,交换间隔扩展)应继续在那里通告,以便现有应用不会中断。它们还应通过wglGetExtensionsStringARB通告,以便新应用可以进行一次调用来找出支持哪些WGL扩展。

oyt4ldly

oyt4ldly3#

你可以使用glGetInteger64v来获取扩展名的数量,但是Windows没有提供这个函数,在OpenG1.1之后,它必须像任何gl-command一样被分配一个指针
glGetStringi也有同样的问题,都是OGL〉= 3.0的函数。
因此,你的循环是无用的。我甚至不知道代码是否可以编译。你没有显示的东西可能会给那些函数赋值指针。
wglCreateContextAttribsARB确实存在于Windows中,所以您在没有检查其扩展名之前就获得了一个指针。
获取Windows中可用扩展名的函数有wglGetExtensionsStringARBwglGetExtensionsStringEXT。通过常用的wglGetProcAddress获取它们的指针。

相关问题