【问题标题】:OpenGL Render Function OrderOpenGL 渲染函数顺序
【发布时间】:2018-10-02 23:05:47
【问题描述】:

我正在使用 OpenGL 在体素游戏中渲染块块。每个chunk都有自己的顶点缓冲区,现有的render函数(简化)如下:

foreach (Chunk c in chunks)
{
    glBindBuffer(BufferID.Array, c.handle);
    if (c.dirty)
    {
        glBufferData(BufferID.Array, ... , BufferUsage.StaticDraw);
        c.dirty = false;
    }

    // For position, normal, colour and UV
    glEnableVertexAttribArray(...);
    glVertexAttribPointer(...);

    glUseProgram(shader.Handle);
    glDrawArrays(DrawMode.TriangleStrip, 0, c.vertexBuffer.Length);
}

上面的代码可以运行,但是 glEnableVertexAttribArray、glVertexAttribPointer 和 glUseProgram 的 CPU 使用率很高。

我可以在循环开始之前调用这些函数,还是必须在每个 glBindBuffer 之后调用?

【问题讨论】:

  • 这些函数背后的操作对于每个“块”是否需要不同?如果不是,那么为什么他们首先在循环中?如果是这样,那么这个问题就没有实际意义了。这些不是您以任意顺序组装的随机事物;这些函数中的每一个都做一些事情。因此,如果您知道这些函数的作用,那么您就有了问题的答案。
  • 地图不断变化并被分割成块,这样我就不必在每次添加/删除/更改颜色时重新计算整个地图。这些函数(glEnableVertexAttribArray、glVertexAttribPointer 和 glUseProgram)背后的操作对于每个块都是相同的。

标签: c# opengl rendering render


【解决方案1】:

在出现顶点数组对象 (VAO) 之前,您确实必须在想要更改内存布局和/或指针时重做绑定。然后引入了顶点数组对象,有一段时间人们很难过,因为当时的驱动程序性能仍然有很多不足之处(在写这篇文章时,这大约是 10 年前——时间过得真快)。从那以后,司机们进步了很多。

本质上,VAO 存储哪些缓冲区绑定到哪些属性,以及这些绑定的内存布局。 https://www.khronos.org/opengl/wiki/Vertex_Specification#Vertex_Array_Object

【讨论】:

  • 所以我可以在循环之前移动 glEnableVertexAttribArray、glVertexAttribPointer 和 glUseProgram 函数调用?
  • @MitchellRobinson 是的,每个块都有自己的 VAO,它是一组 VBO,因此您在地图初始化或其他任何过程中只配置一次。并且在渲染中,您只需为每个地图块绑定单个 VAO。顺便说一句,看看这个my simple GLSL voxel ray tracer,它使用 3D 纹理作为地图,而不是 VAO/VBO 几何,后者更适合体素世界。
猜你喜欢
  • 1970-01-01
  • 2011-08-16
  • 2010-12-23
  • 1970-01-01
  • 2014-01-15
  • 2019-02-24
  • 1970-01-01
  • 2013-07-05
  • 1970-01-01
相关资源
最近更新 更多