带和不带着色器的 VBO OpenGL C++
Posted
技术标签:
【中文标题】带和不带着色器的 VBO OpenGL C++【英文标题】:VBO with and without shaders OpenGL C++ 【发布时间】:2013-12-22 16:07:09 【问题描述】:我正在尝试实现现代 OpenGL,但问题是:大多数教程都是基于 3.3+,并且谈论 GLSL 330,我只有 GLSL 130。因此,很多事情显然不同,因为我的 VBO 不起作用。
您能给我一些一般提示或教程来解释如何将 GLSL 130 与 VBO 一起使用吗?在我的情况下,我加载了 vbo,但是当我使用我的着色器程序时,只有用 glVertex 调用的顶点被渲染,就像 vbo 被忽略(没有输入)。如何解决?
你能在没有着色器的情况下使用 VBO 吗?我试图这样做,但它崩溃了......
【问题讨论】:
VBO 和着色器(以及着色器版本)在 GL 中是完全正交的功能。 (现代 GL 只需要两者。)是什么让您认为“您的 VBO 不起作用”,仅仅因为您使用 GLSL 1.30 而不是 3.30? 正如我所说,它们对我来说是新的,所以我按照教程进行操作,但大多数教程(或我找到的所有教程)都是针对 330 GLSL 的。比如layout(=0)或者sth在130中不存在,gl_modelview_matrix等可能在330中不存在。我简直不知道从哪里开始... 你混淆了很多不同的东西。 不幸的是,现在 OpenGL 编程的这一方面对于试图学习的人来说是一团糟。您感到困惑是完全可以理解的,因为这是一个令人困惑的情况。您是否可以选择升级到更新的驱动程序或适用于 3.3+ 的更新的操作系统? 我正在使用 NVIDIA,我可以更新我的驱动程序,但是我担心我的计算机不支持 330+ GLSL。运气不好,因为 GLSL 330+ 显然是现代标准 【参考方案1】:是的,VBO 仍然可以在 GLSL 130 中使用,即使没有着色器也仍然可以使用。 VBO 的目的是保存用于绘图的顶点属性。我见过的大多数最新教程都使用布局位置说明符来指示如何处理着色器中的不同属性,即
layout(location = 0) in vec3 Position;
这在 GLSL 130 中不受支持,因此您必须通过另一种方式将属性与 VBO 关联起来。这很简单……您可以使用glBindAttribLocation
或glGetAttribLocation
。调用 glGetAttribLocation
将为您提供您需要在 glVertexAttribPointer
中使用的标识符,以将 VBO 数据与特定属性相关联。您可以在程序编译后随时调用它。此外,如果您在创建程序对象之后但在链接着色器之前调用它,您可以调用 glBindAttribLocation 来专门设置将与给定属性名称关联的标识符。这很方便,因为它可以让您自己决定位置应该是什么,就像您可以使用布局说明符一样。
最后,如果您想使用 VBO 而不使用着色器,那么您仍然必须找到一种方法,将 VBO 中的数据与固定功能管道所期望的各种输入相关联。这是使用现已弃用的称为glEnableClientState()
和glVertexPointer()
的方法完成的,它们一起让您告诉OpenGL 您要填充的固定函数管道属性,以及它如何在VBO 中找到数据。
【讨论】:
您实际上不必调用glVertexPointer (...)
,glVertexAttribPointer (0, ...)
保证在固定功能管道中对顶点位置进行别名。 glVertexPointer
绝对是更好的方法,因为不知道这一点的人会被在固定功能应用程序中设置顶点属性 0 指针的代码混淆。
我很好奇这是在哪里记录的,以及其他固定函数顶点属性是否具有标准别名。
如果你看一下OpenGL 4.4 compatibility profile 规范,在 pg. 387 在 “10.8.2 使用顶点属性为零传输顶点” 小节下以丑陋的红色(已弃用)文本描述了此行为。这仅(可移植地)适用于顶点属性 0,但在将 GLSL 引入核心 (GL 2.0) 之前,ARB Vertex Program extension 在 Table X.1下定义了一整套别名>。它们不应该在 GLSL 中工作。
我现在不支持 330 GLSL 是否应该使用已弃用的功能?我的目标是编写一个能够在大多数 OpenGL 实现上运行的引擎,所以我可以从
您不能将 glVertex() 和 VBO 结合使用(也不能使用 glBegin()/glEnd(),您需要使用 glDrawElements() 或 glDrawArrays() )。使用带有固定函数管道的 VBO 主要是调用 glEnableClientState() 以便 OpenGL 知道从 VBO 中拉出顶点,然后使用 glDrawArrays() 方法强制管道开始搅拌三角形。以上是关于带和不带着色器的 VBO OpenGL C++的主要内容,如果未能解决你的问题,请参考以下文章