3

我不明白这里的一些难题。C++ 开发人员只需调用wglCreateContext一次即可设置上下文(无论是虚拟上下文还是它们的主上下文)。建议 AC# 开发人员调用wglCreateContext 两次来设置上下文(如果第一次调用失败,则忽略第一次调用的结果)。

例如,下面是OpenTK源代码的摘录:

Handle = new ContextHandle(Wgl.Imports.CreateContext(window.DeviceContext));
if (Handle == ContextHandle.Zero)
    Handle = new ContextHandle(Wgl.Imports.CreateContext(window.DeviceContext));
if (Handle == ContextHandle.Zero)
    throw new GraphicsContextException(
        String.Format("Context creation failed. Wgl.CreateContext() error: {0}.",
            Marshal.GetLastWin32Error()));

据我了解,opengl32.dll似乎覆盖了一些公开的 API gdi32.dll(例如ChoosePixelFormat),因此加载这些 DLL 的顺序很重要。对于 C++,我认为这意味着链接库的顺序很重要。使用 C#,您不需要链接库,并且DllImport会进行延迟加载,因此我认为两次调用该函数会以某种方式最终使排序正确。

谁能确认发生了什么?

4

1 回答 1

1

这是正确的,微软的可安装客户端驱动程序(ICD)/迷你客户端驱动程序模型用于 OpenGL 的奇怪后果之一。如果您可以设法调用opengl32.dll不在其中的函数gdi32.dll(其中有很多),则可以让 C# 在opengl32.dllgdi32 之上 import 的符号表。

您可能只需glGetError (...)在开始创建上下文的过程之前立即调用即可完成同样的事情。显然,在glGetError (...)没有活动上下文的情况下调用是错误的,但这不是重点——您只需要一个 API 调用就可以开始导入 DLL 符号。

在 C/C++ 中要容易得多,因为到 DLL 的链接在构建时部分解决(DLL 导入顺序由链接器开关中的库顺序建立)。在 C/C++ 中,只需在 opengl32.lib 之前链接到 gdi32.lib 即可解决此问题。

这个想法是相同的,ChoosePixelFormat (...)必须被硬件供应商分发的 OpenGL ICD 覆盖,以便将请求的格式参数与一组硬件加速像素格式相匹配。如果您使用 gdi32 的版本,ChoosePixelFormat (...)您将永远无法获得任何硬件加速的像素格式,只有糟糕的基于软件的 OpenGL 1.1 参考实现,自 Windows NT/95 OSR2 以来一直在 GDI 之上分层。显然没有人想要这样,因为参考实现是不可扩展的,如果你最终使用 GDI 像素格式,你将永远停留在 OpenGL 1.1 中。

于 2013-09-29T22:17:54.003 回答