【发布时间】:2013-02-23 02:32:32
【问题描述】:
我目前正在构建一个体素引擎(例如 Minecraft),并且我正在使用 opengl。
目前的引擎设计如下:
class Map -> 包含二维数组块(std::vector of 标准::向量)
class Chunk -> 包含块的 3d 数组(也使用 std::vector)
class Block -> 包含块的顶点。 (立方体,由 12 个三角形);
我想做的是让每个块都有一个 draw() 函数,它将绘制块中的所有块。我想我会使用 glGenBuffers() 为每个块创建一个缓冲区。从我阅读的教程中,应该首先使用 glVertexArray 创建一个顶点数组,然后绑定它,然后使用目标 GL_ARRAY_BUFFER 将缓冲区绑定到它并用数据填充它。
到目前为止,我设法使用在块中使用 glGenBuffers() 创建的缓冲区来渲染具有多个块的单个块,但在主函数中我创建 glVertexArray 并绑定它,而不是在块,它使用 glDrawArrays() 绑定块的缓冲区和绘图。
我的问题是,为每个块创建一个 VBO 是否正确?我也需要为每个块创建一个 glVertexArray 吗?或者我应该为所有块使用一个,并且每次绑定另一个 VBO?
我尝试通过教程和 opengl wiki 了解更多关于 VAO 和 VBO 的信息,但到目前为止我还没有完全理解它是如何工作的以及应该如何正确使用它。
【问题讨论】:
-
"std::vector of std::vector"...这对于密集的 2D/3D 数组通常不是很有效。切换到
boost.multiarray之类的内容。 -
我建议不要为每个 Block 类使用
draw方法。虽然这是封装的一个很好的例子,但它有可能非常低效。特别是,对于渲染等操作,您可能必须在每个draw方法中冗余地设置状态(例如,绑定 VBO、更改着色器制服等),并且封装阻止了您可能如何优化该操作的任何全局视图。查看Visitor Pattern,它描述了一种以有组织的方式协调数据遍历的方法。 -
你指的这个
glVertexArray()函数是什么? OpenGL 有vertex arrays、vertex array objects 和vertex buffer objects。其中没有一个使用名为glVertexArray()的东西。也许你在想glGenVertexArrays()? -
是的,我的意思是,很抱歉造成误解:D
-
@pqnet 通常,
draw方法与封装了绘制它们所代表的对象所需的所有状态的类相关联(当然,这取决于您如何实现它)。这种封装可能会导致向 OpenGL 发送冗余信息,因为使用相同状态(例如,着色器、纹理等)的对象都需要发送(或至少绑定)该状态。只是效率低下。为获得最佳性能,您需要一种对所有对象具有更“全局”视图的机制,并且可以尽量减少状态变化。