我试图了解显卡版本,OpenGL版本和API标头如何协同工作.我已经阅读了OpenGL论坛和其他地方的OpenGL 2.0/3.0/3.1崩溃,但目前还不清楚这对我作为开发人员(OpenGL新手)的影响.(顺便说一句,我在这个问题中使用nVidia作为一个例子,因为我正在购买他们的一张卡,但显然我希望与我开发的软件不相关供应商).
首先,GPU需要支持OpenGL版本.但是,例如nVidia有较旧的视频卡驱动程序支持OpenGL 3.这是否意味着这些驱动程序在软件中实现某些功能来模拟硬件中没有的新功能?
然后是API标头.如果我决定为OpenGL 3编写一个应用程序,我应该等到Microsoft发布带有支持该版本的标头的平台SDK的更新版本吗?你如何选择使用哪个版本的API - 通过代码中的预处理器定义,或者更新到最新平台SDK只需升级到最新版本(无法想象最后一个选项,但你永远不知道. ..).
向后兼容性怎么样?如果我编写一个针对OpenGL 1.2的应用程序,为其支持OpenGL 3的卡安装驱动程序的用户是否仍然可以运行它,或者我应该在我的应用程序中测试该卡的功能/支持的版本?阅读http://developer.nvidia.com/object/opengl_3_driver.html似乎确认至少对于针对1.2编写的nVidia卡应用程序将继续工作,但这也意味着其他供应商可能会停止支持1.2 API.基本上,这将使我(可能)处于未来的位置,软件将无法使用最近的卡,因为它们不再支持1.2.但是,如果我今天为OpenGL 3甚至2开发,我可能会拒绝那些只支持gpu的用户1.2.
我不需要OpenGL中的奇特功能 - 我几乎不使用任何着色,固定管道对我来说很好(我的应用程序是类CAD).什么是基于新应用程序的最佳版本,期望它将成为一个长期存在的应用程序,并在未来几年内进行增量更新?
我可能忘记了在这种情况下相关的其他问题,我们非常感谢任何见解.
从我的OpenGL经验来看,似乎"定位"给定版本只是访问为该版本添加的各种扩展.因此,你想要"定位"OpenGL版本3的唯一原因是你想要使用一些新版本3的扩展.如果你没有真正使用版本3扩展(如果你只是在做基本的OpenGL东西)那么你自然不会"瞄准"版本3.
在Visual Studio中,您始终将应用程序与opengl32.lib链接,并且opengl32.lib不会在不同的OpenGL版本之间进行更改.相反,OpenGL使用wglGetProcAddress()在运行时而不是在编译时动态访问OpenGL扩展/版本.也就是说,如果给定的驱动程序不支持扩展,那么当请求该扩展的过程时,wglGetProcAddress()将在运行时返回NULL.因此,在您的代码中,您将需要实现处理NULL返回情况的逻辑.在最简单的情况下,您可以只打印错误并说"此功能不可用,因此该程序将表现......".或者您可以找到其他替代方法来执行不使用扩展的相同方法.在大多数情况下,如果应用程序在不支持添加了您正在寻找的扩展的OpenGL版本的旧硬件/驱动程序上运行,则只能从wglGetProcAddress返回NULL.但是,在未来几年中,您需要及时了解较新的OpenGL版本决定弃用的内容.我没有读过3.1规范,但显然他们引入了一个弃用模型,旧技术/扩展可能会被弃用,这将为更新的硬件/驱动程序打开大门,不再支持弃用的扩展,在这种情况下wglGetProcAddress将再次为这些扩展返回NULL.因此,如果您将逻辑放在wglGetProcAddress()上处理NULL返回,那么即使对于不推荐使用的扩展,您仍应该没问题.您可能有必要实施更好的替代方案,或者更新默认扩展.
对于版本化的API标头,对标头的更改大多只是更改,以允许访问wglGetProcAddress()返回的新函数.因此,如果您包含版本2的API标头,只要您只需要OpenGL 2的扩展,就可以继续使用.如果您需要访问在版本3中添加的功能/扩展,那么您只需更换您的版本带有版本3标头的2标头,它只是添加了一些与新扩展相关联的附加函数指针typedef,这样当你调用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访问.此外,微软是否会在其Visual Studio版本中包含新的opengl32.lib?我没有对这些问题的答案,但我认为,即使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.
祝好运.