OpenGL 3.+ glsl 兼容性一团糟?

Posted

技术标签:

【中文标题】OpenGL 3.+ glsl 兼容性一团糟?【英文标题】:OpenGL 3.+ glsl compatibility mess? 【发布时间】:2013-11-23 10:12:34 【问题描述】:

所以,我搜索了很多 opengl 3.+ 教程,都包含着色器(GLSL 330 核心)。但是,我没有支持这些较新的 GLSL 实现的显卡,要么我必须更新我的驱动程序,但我仍然不确定我的卡是否能够支持它。

目前我的 openGL 版本是 3.1,我在 Windows 上使用 C++ 创建了一个具有向后兼容性的现代上下文。我的 GLSL 版本是 1.30,通过 NVIDIA Cg 编译器(完整定义)和 GLSL 1.30 -> 版本 130。

问题是:版本 130 完全基于传统的 opengl 管道,因为它包含 viewmatrix、modelmatrix 等内容。那么当我在客户端应用程序(OpenGL 3)中使用核心功能时,我应该如何使用它们+)?

这真是令人困惑,给我具体的例子。

此外,我希望我的应用程序能够在大多数 OpenGL 实现上运行,那么您能告诉我传统 GLSL 和现代 GLSL 之间的边界在哪里吗? GLSL 300 是现代的 GLSL,是否兼容 OpenGL 3.+ 和旧 GLSL 版本?

【问题讨论】:

仅仅因为存在这些内置的制服变量并不意味着您不能创建自己的制服并使用它们。不,GLSL 130 完全基于旧版 OpenGL。 【参考方案1】:

我会说 OpenGL 3.1 是现代的 OpenGL。

任何支持 OpenGL 3.1 的硬件都能够支持 OpenGL 3.3。驱动程序是否始终支持它是另一回事。更新你的显卡可能会让你升级到 OpenGL 3.3。

为了澄清这一点,OpenGL 3.1 不是旧版 OpenGL。

旧版 OpenGL 将是:

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(90.0, 0.0, 1.0, 0.0);
glTranslatef(0.0, 0.0, -5.0);

具有兼容性上下文的 OpenGL 3.1 支持哪个,但这并不意味着应该使用它。如果您正在为支持 OpenGL 3 的硬件进行开发,您绝对不应该使用它。您可以通过请求核心上下文来禁用旧版功能。

如果您正在使用着色器,那么您已经移除了传统的固定功能管道。所以 GLSL 130 不是遗留的:P.

使用我的英特尔 CPU 在我的 Linux 笔记本电脑上工作,其中最新的稳定驱动程序仅在 OpenGL 3.1(是的 OpenGL 3.3 提交已经到位,但我正在等待 MESA 10 ;))我已经毫不费力地能够无需接触旧版 OpenGL,即可在我的机器上运行 OpenGL 3.3 教程。

OpenGL 的一大优点是您可以使用 OpenGL 扩展来扩展功能。即使您的硬件无法处理 OpenGL 4.4,您仍然可以使用不需要 OpenGL 4 硬件和更新驱动程序的扩展!

请参阅https://developer.nvidia.com/opengl-driver 和http://developer.amd.com/resources/documentation-articles/opengl-zone/,了解有关旧硬件添加了哪些功能的信息,但如果您不确定,您只需在您的硬件上进行测试即可。

最后我会说 Legacy OpenGL 也有它的位置。

在我看来,传统 OpenGL 可能比现代 OpenGL 更容易学习,因为您不需要着色器和 OpenGL 缓冲区的知识来绘制您的第一个三角形,但我认为您不应该在现代生产中使用它应用。

如果您需要对旧硬件的支持,您可能需要使用旧的 OpenGL 版本。即使是现代 CPU 也支持 OpenGL 3,所以我不会太担心这一点。

从 OpenGL 3.3 转换到 OpenGL 3.0

我在http://www.opengl-tutorial.org/ 的教程中对其进行了测试。我不能把我转换的代码放上去,因为大部分都是教程中的,我没有权限把代码放在这里。

他们的作者谈到了 OpenGL 3.1,但由于他的上限为 glsl 130 (OpenGL 3.0),我正在转换为 3.0。

    首先将上下文版本更改为 OpenGL 3.0(只需更改 如果您从教程中工作,则次要版本为 0)。如果您使用 OpenGL 3.0,也不要将其设置为使用核心上下文,因为据我所知 ARB_compatibility 仅适用于 OpenGL 3.1。

    将着色器版本更改为

    #version 130
    

    删除着色器中的所有布局绑定

     layout(location = #) in vec2 #myVarName;
    

     in vec2 #myVarName;
    

    使用 glBindAttribLocation 绑定指定的 in 布局(参见 3)

    例如

    glBindAttribLocation(#myProgramName, #, "#myVarName");
    

    使用glBindFragDataLocation 绑定指定的输出布局(参见3)

    例如

    glBindFragDataLocation(#myProgramName, #, "#myVarName");
    

    glFramebufferTexture 在 OpenGL 3.0 中不起作用。 (用于阴影贴图和延迟渲染等)。相反,您需要使用glFramebufferTexture2D。 (它有一个额外的参数,但文档就足够了)

这里是tutorial16的截图(我虽然这个涵盖了大部分领域,并用这个测试看看是否需要所有这些)

tutorial16 的来源有误(在撰写本文时)。 FBO 设置为没有颜色输出,但片段着色器仍然输出颜色值,导致段错误(尝试写入任何内容通常会这样做)。只需将深度片段着色器更改为不输出任何内容即可修复它。 (不会对更宽容的驱动程序产生段错误,但这不是你应该讨价还价的东西)

【讨论】:

好的,但是你能告诉我,我应该如何在没有遗留函数的情况下将 GLSL 130 与 OpenGL 3.1 现代上下文一起使用,着色器即期望遗留矩阵,而 GLSL 130 不适合 openGL 3.3 核心?请澄清我如何在这种情况下使用它 @user209347 “着色器即期望遗留矩阵”。嗯,不,你为什么这么认为。强迫某人使用已弃用的功能是愚蠢的(为什么首先要弃用它们)。您可以使用核心 3.3 上下文运行 GLSL 130,但它们没有 GLSL 330 所没有的所有功能。最值得注意的是,它们不允许在着色器中指定顶点属性位置,但您可以使用 glBindAttribLocation 进行设置。 @user209347 如果您认为这有助于您理解,也许我可以为您将 OpenGL 3.3 示例转换为 OpenGL 3,1。 @user209347 我添加了如何在不使用旧功能的情况下从 opengl 3.3 转换为 3.0。如果您还有任何问题,请随时提出。 非常好,非常感谢!谢谢!但是你能帮我决定吗,我想编写一个能够在多个硬件/旧版本的 OpenGL 以及新的现代 OpenGL 上运行的引擎。我是否需要编写相同职责的多个着色器并检查 glsl 版本以确定加载一个?对于较旧的 glsl 中不可用的功能,是否有可能的解决方法?最终可能会有很多着色器;p

以上是关于OpenGL 3.+ glsl 兼容性一团糟?的主要内容,如果未能解决你的问题,请参考以下文章

openGL之API学习(一七三)glsl如何设置版本和兼容性

我的OpenGL学习进阶之旅OpenGL ES 3.0和向后兼容性

我的OpenGL学习进阶之旅OpenGL ES 3.0和向后兼容性

OpenGL核心和兼容性[关闭]

显卡OpenGL兼容问题

glVertexAttribPointer 问题(OpenGL 3.x 前向兼容上下文)