代码之家  ›  专栏  ›  技术社区  ›  Roel

OpenGL版本和GPU-有什么兼容性?

  •  5
  • Roel  · 技术社区  · 16 年前

    我试图理解图形卡版本、OpenGL版本和API头是如何协同工作的。我在OpenGL论坛和其他地方读过OpenGL 2.0/3.0/3.1的崩溃,但作为一个开发人员(OpenGL的新手),这对我来说仍然不清楚。(顺便说一句,我在这个问题中使用Nvidia作为例子,因为我正在购买他们的卡,但显然我想成为我开发的软件的供应商不可知论者)。

    首先,GPU需要支持OpenGL版本。但是,例如,Nvidia有用于支持OpenGL3的老式显卡的驱动程序。这是否意味着这些驱动程序在软件中实现某些功能,以模拟硬件中没有的新功能?

    然后是API头。如果我决定为OpenGL3编写一个应用程序,我应该等到Microsoft发布一个支持此版本的带有头部的平台SDK的更新版本吗?如何选择要使用的API版本-通过在代码中定义的预处理器,或者更新到最新的平台SDK只是升级到最新的版本(无法想象最后一个选项,但您永远不知道…)。

    向后兼容性呢?如果我编写一个针对OpenGL 1.2的应用程序,为支持OpenGL 3的卡安装了驱动程序的用户是否仍然能够运行它,或者我应该在我的应用程序中测试卡的功能/支持的版本?阅读 http://developer.nvidia.com/object/opengl_3_driver.html 似乎可以确认,至少对于Nvidia卡,针对1.2编写的应用程序将继续工作,但这也意味着其他供应商可能会停止支持1.2 API。基本上,这将使我(潜在地)在未来的位置上,软件不会与最近的卡一起工作,因为它们不再支持1.2。但如果我现在为OpenGL3甚至是2开发,我可能会将GPU唯一支持1.2的用户拒之门外。

    我不需要OpenGL中那些花哨的特性——我几乎不使用任何阴影,固定管道对我来说很好(我的应用程序类似于CAD)。新应用程序的最佳版本是什么,期望它在未来几年将是一个具有增量更新的长寿命应用程序?

    我可能忘记了与此相关的其他问题,任何见解都会受到赞赏。

    3 回复  |  直到 11 年前
        1
  •  7
  •   Anthony Johnson    16 年前

    根据我的OpenGL经验,似乎“瞄准”给定版本只是访问为该版本添加的各种扩展。因此,您“瞄准”OpenGL版本3的唯一原因是,如果您想使用版本3中的一些新扩展。如果您没有真正使用版本3扩展(如果您只是在做基本的OpenGL工作),那么您自然不会“瞄准”版本3。

    在Visual Studio中,您将始终将应用程序链接到OpenGL32.lib,并且OpenGL32.lib不会在不同的OpenGL版本之间发生更改。OpenGL使用wglgetprocAddress()在运行时而不是编译时动态访问OpenGL扩展/版本。也就是说,如果给定的驱动程序不支持扩展,那么当请求扩展的过程时,wglgetProcAddress()将在运行时返回空值。因此,在代码中,您需要实现处理空返回情况的逻辑。在最简单的场景中,您只需打印一个错误并说“此功能不可用,因此该程序将运行…”。或者,您可以找到其他替代方法来执行不使用扩展名的相同操作。在大多数情况下,如果您的应用程序运行在不支持OpenGL版本的旧硬件/驱动程序上,而该版本添加了您要查找的扩展,那么您只能从wglgetprocAddress获得空返回。然而,在未来的几年里,您将希望了解到那些新的OpenGL版本决定要放弃的东西。我对3.1规范没有太多了解,但很明显他们引入了一个不推荐的模型,其中旧的技术/扩展可能会被否决,这将为新的硬件/驱动程序打开大门,不再支持不推荐的扩展,在这种情况下,wglgetprocaddress将再次为这些扩展返回空值。因此,如果您将处理wglgetProcAddress()上的空返回的逻辑放入,那么即使对于不推荐使用的扩展,您仍然可以使用。您可能需要实现更好的替代方案,或者使更新的扩展成为默认扩展。

    就版本化的API头而言,对头的更改主要是为了允许访问wglgetProcAddress()返回的新函数而进行的更改。因此,如果您包含版本2的API头文件,那么只要您只需要OpenGL2的扩展就可以了。如果您需要访问在版本3中添加的函数/扩展,那么您只需将版本2的头替换为版本3的头,它只会添加一些与新扩展相关联的额外函数指针typedef,以便在调用wglgetprocAddress()时,可以将返回值强制转换为右侧的函数指针。例子:

    PFNGLGENQUERIESARBPROC glGenQueriesARB = NULL;
    
    ...
    
    glGenQueriesARB = (PFNGLGENQUERIESARBPROC)wglGetProcAddress("glGenQueriesARB");
    

    在上面的示例中,pfnglgenqueriesarbproc的typedef在API头中定义。我相信glgenqueriesarb是在1.2中添加的,所以我至少需要1.2api头来获取pfnglgenqueriesarbproc的定义。所有的标题都是这样的。

    关于3.1,我想再提一件事。显然,在3.1版本中,它们贬低了许多OpenGL功能,我的公司已经广泛使用这些功能,包括显示列表、glbegin/glend机制和gl-select呈现模式。我对细节不太了解,但我不知道他们如何在不创建新的opengl32.lib链接的情况下做到这一点,因为大多数功能似乎嵌入到opengl32.lib中,而不是通过wglgetprocaddress访问。另外,微软会在他们的Visual Studio版本中包含新的opengl32.lib吗?我对这些问题没有答案,但我认为,即使3.1否定了它,这个功能仍将存在很长一段时间。如果您继续与当前的opengl32.lib链接,它将继续工作,几乎是无限期的,尽管您可能会在某一点上失去硬件加速。Web上提供的大多数OpenGL教程都使用glbegin/glend方法绘制原语。尽管许多硬件不再加速GL U选择渲染模式,但对于GL U选择也是如此。甚至OpenGL.org的教程也使用了据称已被弃用的glbegin/glend方法。我还没有找到一个只使用3.1功能的“入门”教程,避免使用不推荐使用的功能(当然,如果有人知道,请链接我)。不管怎样,虽然3.1似乎已经抛弃了很多旧的东西来换新的东西,但我认为旧的东西仍然会存在很长一段时间。

    长话短说,这是我的建议。如果您的OpenGL需求很简单,只需使用基本的OpenGL功能即可。版本1.1-3.1支持顶点数组,因此如果您正在寻找最长的生存期,并且正在重新开始,那么这可能是您应该使用的。不过,我的观点是glbegin/glend,显示列表在一段时间内仍然存在,即使在版本3中它们被否决了,所以如果您想使用它们,我不会担心太多。我将避免选择GL U模式,选择另一种方法。许多硬件供应商认为gl-select已经被弃用多年了,尽管它刚刚被版本3弃用。在我们的应用程序中,我们会遇到许多问题,在这些问题上,它不能在ATI卡和集成GMA卡上工作。随后,我们使用遮挡查询实现了一种选择方法,似乎可以解决这个问题。因此,要在第一次正确执行,请避免GL_选择。

    祝你好运。

        2
  •  2
  •   basszero    16 年前

    就驱动程序而言,我认为在某些情况下,它缺少用软件编写的功能。使用OpenGL(除了加速之外)的关键是写入API,而不关心它是如何实现的。

    根据我的经验,您不会声明OpenGL版本。API版本之间的函数调用不重叠。注意规范,例如,如果调用2.0方法,则应用程序的最低版本刚刚变为2.0。我有针对OpenGL(愚蠢的老Sun视频卡)的显示应用程序,它在全新的Nvidia 200系列卡上工作得很好。

    我认为无论如何都不能保证将来API不会改变,特别是如果你不控制它的话。当我们使用OpenGL6.4时,您的应用程序可能会在10年内停止工作。希望您已经编写了一个足够好的应用程序,客户愿意为升级付费。

        3
  •  0
  •   Marc Clint Dion    11 年前

    这个叫MarkJ.Kilgard的家伙从90年代开始就在OpenGL上发布Nvidia源代码和文档,并且一直代表着游戏硬件领域两个最大的公司之一发布。

    /——————————————————————————————————————————————————————————————————————————————————————————————————————————————————--- …认为OpenGL应用程序使用即时模式是“错误的”的想法是过于狂热的。OpenGL3.0规范甚至已经将OpenGL中的即时模式标记为“取消预测”(无论什么意思!)这种极端主义适得其反,愚蠢至极。鼓励良好的API使用的正确方法不是试图贬低或禁止API使用,而是教育开发人员在特定情况下正确的API使用。