我对如何在不同的多个程序之间正确切换感到困惑。我已将问题缩小到以下几点:如果我使用NO_HDR运行,它可以正常工作;我得到了一些线,太空船和一些球,按顺序渲染。如果我使用HDR运行,我会得到大部分相同的东西,但是我得到了2d方格而不是球体。
我认为来自hdr部分的四重顶点属性会覆盖在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);
答案 0 :(得分:6)
发布的代码表明可能存在对Vertex Array Objects(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,您的程序结构通常如下所示:
我认为你的代码中没有这个问题,只是为了强调一个有时会引起混淆的相关项:正确的GL_ARRAY_BUFFER
绑定需要在{{1}时到位。 } 叫做。没有必要为绘制调用建立glVertexAttribPointer()
绑定。