程序解绑再反弹后如何恢复属性绑定

Posted

技术标签:

【中文标题】程序解绑再反弹后如何恢复属性绑定【英文标题】:How to restore attribute binding after program is unbound and then rebound 【发布时间】:2016-06-13 06:11:36 【问题描述】:

我想知道如何在我们解除绑定和重新绑定程序时恢复所有属性绑定。据我所知,如果我使用的是 VAO,它就像反弹 VAO 一样简单,但我不确定我什么时候不使用 VAO。我正在创建 VBO,但不是 VAO。

如果我执行以下操作

glUseProgram(shader1);

// Now set uniforms.
glUniformMatrix4fv(matrix_handdle, 1, false, matrix);

glBindBuffer(GL_ARRAY_BUFFER, bufferIndex);
glEnableVertexAttribArray(m_attributes[position_1]);

glVertexAttribPointer(m_attributes[POSITION_HANDLE], 3, GL_FLOAT, false, 3 * sizeof(GLfloat), 0);

现在保存当前程序,vbo 绑定。然后使用第二个程序

glUseProgram(shader2);
//bind some new  vbo, set some uniform, vertex attribute variable.
element.draw();

然后再次使用第一个着色器程序。重新绑定 vbo

glUseProgram(shader1); //Here, do the attributes set in first shader program remain?
element.draw();

我认为我需要使用 glGetVertexAttrib() 函数获取所有顶点属性的大小、步幅、类型、规范化标志、缓冲区绑定和数组指针的顶点属性值并保存它们。然后当我重新绑定程序时,我将设置顶点属性值。我想我需要通过使用 GL_MAX_VERTEX_ATTRIBS 来获取着色器程序的 Max 属性,然后保存/恢复所有属性位置的值。是正确还是我在某个地方错了?

【问题讨论】:

【参考方案1】:

您使用glVertexAttribPointer 定义如何将 VBO 数据绑定到着色器调用。所以你可以做的是调用glVertexAttribPointer 一次或多次,例如。 G。定义顶点位置、法线和纹理数据,然后进行绘制。

VAO 的目的是为您省去多次调用glVertexAttribPointer 的麻烦。您无需在绘制之前调用glVertexAttribPointer,而是将状态存储在VAO 中,然后您只需在绘制之前调用glBindVertexArray​ 一次。所以 VAO 的全部意义在于你自己没有存储状态,你让 VAO 处理它。有很多关于如何做到这一点的教程。

只要您的着色器使用相同的输入格式,您就可以使用具有相同 VAO 的多个着色器。

附带说明:请尝试一次问一个问题。谢谢你。 :)

【讨论】:

我的问题是关于我不使用 VAO 时的情况。我只是在使用 VBO。我想我需要获取 GL_MAX_VERTEX_ATTRIBS 并存储所有顶点属性的大小、步幅、类型、规范化标志、缓冲区绑定和数组指针并保存。然后当我重新绑定着色器程序时,再次使用 glVertexAttribPointer 设置顶点属性值。它是正确的还是我在某个地方错了? 但是。谁是首先设置这些属性的人?我认为已经在你的程序的某个地方拥有了所有的信息。您是否正在尝试构建一个实现 VAO 的库?为什么?已经有一个,它被称为 OpenGL 3.0。 ;) 这些值将由使用库的人设置。是的,你是对的,我正在尝试 VAO 为你做的事情。如果有人使用 opengl 2.0,我需要这样做。我已经更新了我的问题。请看一看。我 This question 有一些很好的答案。我想强调的是,您应该阅读opengl.org/registry 的 OpenGL 规范,尤其是在您编写库时。【参考方案2】:

现在保存当前程序,vbo 绑定。

程序对象没有绑定了缓冲区。 曾经。程序对象除了已编译的程序外,唯一的状态是统一状态。

而且顶点数组不是统一的。

用于顶点数据的缓冲区可以存储在顶点数组对象 (VAO) 中。如果您无权访问 VAO,则必须在每次要使用这些缓冲区进行渲染时重置此状态。这意味着您每次都必须调用glBindBufferglEnableVertexAttribArrayglVertexAttribPointer

存在 VAO 是为了避免这样做。但是,如果您无权访问它们,那么您就应该利用您所拥有的。

【讨论】:

以上是关于程序解绑再反弹后如何恢复属性绑定的主要内容,如果未能解决你的问题,请参考以下文章

解码后如何恢复 UICollectionViewCell 中的绑定

WPF 属性变动后的业务处理及恢复原始值的方法

怎样解绑微信上绑定的小程序呢?

移动硬盘属性0字节要如何办啊

C#WPF:从SourceSafe恢复项目后获取自定义绑定错误(转换器属性未知)

Service的启动与停止绑定与解绑