繁体   English   中英

glVertexAttribPointer覆盖

[英]glVertexAttribPointer overwrite

我对如何在不同的多个程序之间正确切换感到困惑。 我将问题缩小到以下范围:如果我使用NO_HDR运行,它可以正常工作; 我得到了一些线条,一艘太空飞船和一些球体,并以此顺序进行渲染。 如果使用HDR运行,我得到的几乎是相同的东西,但是得到的不是球面而是2d正方形。

我认为hdr部分的quad vertex属性正在覆盖forwardRender()部分中要渲染的最后一件事。 如果我更改了forwardRender()的顺序,那么在forwardRender()中最后呈现的内容将以某种方式弄乱。 我错过了允许四边形顶点覆盖其他对象的问题?

#if NO_HDR
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
forwardRender();

#else

//set to render to custom frame buffer
glBindFramebuffer(GL_FRAMEBUFFER, rt.FramebufferName);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
forwardRender();

//now switch to render to screen
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, rt.renderedTexture);

glUseProgram(hdr.shaderProgram);
glUniform1i(texID, 0);

glBindBuffer(GL_ARRAY_BUFFER, hdr.quad_vertexbuffer);
glEnableVertexAttribArray(hdr.quad_vertexPosition_modelspace);
glVertexAttribPointer(
                      hdr.quad_vertexPosition_modelspace, // attribute
                      3,                              // size
                      GL_FLOAT,                       // type
                      GL_FALSE,                       // normalized?
                      0,                              // stride
                      (void*)0                        // array buffer offset
                      );
// Draw the triangles !
glBindVertexArray(hdr.vao);
glDrawArrays(GL_TRIANGLES, 0, 6); // 2*3 indices starting at 0 -> 2 triangles

#endif

另一个提示:如果我在最后的glDrawArrays之后禁用了vertexAttribArray,我的球体/正方形将消失!

供参考,这是我如何在forwardRender()中渲染球体的方法:

glUseProgram(globe.shaderProgram);
glm::mat4 mvp = camera * world * position * size * orientation;
GLint uTransform = glGetUniformLocation(shaderProgram, "transform");
glUniformMatrix4fv(uTransform, 1, GL_FALSE, glm::value_ptr(mvp));
glBindVertexArray(globe.vao);
glDrawArrays(drawType, 0, globe.drawCount);

发布的代码表明可能对顶点数组对象(VAO)的工作方式有误解。 VAO是国家的集合。 它包含通过以下调用设置的状态:

  • glVertexAttribPointer(...)
  • glEnableVertexAttribArray(...)glDisableVertexAttribArray()
  • glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ...)

每当您进行这些调用之一时,相应的状态都会保存在当前绑定的VAO中。 当您以后再次绑定VAO时,状态将恢复。

例如,按以下顺序发布代码:

glEnableVertexAttribArray(hdr.quad_vertexPosition_modelspace);
glVertexAttribPointer(hdr.quad_vertexPosition_modelspace, ...);
// Draw the triangles !
glBindVertexArray(hdr.vao);
glDrawArrays(GL_TRIANGLES, 0, 6); // 2*3 indices starting at 0 -> 2 triangles

glDrawArrays()调用将使用您在序列中前两个调用中设置的状态。 该状态将应用于当时绑定的任何VAO。 然后, glBindVertexArray(hdr.vao)调用将还原存储在hdr.vao的状态,该状态是先前绑定VAO时的最新状态集。

另请注意,这与切换程序无关。 顶点状态不是程序状态的一部分。

为了有效地使用VAO,您的程序结构通常如下所示:

  1. 一次,在安装过程中,您将为每个对象创建一个VAO。 例如,一个地球仪,一个地球仪,等等。然后绑定每个VAO,并从上面的列表中进行调用以设置对象的顶点状态。
  2. 在渲染期间,对于每个对象,如有必要,请更改程序,绑定对象的VAO,然后进行绘制调用。 您不需要任何其他顶点状态调用,因为状态存储在每个对象的VAO中。

我不认为您的代码有问题,只是为了强调有时会引起混淆的一个相关项目:调用glVertexAttribPointer()时,必须存在正确的GL_ARRAY_BUFFER绑定。 无需为绘图调用建立GL_ARRAY_BUFFER绑定。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM