【问题标题】:How does OpenGL find the implementation to use on Windows?OpenGL 如何找到在 Windows 上使用的实现?
【发布时间】:2016-10-09 21:50:05
【问题描述】:

我有一个通过 JOGL 使用 OpenGL 的 Java 程序,并且有一些只出现在我想调试的 Windows 上的错误。为此,我尝试用Windows设置备用计算机,但在调试程序时遇到了一个奇怪的问题:

当我通过 Java Web Start“正常”运行程序时,它可以正常运行,但是当我编译程序并尝试通过命令行 java 启动器或通过 NetBeans 运行它时(我认为确实如此)同样的东西),它似乎使用了一种不同的非常原始的 OpenGL 实现,它不支持可编程着色或任何东西。

在研究问题时,我让自己明白,在 Windows 上运行的 OpenGL 程序会加载 opengl32.dll,这显然是 Windows 附带的一个通用库(如果我错了,请纠正我)并反过来加载“真正的”OpenGL 实现并将 OpenGL 函数调用转发给它。 (这似乎也有点用词不当,因为它实际上是在一个明显高于 232 的基地址处加载到一个 64 位进程中的。)

使用 Process Explorer,我看到,当我在 Java Web Start(它工作的地方)下运行程序时,它会加载库 ig4icd64.dll,我假设它是英特尔 GPU 驱动程序的实际 OpenGL 实现库;而当尝试通过java.exe 运行程序时,会加载opengl32.dll,但从未加载过ig4icd64.dll,这似乎证实了我对它使用不同的OpenGL 实现的怀疑。

所以这就引出了主要问题:opengl32.dll 如何选择要使用的 OpenGL 实现,我如何影响这个选择以确保加载正确的实现?有什么方法可以调试这个? (这两个上下文之间有什么不同导致它选择不同的实现?在这两种情况下,都使用了 64 位 Java,因此应该不会混淆 32 位或 64 位实现。)

更新:我在 Microsoft 的网站上找到了 this page,它声称 OpenGL ICD 是通过 HKLM/System/CurrentControlSet/Control/Class/{Adapter GUID}/0000/ 注册表项中的 OpenGLDriverName 值找到的。该值确实正确包含ig4icd64.dll,然而,也许更奇怪的是,使用进程监视器来监视Java 进程的系统调用(如果这是正确的Windows 术语)表明它从未尝试访问该密钥。我不能说我知道这是否意味着这篇文章不正确,或者我是否错误地使用了进程监视器,或者是否是其他原因。

【问题讨论】:

    标签: windows opengl


    【解决方案1】:

    在研究问题时,我让自己明白,在 Windows 上运行的 OpenGL 程序会加载 opengl32.dll,这显然是 Windows 附带的一个通用库(如果我错了,请纠正我),然后加载“真正的”OpenGL 实现并将 OpenGL 函数调用转发给它。

    是的,这正是它的工作原理。 opengl32.dll 充当可安装客户端驱动程序 (ICD) 和使用 OpenGL 的程序之间的管道。

    所以这就引出了主要问题:opengl32.dll 如何选择要使用的 OpenGL 实现,我如何影响这个选择以确保加载正确的实现?有什么方法可以调试这个?

    它根据窗口类标志进行选择(这不是 Java 类,而是作为 Windows API 一部分的窗口的一组设置,请参阅https://msdn.microsoft.com/en-us/library/windows/desktop/ms633577(v=vs.85).aspx 了解详细信息),窗口样式标记 像素为窗口设置格式、窗口的位置(这意味着它在哪个屏幕和图形设备上)和上下文创建标志。

    例如,如果您将其作为服务启动,则根本没有图形设备可以在其上创建窗口。如果您要在远程桌面会话中启动它,它将在无头软件光栅器实现上运行。

    我不知道 CLI java 解释器与 WebStart 有何不同的具体细节。但是 IIRC 你使用javaw(注意额外的w)作为GUI 程序。


    (这似乎也有点用词不当,因为它实际上是在一个 64 位进程中加载​​的,基地址明显高于 2^32。)

    不仅仅是opengl32.dll,而是所有 Windows 系统 DLL,即使在 64 位环境中也被命名为 …32,它们甚至位于 \Windows\System32 以增加混乱。原因很简单:编译 64 位时源代码级别向后兼容。如果所有库名称都已更改为 ...64,那么为 64 位环境编译程序 all 必须将字符串文字和对库的引用重命名为 ...64。

    如果它让您对命名感觉更好,请将 ...32 视为版本指示符,而不是体系结构:Win32 API 是为 Windows 9x 和 Windows NT 3 并行开发的,所以请记住…32 代表 “为 Windows NT 3.2 创建的 API 版本”

    【讨论】:

    • 感谢您的描述,但我不确定它是否会提出问题。有没有办法调试选择过程,或者可能有足够详细的描述,我可以手动按照它来重现错误? opengl32.dll 是否支持某种日志记录之类的?
    • 哦,只是为了记录,使用javaw而不是java没有区别。
    • @Dolda2000:不幸的是,OpenGL 的调试能力非常有限。 OpenGL-4 确实引入了许多调试工具,但不幸的是,这些工具仅在上下文创建很久之后才起作用。但是,您描述的问题非常不寻常,并且系统安装不正确。我可以建议您在系统上查找opengl32.dll 的任何实例。在正确安装的环境中,可能只存在其中两个:\Windows\System32 中的一个和\Windows\SysWoW64 中的一个。
    • "系统安装不当的味道" -- 这听起来很奇怪,因为系统是为了这个目的而新安装的。再说一次,既然是这样,我想如果我重新安装它看看是否有帮助,这不会有什么坏处。我会尝试一些东西。
    • @Dolda2000:如果这是全新安装,那么什么都不应该关闭。您是否安装了从 GPU 制造商网站下载的驱动程序?由 Windows 自动安装驱动程序的默认全新 Windows 安装缺乏适当的 OpenGL 支持。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-21
    • 1970-01-01
    • 1970-01-01
    • 2012-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多