2009-06-05 93 views
5

我想了解图形卡版本,OpenGL版本和API标头如何一起工作。我已经阅读了OpenGL论坛和其他地方的OpenGL 2.0/3.0/3.1的崩溃消息,但是作为开发人员(OpenGL的新手),我还不清楚这会如何解决。 (顺便说一句,我在这个问题中使用nVidia作为例子,因为我正在购买他们的一张卡片,但很显然,我想成为我开发的软件的供应商不可知论者)。OpenGL版本和gpus - 有什么样的兼容性?

首先,有GPU需要支持OpenGL版本。但例如nVidia有支持OpenGL 3的旧版视频卡的驱动程序。这是否意味着这些驱动程序在软件中实现某些功能以模拟不在硬件中的新功能?

然后有API头。如果我决定编写OpenGL 3的应用程序,我应该等到微软发布支持此版本的标题的平台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。但是如果我今天为OpenGL 3或者甚至2开发,我可能会拒绝那些只有gpu支持1.2的用户。

我不需要OpenGL中的奇特功能 - 我几乎不使用任何阴影,固定管道对我来说工作正常(我的应用程序类似于CAD)。基于新应用程序的最佳版本是什么?预计它将是一个长期的应用程序,在未来几年会有增量更新?

我可能会忘记在这方面有关的其他问题,任何见解都非常感谢。

回答

7

从我的OpenGL体验来看,“定位”给定版本只是访问为该版本添加的各种扩展。所以你要“瞄准”OpenGL版本3的唯一原因是你想使用一些新的版本3的扩展。如果你没有真正使用版本3的扩展(如果你只是做基本的OpenGL的东西) ,那么你自然不会“定位”版本3。

在Visual Studio中,您将始终将您的应用程序与opengl32.lib链接起来,并且opengl32.lib不会跨越不同的OpenGL版本进行更改。 OpenGL改为使用wglGetProcAddress()在运行时动态访问OpenGL扩展/版本,而不是在编译时。也就是说,如果一个给定的驱动程序不支持扩展名,那么wglGetProcAddress()将在请求该扩展程序的运行时返回NULL。所以在你的代码中,你需要实现处理NULL返回大小写的逻辑。在最简单的情况下,你可以打印一个错误,并说“这个功能不可用,所以这个程序将表现...”。或者你可以找到其他可选方法来做同样的事情,而不使用扩展名。大多数情况下,如果您的应用程序运行在不支持OpenGL版本的旧硬件/驱动程序上,那么您只能从wglGetProcAddress获得NULL返回值,该OpenGL版本添加了您要查找的扩展程序。但是,在未来的几年中,您会希望了解更新的OpenGL版本决定弃用的东西。我没有太多地阅读3.1规范,但显然他们引入了一个弃用模型,其中旧的技术/扩展可能会被弃用,这将为更新的硬件/驱动程序打开大门,不再支持不推荐的扩展,在这种情况下wglGetProcAddress将再次为这些扩展返回NULL。所以,如果你把逻辑放在wglGetProcAddress()上处理NULL返回值,即使是不推荐使用的扩展,你也应该没问题。您可能需要实施更好的替代方案,或者使新的扩展默认。

就版本化的API头文件而言,对头文件的更改大多只是允许访问由wglGetProcAddress()返回的新函数的更改。因此,如果您包含版本2的API标头,那么只要您只需要OpenGL 2的扩展就可以使用。如果您需要访问版本3中添加的功能/扩展,那么您只需替换您的版本2头与版本3头,它只是增加了一些额外的函数指针类型定义与新的扩展相关联,所以当你调用wglGetProcAddress()时,你可以将返回值转换为正确的函数指针。示例:

PFNGLGENQUERIESARBPROC glGenQueriesARB = NULL; 

... 

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

在上面的示例中,PFNGLGENQUERIESARBPROC的typedef是在API标头中定义的。 glGenQueriesARB被添加到1.2我相信,所以我需要至少1.2 API头来获得PFNGLGENQUERIESARBPROC的定义。这就是所有的标题。

还有一件事我想谈谈3.1。很明显,在3.1中,他们正在弃用很多我公司非常普遍使用的OpenGL功能,包括显示列表,glBegin/glEnd机制和GL_SELECT渲染模式。我对细节知之甚少,但我没有看到他们如何创建一个新的opengl32.lib来连接,因为它似乎大部分功能都嵌入到了opengl32.lib中,并且不通过wglGetProcAddress访问。另外,微软是否会将这个新的opengl32.lib包含在他们的Visual Studio版本中?我对这些问题没有答案,但我认为,即使3.1弃用它,这个功能将会持续很长时间。如果你保持与当前的opengl32.lib链接,它应该继续几乎无限期地工作,虽然你可能会在某个时候失去硬件加速。 Web上可用的绝大多数OpenGL教程都使用glBegin/glEnd方法绘制图元。 GL_SELECT也是如此,尽管很多硬件不再加速GL_SELECT渲染模式。即使是opengl.org的教程也使用了被推荐使用的glBegin/glEnd方法。我还没有找到仅使用3.1功能的“入门”教程,避免了不推荐使用的功能(当然,如果有人知道其中的一个,请将其与我联系)。无论如何,虽然看起来3.1已经抛弃了很多旧的东西,但我认为旧的东西仍然会存在很长一段时间。

长话短说,这是我的建议。如果你的OpenGL需求很简单,那就使用基本的OpenGL功能。顶点数组在版本1.1-3上受支持。1,所以如果你正在寻找最大的生命,并且你开始新鲜,那可能就是你应该使用的。不过,我的意见是glBegin/glEnd,即使它们在版本3中被弃用,显示列表仍然会存在一段时间,所以如果你想使用它们,我不会太担心。我会避免使用GL_SELECT模式来选择替代方法。许多硬件供应商已经将GL_SELECT视为已弃用多年,尽管它刚刚在版本3中被弃用。在我们的应用程序中,我们发现很多问题,它在ATI卡和集成GMA卡上不起作用。随后,我们实施了一个采用遮挡查询的拾取方法,这似乎解决了问题。所以要第一次正确地做,避免GL_SELECT。

祝你好运。

2

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

根据我的经验,您不要声明OpenGL版本。 API版本之间的函数调用不重叠。请注意规范,例如,如果您调用2.0方法,那么您的应用程序的最低版本就变成了2.0。我有针对OpenGL(愚蠢的旧的Sun视频卡)编写的显示应用程序,它在全新的nvidia 200系列显卡上工作得很好。

我不认为有任何事情可以保证api将来不会改变;特别是如果你不控制它。当我们使用OpenGL 6.4时,您的应用程序可能会在10年内停止工作。希望你已经写了一个足够好的应用程序,客户愿意为升级付费。

0

这位研究员MarK J. Kilgard自90年代以来一直在openGL上发布nVidia源代码和文档,并一直代表游戏硬件领域的两个大腕之一。

// -------------------------------------------- ----------------------------------------- ...这个概念一个OpenGL应用程序对于使用即时模式是“错误的”是过分热心的。 OpenGL 3.0规范甚至将OpenGL中的即时模式标记为“不赞成”(无论这意味着什么!);这种极端主义是相反的,愚蠢的。鼓励良好API使用的正确方法不是试图反对或禁止API使用,而是教育开发人员在特定情况下使用正确的API。

+0

为了教育开发人员关于特定情况下正确的API使用的精神,我想补充一点:`即时模式=提交的'几何体'数量与API调用数量之间的线性相关性零开销)。 – Gigi 2013-07-19 11:10:30