wglCreateContextAttribsARB 在 NVIDIA 硬件上失败
ContextWin32::ContextWin32(WindowHandle parent, NLOpenGLSettings settings)
: IPlatformContext(parent, settings)
{
int pf = 0;
PIXELFORMATDESCRIPTOR pfd = {0};
OSVERSIONINFO osvi = {0};
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
// Obtain HDC for this window.
if (!(m_hdc = GetDC((HWND)parent)))
{
NLError("[ContextWin32] GetDC() failed.");
throw NLException("GetDC() failed.", true);
}
// Create and set a pixel format for the window.
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = settings.BPP;
pfd.cDepthBits = settings.BPP;
pfd.iLayerType = PFD_MAIN_PLANE;
// Obtain Windows Version
if (!GetVersionEx(&osvi))
{
NLError("[ContextWin32] GetVersionEx() failed.");
throw NLException("[ContextWin32] GetVersionEx() failed.");
}
// Get a pixelformat, based on our settings
pf = ChoosePixelFormat(m_hdc, &pfd);
// Set the pixelformat
if (!SetPixelFormat(m_hdc, pf, &pfd))
{
NLError("[ContextWin32] GetVersionEx() failed.");
throw NLException("[ContextWin32] SetPixelFormat() failed.");
}
// When running under Windows Vista or later support desktop composition.
// This doesn't really apply when running in full screen mode.
if (osvi.dwMajorVersion > 6 || (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion >= 0))
pfd.dwFlags |= PFD_SUPPORT_COMPOSITION;
// Verify that this OpenGL implementation supports the extensions we need
std::string extensions = wglGetExtensionsStringARB(m_hdc);
if (extensions.find("WGL_ARB_create_context") == std::string::npos){
NLError("[ContextWin32] Required extension WGL_ARB_create_context is not supported.");
throw NLException("[ContextWin32] Required extension WGL_ARB_create_context is not supported.");
}
int attribList[] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, settings.MAJOR,
WGL_CONTEXT_MINOR_VERSION_ARB, settings.MINOR,
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
WGL_COLOR_BITS_ARB, 32,
WGL_DEPTH_BITS_ARB, 24,
0
};
// First try creating an OpenGL context.
if (!(m_hglrc = wglCreateContextAttribsARB(m_hdc, 0, attribList)))
{
// Fall back to an OpenGL 3.0 context.
attribList[3] = 0;
if (!(m_hglrc = wglCreateContextAttribsARB(m_hdc, 0, attribList))){
NLError("[ContextWin32] wglCreateContextAttribsARB() failed for OpenGL 3 context.");
throw NLException("[ContextWin32] wglCreateContextAttribsARB() failed for OpenGL 3 context.", true);
}
}
if (!wglMakeCurrent(m_hdc, m_hglrc)){
NLError("[ContextWin32] wglMakeCurrent() failed for OpenGL 3 context.");
throw NLException("[ContextWin32] wglMakeCurrent() failed for OpenGL 3 context.");
}
// Load wglSwapIntervalExt
typedef BOOL (APIENTRY * PFNWGLSWAPINTERVALEXTPROC)(int);
static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = 0;
wglSwapIntervalEXT = reinterpret_cast<PFNWGLSWAPINTERVALEXTPROC>(wglGetProcAddress("wglSwapIntervalEXT"));
if ( wglSwapIntervalEXT )
{
if ( settings.VSYNC == true )
{
wglSwapIntervalEXT(1);
}
else if ( settings.VSYNC == false )
{
wglSwapIntervalEXT(0);
}
}
else if (wglSwapIntervalEXT == NULL )
{
NLWarning("[ContextWin32] Cannot load wglSwapIntervalEXT");
}
}
这是有问题的代码。 当我尝试设置属性时,它在第 77 行失败。 但同样的代码可以在我的 ATI 上运行。 我不拥有任何 NVIDIA 产品,因此无法重现它,但我当然需要修复它。有人可以帮忙解决这个问题吗?我忽略了什么?
我的定义:
extern "C" {
#define ERROR_INVALID_VERSION_ARB 0x2095
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
#define WGL_CONTEXT_FLAGS_ARB 0x2094
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
#define WGL_DRAW_TO_BITMAP_ARB 0x2002
#define WGL_ACCELERATION_ARB 0x2003
#define WGL_NEED_PALETTE_ARB 0x2004
#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
#define WGL_SWAP_METHOD_ARB 0x2007
#define WGL_NUMBER_OVERLAYS_ARB 0x2008
#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
#define WGL_TRANSPARENT_ARB 0x200A
#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
#define WGL_SHARE_DEPTH_ARB 0x200C
#define WGL_SHARE_STENCIL_ARB 0x200D
#define WGL_SHARE_ACCUM_ARB 0x200E
#define WGL_SUPPORT_GDI_ARB 0x200F
#define WGL_SUPPORT_OPENGL_ARB 0x2010
#define WGL_DOUBLE_BUFFER_ARB 0x2011
#define WGL_STEREO_ARB 0x2012
#define WGL_PIXEL_TYPE_ARB 0x2013
#define WGL_COLOR_BITS_ARB 0x2014
#define WGL_RED_BITS_ARB 0x2015
#define WGL_RED_SHIFT_ARB 0x2016
#define WGL_GREEN_BITS_ARB 0x2017
#define WGL_GREEN_SHIFT_ARB 0x2018
#define WGL_BLUE_BITS_ARB 0x2019
#define WGL_BLUE_SHIFT_ARB 0x201A
#define WGL_ALPHA_BITS_ARB 0x201B
#define WGL_ALPHA_SHIFT_ARB 0x201C
#define WGL_ACCUM_BITS_ARB 0x201D
#define WGL_ACCUM_RED_BITS_ARB 0x201E
#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
#define WGL_DEPTH_BITS_ARB 0x2022
#define WGL_STENCIL_BITS_ARB 0x2023
#define WGL_AUX_BUFFERS_ARB 0x2024
#define WGL_NO_ACCELERATION_ARB 0x2025
#define WGL_GENERIC_ACCELERATION_ARB 0x2026
#define WGL_FULL_ACCELERATION_ARB 0x2027
#define WGL_SWAP_EXCHANGE_ARB 0x2028
#define WGL_SWAP_COPY_ARB 0x2029
#define WGL_SWAP_UNDEFINED_ARB 0x202A
#define WGL_TYPE_RGBA_ARB 0x202B
#define WGL_TYPE_COLORINDEX_ARB 0x202C
extern HGLRC wglCreateContextAttribsARB(HDC hDC, HGLRC hShareContext, const int *attribList);
}
也许我的一些#defines 是错误的?
任何意见都将受到高度赞赏。
ps.:关于 AttribList[3] = 0 的小故障;现在已修复,必须为 1。但这不是问题所在。
ContextWin32::ContextWin32(WindowHandle parent, NLOpenGLSettings settings)
: IPlatformContext(parent, settings)
{
int pf = 0;
PIXELFORMATDESCRIPTOR pfd = {0};
OSVERSIONINFO osvi = {0};
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
// Obtain HDC for this window.
if (!(m_hdc = GetDC((HWND)parent)))
{
NLError("[ContextWin32] GetDC() failed.");
throw NLException("GetDC() failed.", true);
}
// Create and set a pixel format for the window.
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = settings.BPP;
pfd.cDepthBits = settings.BPP;
pfd.iLayerType = PFD_MAIN_PLANE;
// Obtain Windows Version
if (!GetVersionEx(&osvi))
{
NLError("[ContextWin32] GetVersionEx() failed.");
throw NLException("[ContextWin32] GetVersionEx() failed.");
}
// Get a pixelformat, based on our settings
pf = ChoosePixelFormat(m_hdc, &pfd);
// Set the pixelformat
if (!SetPixelFormat(m_hdc, pf, &pfd))
{
NLError("[ContextWin32] GetVersionEx() failed.");
throw NLException("[ContextWin32] SetPixelFormat() failed.");
}
// When running under Windows Vista or later support desktop composition.
// This doesn't really apply when running in full screen mode.
if (osvi.dwMajorVersion > 6 || (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion >= 0))
pfd.dwFlags |= PFD_SUPPORT_COMPOSITION;
// Verify that this OpenGL implementation supports the extensions we need
std::string extensions = wglGetExtensionsStringARB(m_hdc);
if (extensions.find("WGL_ARB_create_context") == std::string::npos){
NLError("[ContextWin32] Required extension WGL_ARB_create_context is not supported.");
throw NLException("[ContextWin32] Required extension WGL_ARB_create_context is not supported.");
}
int attribList[] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, settings.MAJOR,
WGL_CONTEXT_MINOR_VERSION_ARB, settings.MINOR,
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
WGL_COLOR_BITS_ARB, 32,
WGL_DEPTH_BITS_ARB, 24,
0
};
// First try creating an OpenGL context.
if (!(m_hglrc = wglCreateContextAttribsARB(m_hdc, 0, attribList)))
{
// Fall back to an OpenGL 3.0 context.
attribList[3] = 0;
if (!(m_hglrc = wglCreateContextAttribsARB(m_hdc, 0, attribList))){
NLError("[ContextWin32] wglCreateContextAttribsARB() failed for OpenGL 3 context.");
throw NLException("[ContextWin32] wglCreateContextAttribsARB() failed for OpenGL 3 context.", true);
}
}
if (!wglMakeCurrent(m_hdc, m_hglrc)){
NLError("[ContextWin32] wglMakeCurrent() failed for OpenGL 3 context.");
throw NLException("[ContextWin32] wglMakeCurrent() failed for OpenGL 3 context.");
}
// Load wglSwapIntervalExt
typedef BOOL (APIENTRY * PFNWGLSWAPINTERVALEXTPROC)(int);
static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = 0;
wglSwapIntervalEXT = reinterpret_cast<PFNWGLSWAPINTERVALEXTPROC>(wglGetProcAddress("wglSwapIntervalEXT"));
if ( wglSwapIntervalEXT )
{
if ( settings.VSYNC == true )
{
wglSwapIntervalEXT(1);
}
else if ( settings.VSYNC == false )
{
wglSwapIntervalEXT(0);
}
}
else if (wglSwapIntervalEXT == NULL )
{
NLWarning("[ContextWin32] Cannot load wglSwapIntervalEXT");
}
}
This is the code in question.
It fails on Line 77, when I try to set the Attributes.
But the very same code works on my ATI.
I do not own any NVIDIA Product and cannot reproduce it, but I need to fix it of course. Can anyone help on the issue? What did I overlook?
My Definitions:
extern "C" {
#define ERROR_INVALID_VERSION_ARB 0x2095
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
#define WGL_CONTEXT_FLAGS_ARB 0x2094
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
#define WGL_DRAW_TO_BITMAP_ARB 0x2002
#define WGL_ACCELERATION_ARB 0x2003
#define WGL_NEED_PALETTE_ARB 0x2004
#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
#define WGL_SWAP_METHOD_ARB 0x2007
#define WGL_NUMBER_OVERLAYS_ARB 0x2008
#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
#define WGL_TRANSPARENT_ARB 0x200A
#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
#define WGL_SHARE_DEPTH_ARB 0x200C
#define WGL_SHARE_STENCIL_ARB 0x200D
#define WGL_SHARE_ACCUM_ARB 0x200E
#define WGL_SUPPORT_GDI_ARB 0x200F
#define WGL_SUPPORT_OPENGL_ARB 0x2010
#define WGL_DOUBLE_BUFFER_ARB 0x2011
#define WGL_STEREO_ARB 0x2012
#define WGL_PIXEL_TYPE_ARB 0x2013
#define WGL_COLOR_BITS_ARB 0x2014
#define WGL_RED_BITS_ARB 0x2015
#define WGL_RED_SHIFT_ARB 0x2016
#define WGL_GREEN_BITS_ARB 0x2017
#define WGL_GREEN_SHIFT_ARB 0x2018
#define WGL_BLUE_BITS_ARB 0x2019
#define WGL_BLUE_SHIFT_ARB 0x201A
#define WGL_ALPHA_BITS_ARB 0x201B
#define WGL_ALPHA_SHIFT_ARB 0x201C
#define WGL_ACCUM_BITS_ARB 0x201D
#define WGL_ACCUM_RED_BITS_ARB 0x201E
#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
#define WGL_DEPTH_BITS_ARB 0x2022
#define WGL_STENCIL_BITS_ARB 0x2023
#define WGL_AUX_BUFFERS_ARB 0x2024
#define WGL_NO_ACCELERATION_ARB 0x2025
#define WGL_GENERIC_ACCELERATION_ARB 0x2026
#define WGL_FULL_ACCELERATION_ARB 0x2027
#define WGL_SWAP_EXCHANGE_ARB 0x2028
#define WGL_SWAP_COPY_ARB 0x2029
#define WGL_SWAP_UNDEFINED_ARB 0x202A
#define WGL_TYPE_RGBA_ARB 0x202B
#define WGL_TYPE_COLORINDEX_ARB 0x202C
extern HGLRC wglCreateContextAttribsARB(HDC hDC, HGLRC hShareContext, const int *attribList);
}
Maybe I got some #defines wrong?
Any input is highly appreciated.
ps.: The little glitch regarding AttribList[3] = 0; is fixed by now, must be 1. But that was not the issue.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
从“attribList”中删除以下对:
这些属性名称已经是由“*m_hdc*”句柄指定(事实上,您对其调用SetPixelFormat)。
我在 NVIDIA 平台上创建了一个没有这些标志的有效上下文。
CreateContextAttribsARB 的有效属性名称为:
此外,返回 wglCreateContextAttribsARB 的错误是什么?
实例示例:
Remove from 'attribList' the following pairs:
Those attribute names are already specified by the '*m_hdc*' handle (infact you call SetPixelFormat on it).
I create a valid context without those flags on NVIDIA platforms.
Valid attribute names for CreateContextAttribsARB are:
Furthermore, what error is returning wglCreateContextAttribsARB?
Instance example: