2

我搞砸了一个用 C++/OpenGL 创建 2D 墙的简单概念。每面墙由 4 个顶点描述,水平或垂直延伸,并且还具有颜色。如果它们发生碰撞,墙壁就会相互连接。由墙壁形成的周边由简单的矩形填充。

原来的

我的想法是将许多墙的顶点数据存储在一个 VBO 中。或者每个属性有多个,然后放在 VAO 中?在一个 VBO 中交错并通过 VAO 访问?无论如何,一个物体中有许多墙。如果我存储的任何空间都用完了,请制作另一个 VBO(或我正在使用的任何东西)来存储另一组墙。我还希望有相交的墙,例如以直角,共享顶点以节省空间。

但是,墙是可变的,因此可以随时添加、移动或删除顶点。这将需要跟踪 VBO 中的空闲块,然后根据需要将墙数据分配给它们。这也意味着如果我有多个 VBO,共享顶点的 2 个墙必须在同一个 VBO 中,这可能会引起各种头痛。但同时,我不想为每一面墙都做一个VBO,这最多不过是一个非常简单的4个顶点的东西。

原始图像发生的一些更改示例: 改变

这种情况通常如何处理?是否需要滚动我自己的内存分配方案才能与 VBO 一起使用,或者是否有一个不需要太多工作的适当快速的解决方案?

4

3 回答 3

3

为什么你认为 VBO 可能会用完空间?我的意思是,对于大多数 GPU 而言,VBO 的最大大小约为 16-32-64Mb,这已经很多了!(也在这里检查)

如果您可以将所有数据放在一个 VBO 中,那么问题就简单多了。我只是在需要更改所有数据时重新缓冲它们(我相信这不会经常发生,除非您想在每一帧中添加/移除一堵墙)。

如果这在您的情况下不可接受,我建议您从开源代码中查看一些流行的实现,例如这里有 osg 的 GLBufferObject

看一下GLBufferObject::compileBuffer()功能;在您的情况下,每个都osg::BufferEntry可以是一组连接的墙。要渲染场景,您必须查询此类以获取每个数据的偏移量。

希望这可以帮助。

于 2012-12-08T15:18:43.207 回答
2

我想说,每当您的数据更改(包括在初始创建时)为所有顶点分配一个新缓冲区(重用 VBO 名称,但孤立旧的并分配新的存储)并将顶点从您自己的数据结构复制到 VBO .

于 2012-12-01T18:04:40.930 回答
2

方法很大程度上取决于您的要求。

  • 您的目标平台(PC、手机)的性能如何?
  • 你的缓冲区会有多大(~1Mb、~10mb、~100Mb)?
  • 您将多久更新一次数据(每帧或偶尔)?

我不建议您实现内存管理器,除非确实有必要。即您的缓冲区大于几兆字节并且您经常更新。对于小缓冲区,您可以使用合适的数据结构在 CPU 上保存和处理所有数据,并在渲染之前构建缓冲区并将所有数据流式传输到 GPU。即使用 GL_STREAM_DRAW 创建缓冲区并在每一帧完全更新它。

如果不是这样,那么实现一种内存管理器。为避免移动数据,请使用退化三角形(即,当您移除墙壁时,移动墙壁顶点,使其组成将由光栅化器剔除的三角形)。保留一组自由顶点(构成退化三角形的顶点)的列表,并使用它们来构建新的墙。添加一堵墙应该不是问题。您可以使用您想要的任何缓冲区,但这几乎没有必要(最近我实现了一个使用 ~300Mb VBO 的应用程序,它可以无缝地运行在所有现代硬件上)。

于 2012-12-08T17:31:59.800 回答