我不明白这里的一些难题。 C ++开发人员只需调用wglCreateContext
一次即可设置上下文(无论是虚拟上下文还是主上下文)。建议C#开发人员调用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
似乎覆盖了gdi32.dll
公开的一些API(例如ChoosePixelFormat
),从而使这些DLL加载的顺序变得重要。使用C ++,我认为这意味着链接库的顺序很重要。使用C#,您不会链接库,而DllImport
会lazy loading,所以我认为调用该函数两次以某种方式获得最终的排序。
任何人都可以确认发生了什么吗?
答案 0 :(得分:1)
这是正确的,这是微软用于OpenGL的可安装客户端驱动程序(ICD)/迷你客户端驱动程序模型的一个奇怪后果。如果您可以设法调用opengl32.dll
中不在gdi32.dll
中的函数(其中有很多),您可以通过C#导入opengl32.dll
的符号表顶部gdi32
您可以在开始创建上下文的过程之前立即调用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。