【问题标题】:Introducing a depth buffer to a renderer that uses multiple vertex array objects将深度缓冲区引入使用多个顶点数组对象的渲染器
【发布时间】:2013-01-18 20:33:44
【问题描述】:

我有一个渲染基础设施,它使用多个顶点数组对象来渲染一个复杂的场景。每个顶点数组对象负责维护自己的一组绑定缓冲区、指针和属性(正如它们的设计目的)。

给定多个负责渲染的数组对象,如何引入深度缓冲,使每个单独的数组对象在渲染期间使用相同的深度缓冲区?换句话说,我如何统一 Vertex Array Objects(及其良好的封装属性)和深度缓冲的概念,这似乎是一个更全局的概念。

我发现的所有示例都描述了在帧缓冲区的上下文中使用深度缓冲区。 Apple 描述了这种技术here。那么在帧缓冲区级别实现深度缓冲然后让顶点数组对象写入该帧缓冲区的技术是什么?有没有我可以遵循的使用 VAO 和深度缓冲的示例?

我有一个封装顶点数组对象的类,这是它的绑定方法(负责设置各种缓冲区、指针和属性)。

void scene_GLBuffer::BindTriangles()
{
    glBindVertexArrayOES(_mVertexArrayObject);
    glGenVertexArraysOES(1, &_mVertexArrayObject);

    // generate the buffer and configure the gl pointers for position and normal data
    glGenBuffers(1, &_mVertexPositionNormalTriangles);
    /* Bind and set up vertex position and normal data */
    glBindBuffer(GL_ARRAY_BUFFER, _mVertexPositionNormalTriangles);
    glBufferData(GL_ARRAY_BUFFER,
                 sizeof(crVertexPN)*_mPositionNormalTriangleData->size(),
                 _mPositionNormalTriangleData->data(),
                 GL_STATIC_DRAW);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE,
                          sizeof(crVertexPN), (void*)offsetof(crVertexPN,Position));
    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE,
                          sizeof(crVertexPN), (void*)offsetof(crVertexPN,Normal));
    glEnableVertexAttribArray(GLKVertexAttribNormal);

    // generate the buffer and configure the gl pointers for color and alpha data
    glGenBuffers(1, &_mVertexColorTriangles);
    glBindBuffer(GL_ARRAY_BUFFER, _mVertexColorTriangles);
    glBufferData(GL_ARRAY_BUFFER,
                 sizeof(crVertexC)*_mColorTriangleData->size(),
                 _mColorTriangleData->data(),
                 GL_DYNAMIC_DRAW);
    glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_TRUE,
                          sizeof(crVertexC), (void*)offsetof(crVertexC,Color));
    glEnableVertexAttribArray(GLKVertexAttribColor);
    glBindBuffer(GL_ARRAY_BUFFER,0);

    // generate the buffer and configure the gl pointers for triangle index data
    glGenBuffers(1, &_mVertexIndexTriangles);
    /* Bind and set up triangle index data */
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _mVertexIndexTriangles);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(bits32)*_mIndexTriangleData->size(),_mIndexTriangleData->data(), GL_STATIC_DRAW);
    //        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);

    glBindVertexArrayOES(0);
}

绑定后,draw方法实现如下(这个draw方法在每个单独的顶点缓冲区对象上调用):

void scene_GLBuffer::Draw()
{
    glBindVertexArrayOES(_mVertexArrayObject);

    glBindBuffer(GL_ARRAY_BUFFER, _mVertexPositionNormalTriangles);
    glDrawElements(GL_TRIANGLES, _mIndexTriangleData->size(), GL_UNSIGNED_INT, 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindVertexArrayOES(0);
}

所有这些都运行得很顺利,但我很难看到深度缓冲在哪里适合。

【问题讨论】:

    标签: opengl-es opengl-es-2.0 depth-buffer vertex-array


    【解决方案1】:

    我无法看到深度缓冲在哪里适合。

    那是因为它适合其中任何一个。

    顶点数组对象是封装顶点数组状态的方式。此状态与当前程序对象、当前绑定的纹理或帧缓冲区等其他状态无关。最后一个是深度缓冲区的来源。

    如果您想用 VAO 将多个对象渲染到同一个帧缓冲区,那么只需 不要更改帧缓冲区。这就是您将它们全部渲染到同一图像的方式(为简单起见,我们将其称为屏幕)。深度缓冲区是帧缓冲区的一部分,因此如果要渲染到相同的深度缓冲区,请不要更改不同对象之间的帧缓冲区。

    简而言之,您对象的Draw 函数既不知道也不关心当前正在使用什么深度缓冲区。就像Draw 函数不知道也不关心正在使用什么程序、绑定什么纹理以及当前视口是什么。

    【讨论】:

    • 谢谢!这对理清我心中的关系大有帮助。
    猜你喜欢
    • 1970-01-01
    • 2012-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多