使用 OpenTK 创建图形上下文 returns 自 nvidia 的 375.63 驱动程序更新以来的 1.1 OpenGL 上下文
Creating a Graphic Context using OpenTK returns a 1.1 OpenGL context since nvidia's 375.63 driver update
问题描述
我一直在使用 OpenTK 在各种 Windows 配置(7、8、8.1、10)和硬件(各种 AMD、nvidia GPU 和英特尔的图形芯片组)上创建 OpenGL 上下文,超过 2 个都没有问题年。
但是由于 nvidia 的 375.63 驱动程序更新和所有后续驱动程序更新(甚至是昨天发布的最新 378.49),当我尝试使用 OpenTK 创建 OpenGL 上下文时,我最终得到了 OpenGL 1.1.0 上下文(供应商:Microsoft公司,渲染器:GDI 通用)。这看起来像是一个“后备”OpenGL 上下文,它当然缺少我需要的大多数 OpenGL 函数。
回滚到 373.06 或更早版本可以解决问题,但不是长期可行的解决方案。
观察
- 我已仔细阅读 nvidia's released notes 但没有发现与该问题相关的任何问题或评论。
- 我怀疑由 OpenTK 创建的句柄初始化的像素格式突然变得不受 nvidia 的驱动程序支持。 (如果需要我可以提供详细信息)
- 我已经使用 glfw 尝试了一些示例 C++ 代码,我可以获得正确的 OpenGL 上下文(版本:4.5.0,供应商:nvidia),因此它似乎不是低级驱动程序问题,而是上下文的创建方式以某种方式被破坏了。
我已开始深入研究 OpenTK 代码以缩小问题范围。
上下文是使用
周围的包装器创建的
Delegates.wglCreateContextAttribsARB((IntPtr)hDC, (IntPtr)hShareContext, (int*)attribList_ptr);
此委托是使用 GetProcAddress 函数加载的:
[System.Runtime.InteropServices.DllImport(Wgl.Library, EntryPoint = "wglGetProcAddress", ExactSpelling = true, SetLastError = true)]
internal extern static IntPtr GetProcAddress(String lpszProc);
其中 Wgl.Library 是“OPENGL32.dll”。函数加载正确。
传递的属性只是 GL_MAJOR = 1 GL_MINOR = 0 应该(并且始终具有)return 最新支持的 OpenGL 上下文。我也曾尝试将这些值分别强制为 4 和 5,但没有成功。
specs of wglCreateContextAttribsARB 没有提及任何“回退”上下文。
(注意:我的显卡支持wglCreateContextAttribsARB)
问题
- 有没有人在创建 OpenGL 上下文时遇到过类似的问题,您是如何解决的?
- 两个驱动程序版本之间可能发生了什么变化会破坏这个?
欢迎提供任何帮助或线索。如果需要,我可以详细说明一些具体点。
更新 (26.1.2017)
看来像素模式的获取方式才是问题的根源。初始化步骤尝试检索使用 wglChoosePixelFormatARB
函数的 ARB 模式,并使用新驱动程序获得 0 个有效模式。
这是代码块的相关部分。 (Wgl.Arb.ChoosePixelFormat
是 wglChoosePixelFormatARB
的包装)
...
int[] attribs = new int[]
{
(int)WGL_ARB_pixel_format.AccelerationArb,
(int)WGL_ARB_pixel_format.RedBitsArb,
(int)WGL_ARB_pixel_format.GreenBitsArb,
(int)WGL_ARB_pixel_format.BlueBitsArb,
(int)WGL_ARB_pixel_format.AlphaBitsArb,
(int)WGL_ARB_pixel_format.ColorBitsArb,
(int)WGL_ARB_pixel_format.DepthBitsArb,
(int)WGL_ARB_pixel_format.StencilBitsArb,
(int)WGL_ARB_multisample.SampleBuffersArb,
(int)WGL_ARB_multisample.SamplesArb,
(int)WGL_ARB_pixel_format.AccumRedBitsArb,
(int)WGL_ARB_pixel_format.AccumGreenBitsArb,
(int)WGL_ARB_pixel_format.AccumBlueBitsArb,
(int)WGL_ARB_pixel_format.AccumAlphaBitsArb,
(int)WGL_ARB_pixel_format.AccumBitsArb,
(int)WGL_ARB_pixel_format.DoubleBufferArb,
(int)WGL_ARB_pixel_format.StereoArb,
0
};
int[] values = new int[attribs.Length];
int[] attribs_values = new int[]
{
(int)WGL_ARB_pixel_format.AccelerationArb,
(int)WGL_ARB_pixel_format.FullAccelerationArb,
(int)WGL_ARB_pixel_format.SupportOpenglArb, 1,
(int)WGL_ARB_pixel_format.DrawToWindowArb, 1,
0, 0
};
int[] num_formats = new int[1];
// Get the number of available formats
if (Wgl.Arb.ChoosePixelFormat(window.DeviceContext, attribs_values, null, 0, null, num_formats))
{
// Create an array big enough to hold all available formats and get those formats
int[] pixel = new int[num_formats[0]];
//result differ here from one driver to the other :
//373.06 => num_formats[0] is 66
//378.49 => num_formats[0] is 0
if (Wgl.Arb.ChoosePixelFormat(window.DeviceContext, attribs_values, null, pixel.Length, pixel, num_formats))
{
//for loop to fetch all the modes
}
}
...
如您所见num_formats[0]
,returns 0 新驱动程序版本的有效格式。从这里我猜最有可能的可能性是给定的标志不再正确或者 wglChoosePixelFormatARB
函数中存在一些错误。
看起来它只是找不到 NVIDIA OpenGL 上下文,正在退回到 Windows 附带的古老上下文,并且已经十多年没有更新了。
我唯一设法找到的是 this old issue on the OpenTK repo。它应该在任何最新版本的 OpenTK 中得到修复,但问题可能再次出现。
看起来您已经做了很多工作来隔离问题并使其可重现。为此,用 OpenTK 提出一个 pull request 也不是不可能的。 OpenTK 可能以不同于 GLFW 的方式扫描和调用 wglCreateContextAttribsARB
。
如果您可以查看并比较 GLFW 和 OpenTK 上下文初始化,问题可能会在那里出现。
事实证明,我正在处理的代码库的 OpenTK 代码不是最新的。我上面发布的代码块已经过时了。它实际上看起来像代码来自 mono/opentk repo (the exact code chunk is here). I have looked into ARB extensions loading functions of version 2.0-0 (tag), they change a lot (code here).
底线
我用 version 2.0-0 进行了测试并解决了问题。
感谢罗伯特·鲁哈尼指出这是一个老问题。
问题描述
我一直在使用 OpenTK 在各种 Windows 配置(7、8、8.1、10)和硬件(各种 AMD、nvidia GPU 和英特尔的图形芯片组)上创建 OpenGL 上下文,超过 2 个都没有问题年。
但是由于 nvidia 的 375.63 驱动程序更新和所有后续驱动程序更新(甚至是昨天发布的最新 378.49),当我尝试使用 OpenTK 创建 OpenGL 上下文时,我最终得到了 OpenGL 1.1.0 上下文(供应商:Microsoft公司,渲染器:GDI 通用)。这看起来像是一个“后备”OpenGL 上下文,它当然缺少我需要的大多数 OpenGL 函数。
回滚到 373.06 或更早版本可以解决问题,但不是长期可行的解决方案。
观察
- 我已仔细阅读 nvidia's released notes 但没有发现与该问题相关的任何问题或评论。
- 我怀疑由 OpenTK 创建的句柄初始化的像素格式突然变得不受 nvidia 的驱动程序支持。 (如果需要我可以提供详细信息)
- 我已经使用 glfw 尝试了一些示例 C++ 代码,我可以获得正确的 OpenGL 上下文(版本:4.5.0,供应商:nvidia),因此它似乎不是低级驱动程序问题,而是上下文的创建方式以某种方式被破坏了。
我已开始深入研究 OpenTK 代码以缩小问题范围。 上下文是使用
周围的包装器创建的Delegates.wglCreateContextAttribsARB((IntPtr)hDC, (IntPtr)hShareContext, (int*)attribList_ptr);
此委托是使用 GetProcAddress 函数加载的:
[System.Runtime.InteropServices.DllImport(Wgl.Library, EntryPoint = "wglGetProcAddress", ExactSpelling = true, SetLastError = true)]
internal extern static IntPtr GetProcAddress(String lpszProc);
其中 Wgl.Library 是“OPENGL32.dll”。函数加载正确。
传递的属性只是 GL_MAJOR = 1 GL_MINOR = 0 应该(并且始终具有)return 最新支持的 OpenGL 上下文。我也曾尝试将这些值分别强制为 4 和 5,但没有成功。
specs of wglCreateContextAttribsARB 没有提及任何“回退”上下文。 (注意:我的显卡支持wglCreateContextAttribsARB)
问题
- 有没有人在创建 OpenGL 上下文时遇到过类似的问题,您是如何解决的?
- 两个驱动程序版本之间可能发生了什么变化会破坏这个?
欢迎提供任何帮助或线索。如果需要,我可以详细说明一些具体点。
更新 (26.1.2017)
看来像素模式的获取方式才是问题的根源。初始化步骤尝试检索使用 wglChoosePixelFormatARB
函数的 ARB 模式,并使用新驱动程序获得 0 个有效模式。
这是代码块的相关部分。 (Wgl.Arb.ChoosePixelFormat
是 wglChoosePixelFormatARB
的包装)
...
int[] attribs = new int[]
{
(int)WGL_ARB_pixel_format.AccelerationArb,
(int)WGL_ARB_pixel_format.RedBitsArb,
(int)WGL_ARB_pixel_format.GreenBitsArb,
(int)WGL_ARB_pixel_format.BlueBitsArb,
(int)WGL_ARB_pixel_format.AlphaBitsArb,
(int)WGL_ARB_pixel_format.ColorBitsArb,
(int)WGL_ARB_pixel_format.DepthBitsArb,
(int)WGL_ARB_pixel_format.StencilBitsArb,
(int)WGL_ARB_multisample.SampleBuffersArb,
(int)WGL_ARB_multisample.SamplesArb,
(int)WGL_ARB_pixel_format.AccumRedBitsArb,
(int)WGL_ARB_pixel_format.AccumGreenBitsArb,
(int)WGL_ARB_pixel_format.AccumBlueBitsArb,
(int)WGL_ARB_pixel_format.AccumAlphaBitsArb,
(int)WGL_ARB_pixel_format.AccumBitsArb,
(int)WGL_ARB_pixel_format.DoubleBufferArb,
(int)WGL_ARB_pixel_format.StereoArb,
0
};
int[] values = new int[attribs.Length];
int[] attribs_values = new int[]
{
(int)WGL_ARB_pixel_format.AccelerationArb,
(int)WGL_ARB_pixel_format.FullAccelerationArb,
(int)WGL_ARB_pixel_format.SupportOpenglArb, 1,
(int)WGL_ARB_pixel_format.DrawToWindowArb, 1,
0, 0
};
int[] num_formats = new int[1];
// Get the number of available formats
if (Wgl.Arb.ChoosePixelFormat(window.DeviceContext, attribs_values, null, 0, null, num_formats))
{
// Create an array big enough to hold all available formats and get those formats
int[] pixel = new int[num_formats[0]];
//result differ here from one driver to the other :
//373.06 => num_formats[0] is 66
//378.49 => num_formats[0] is 0
if (Wgl.Arb.ChoosePixelFormat(window.DeviceContext, attribs_values, null, pixel.Length, pixel, num_formats))
{
//for loop to fetch all the modes
}
}
...
如您所见num_formats[0]
,returns 0 新驱动程序版本的有效格式。从这里我猜最有可能的可能性是给定的标志不再正确或者 wglChoosePixelFormatARB
函数中存在一些错误。
看起来它只是找不到 NVIDIA OpenGL 上下文,正在退回到 Windows 附带的古老上下文,并且已经十多年没有更新了。
我唯一设法找到的是 this old issue on the OpenTK repo。它应该在任何最新版本的 OpenTK 中得到修复,但问题可能再次出现。
看起来您已经做了很多工作来隔离问题并使其可重现。为此,用 OpenTK 提出一个 pull request 也不是不可能的。 OpenTK 可能以不同于 GLFW 的方式扫描和调用 wglCreateContextAttribsARB
。
如果您可以查看并比较 GLFW 和 OpenTK 上下文初始化,问题可能会在那里出现。
事实证明,我正在处理的代码库的 OpenTK 代码不是最新的。我上面发布的代码块已经过时了。它实际上看起来像代码来自 mono/opentk repo (the exact code chunk is here). I have looked into ARB extensions loading functions of version 2.0-0 (tag), they change a lot (code here).
底线
我用 version 2.0-0 进行了测试并解决了问题。
感谢罗伯特·鲁哈尼指出这是一个老问题。