我正在执行以下代码来创建核心配置文件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;
问题是WGL_ARB_create_context
扩展名不存在。
但是,如果我忘记检查扩展名列表,即放弃循环,只需:
wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
我最终得到了一个函数指针,一切正常。
为什么我的可用扩展列表不提供WGL_ARB_create_context
字符串,即使扩展名存在?
编辑我有AMD Radeon HD 7900系列
答案 0 :(得分:8)
为什么我的可用扩展列表不提供
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。 glGetInteger64v
和glGetStringi
可能都不可用,如果在某些较旧的GPU上运行,或者在回退到Microsoft的GL 1.1渲染器时,此代码很可能会崩溃。
答案 1 :(得分:3)
扩展名WGL_ARB_create_context
不在支持的扩展名列表中的原因是因为它在技术上不是OpenGL扩展而是WGL扩展。 glGetStringi
仅返回OpenGL扩展,但不返回WGL 1 。
要查询WGL扩展程序,必须使用提供wglGetExtensionsStringARB
方法的WGL_ARB_extensions_string扩展名。检查此扩展名是否可用的唯一方法是查询wglGetExtensionsStringARB
的地址,并查看它是否返回0.
应用程序应调用wglGetProcAddress来查看是否存在 支持wglGetExtensionsStringARB。
请注意,如果您只想知道WGL_ARB_create_context
是否更容易查询wglCreateContextARB
的地址并检查结果。
1 由于历史原因,有一些例外情况。扩展说明指出:
请注意之前通过广告宣传的扩展程序 glGetString(例如,交换间隔扩展)应该继续 在那里做广告,所以现有的应用程序不会中断。他们 也应该通过wglGetExtensionsStringARB做广告这么新 应用程序可以进行一次调用以找出哪些WGL扩展名 支撑。
答案 2 :(得分:-1)
您使用glGetInteger64v
来检索扩展数量。但是Windows不提供此功能,必须在OpenGL 1.1之后将其指定为任何gl-command
与glGetStringi
相同的问题。两者都是OGL&gt; = 3.0函数。
因此,你的循环是没用的。我不知道代码甚至可以编译。您未显示的内容可能会指定指向这些功能的指针。
wglCreateContextAttribsARB
,因此您无需先检查其扩展名即可获得指针。
获取Windows中可用扩展程序的功能包括wglGetExtensionsStringARB
或wglGetExtensionsStringEXT
。按常规wglGetProcAddress
获取指针。