使用 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 或更早版本可以解决问题,但不是长期可行的解决方案。

观察

我已开始深入研究 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)

问题

欢迎提供任何帮助或线索。如果需要,我可以详细说明一些具体点。

更新 (26.1.2017)

看来像素模式的获取方式才是问题的根源。初始化步骤尝试检索使用 wglChoosePixelFormatARB 函数的 ARB 模式,并使用新驱动程序获得 0 个有效模式。

这是代码块的相关部分。 (Wgl.Arb.ChoosePixelFormatwglChoosePixelFormatARB 的包装)

 ...
 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 进行了测试并解决了问题。

感谢罗伯特·鲁哈尼指出这是一个老问题。