我正在执行以下代码来创建核心配置文件OpenGL上下文.
具体来说,我是:
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;
Run Code Online (Sandbox Code Playgroud)
问题是WGL_ARB_create_context扩展名不存在.
但是,如果我忘记检查扩展列表,即放弃循环,只需:
wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
Run Code Online (Sandbox Code Playgroud)
我最终得到一个函数指针,一切正常.
为什么我的可用扩展列表不提供WGL_ARB_create_context字符串,即使扩展名存在?
编辑我有AMD Radeon HD 7900系列
为什么我的可用扩展列表不提供
WGL_ARB_create_context字符串,即使扩展名存在?
由于WGL扩展并不需要通过要发布GL扩展字符串.有一个WGL_ARB_extension_string扩展控制WGL扩展的广告.引用该规范:
应用程序应调用
wglGetProcAddress以查看是否wglGetExtensionsStringARB支持.如果支持,则可以使用它来确定设备支持哪些WGL扩展.
因此,为了不创建任何递归问题,如果函数指针为非,则保证其有效NULL.
如果你想知道为什么一些WGL扩展仍然在GL扩展字符串中:这是一个遗留的东西.再次从该扩展规范中引用问题1:
请注意,先前通过
glGetString(例如,交换间隔扩展)广告的扩展应该继续在那里做广告,因此现有应用程序不会中断.它们也应该通过广告宣传,wglGetExtensionsStringARB因此新的应用程序可以进行一次调用以找出支持哪些WGL扩展.
边注:
您使用的GL扩展查询机制glGetStringi仅适用于从GL 3.0开始.双方glGetInteger64v并glGetStringi可能无法使用,这代码将最有可能只是崩溃,如果在一些比较老的GPU上运行,或回落至微软的GL 1.1渲染器时.