首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我没有WGL_ARB_create_context扩展呢?

为什么我没有WGL_ARB_create_context扩展呢?
EN

Stack Overflow用户
提问于 2017-08-29 11:15:15
回答 2查看 4.3K关注 0票数 5

我正在执行以下代码来创建核心配置文件OpenGL上下文。

具体来说,我是:

  1. 创建一个虚拟窗口
  2. 使用这个虚拟窗口请求一个OpenGL上下文(我假设它会被硬件加速,但我不确定这是否重要)
  3. 使用此OpenGL上下文加载OpenGL函数指针
  4. 然后,使用这些函数指针,我尝试使用wglCreateContextAttribsARB创建第二个上下文,特别是第二个窗口中的核心配置文件。

代码:

代码语言:javascript
复制
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扩展不存在。

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

代码语言:javascript
复制
wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");

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

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

编辑i有AMD 7900 seriesY

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-08-29 12:13:32

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

因为WGL扩展不需要通过GL扩展字符串进行广告。有控制WGL扩展广告的WGL_ARB_extension_string扩展。引用该规范的话:

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

因此,为了不创建任何递归问题,如果函数指针是非NULL的,则保证它是有效的。

如果您想知道为什么某些WGL扩展仍然在GL扩展字符串中: THis再次成为遗留的东西。再次引用该扩展规范中的问题1:

注意,以前通过glGetString发布的扩展(例如交换间隔扩展)应该继续在那里进行广告,这样现有的应用程序就不会中断。它们还应该通过wglGetExtensionsStringARB发布广告,这样新的应用程序就可以通过一个调用来找出支持哪些WGL扩展。

附带说明:

使用glGetStringi的GL扩展查询机制只能从GL3.0开始工作。glGetInteger64vglGetStringi可能都不可用,如果在一些旧的GPU上运行,或者回到微软的GL1.1渲染器上,这段代码很可能就会崩溃。

票数 8
EN

Stack Overflow用户

发布于 2017-08-29 12:13:40

您可以使用glGetInteger64v检索扩展的数量。但是这个函数不是由Windows提供的,必须在OpenGL 1.1之后指定一个指针作为任何gl-命令。

glGetStringi也有同样的问题。这两个函数都是OGL >= 3.0函数。

因此,您的循环是无用的。我不知道这段代码甚至可以编译。您没有显示的东西可能会为这些函数指定指针。

wglCreateContextAttribsARB确实存在于Windows中,所以在没有检查指针的扩展之前,就可以得到指针。

用于获取Windows中可用的扩展的函数是wglGetExtensionsStringARBwglGetExtensionsStringEXT。通过通常的wglGetProcAddress获得他们的指示。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45937728

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档