OpenGL VAO VBO着色器混乱

时间:2015-01-13 07:21:30

标签: c++ opengl glsl vbo vao

我正在写一个渲染器,我正在选择最后一种方法来处理vao / vbo /着色器管理。在网络上,我发现了实际推荐的相互矛盾的信息。 现在的想法如下:

- 一个VBO连续存储所有网格。

-Per“着色器映射”创建VAO以将特定指针映射存储到VBO中。 (“着色器映射”,在具有相同输入的不同着色器中保持一致)

然后通过“着色器映射”对实体进行排序,并使用主VBO中的偏移进行渲染,从而最大限度地减少着色器和VAO切换。类似的东西:

for(shaders by mapping)
    bindVAO(); //set pointers
    for(shader)
        for(entity using shader)
            entity.setUniforms();
            drawArrays(entity.offset, entity.size);

由于这将包括大量的重构,我想问这个解决方案是否是最优的。 我也想知道是否可以在一个VBO中使用多种交错格式。

1 个答案:

答案 0 :(得分:4)

重复使用不同着色器的VAO是一种很好的做法。

然而,与切换着色器相比,切换VBO和VAO通常非常便宜。这意味着在您的情况下,瓶颈可能无论如何都会切换着色器。

出于同样的原因,将所有网格放在同一个VBO中可能有点过分(但只要你不需要更新它就不会受到伤害)。

此外,根据您渲染的内容,按深度/混合状态或深度(通常从前到后)对绘制调用进行排序可能比每个着色器对其进行排序更好。但这需要仔细衡量。 (有关排序here)的更多信息。

编辑:要回答你的第二个问题,有可能将不同类型的顶点放在同一个VBO中,尽管我从未尝试过。这很棘手,因为你需要注意顶点对齐。例如,在调用glDrawArrays(mode, first, count)时,您需要计算first,以便first * sizeof(YourCurrentVertexType)等于将数据放入VBO的偏移量。无论如何,这样做可能不是一个好主意。有些司机可能不会欣赏它,就像我上面说的那样,它可能不会产生显着的差异。