使用VBO的最佳方法 [英] The best way to use VBOs

查看:219
本文介绍了使用VBO的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用VBO最快,最灵活(在大多数情况下适用)的方式是什么?

我正在开发一个openGL应用程序,我希望它能达到最佳性能,因此我需要有人来回答这些问题.我读了许多问题和答案,但我想有很多我不需要的信息会弄乱我的脑筋...

I am developing an openGL application and i want it to get to the best performance, so i need someone to answer these questions. I read many questions and anwers but i guess there's to much information that i don't need which messes up my brain...

  • 我应该使用几个vbo?
  • 我应该如何创建vbos?
  • 如果数据大小不固定,我应该如何更新vbos数据?
  • 我应该如何渲染vbos?
  • 我该如何处理不再想要呈现的vbos中的数据?

推荐答案

  • 我应该使用几个vbo?
  • How many vbos should i use?

尽可能少.切换VBO的成本很小,但可以衡量.通常,您将尝试将类似数据分组到VBO中.例如,在FPS游戏中,躺在街道上的所有不同种类的垃圾,小型道具等通常都位于相同的VBO或只有很少的VBO.

As few as possible. Switching VBOs comes with a small, but measureable cost. In general you'll try to group similar data into VBOs. For example in a FPS game all the different kinds of garbage lying on the street, small props, etc., will be usually located in the same or only a small number of VBOs.

这也取决于图纸的批量大小.渲染少于约100个原语的glDraw…调用次优(即使在15年前,情况也一直如此).因此,您希望在可能的情况下至少批处理100个原语.但是,如果单个网格只有20个三角形(用于实例化的低多边形数道具),则每个三角形都不能在其自己的VBO中进行批量处理.

It also comes down to drawing batch sizes. glDraw… calls which render less than about 100 primitives are suboptimal (this has always been the case, even 15 years ago). So you want to batch at least 100 primitives where possible. But if a single mesh has only, say 20 triangles (low polycount props for instancing or such), each in its own VBO you can no longer batch more.

  • 我应该如何创建vbos?
  • How should i create vbos?

glGenBuffers→glBindBuffer→glBufferData

glGenBuffers → glBindBuffer → glBufferData

UPDATE 您可以将空指针传递给glBufferData的data参数以初始化缓冲区对象,而无需设置数据.

UPDATE You can pass a null pointer to the data parameter of glBufferData to initialize the buffer object without setting the data.

  • 如果数据大小不固定,我应该如何更新vbos数据?
  • How should i update vbos data, if the data size is not fixed?

创建VBO,其粒度比数据大小要大.无论如何,您的操作系统都会对主机端数据进行此操作,这称为分页.同样,如果您想使用 glMapBuffer 将缓冲区对象设为宿主页面大小的倍数,则对整个系统来说非常好.

Create VBOs with a coarser size granularity than your data size is. Your operating system is doing this anyway for your host side data, it's called paging. Also if you want to use glMapBuffer making the buffer object a multiple of the host page size is very nice to the whole system.

在当前系统上,通常的页面大小是4kiB.这就是我要选择的VBO大小粒度. 更新:您可以顺便问一问,操作系统正在使用哪个页面大小.不过,这取决于操作系统,我想再问一个问题.

The usual page size on current systems is 4kiB. So that's the VBO size granularity I'd choose. UPDATE: You can BTW ask your operating system which page size it is using. That's OS dependent though, I'd ask another question for that.

使用glBufferSubData更新数据,或者使用glMapBuffer修改将其映射到主机端映射的内存中,然后再映射glUnmapBuffer.

Update the data using glBufferSubData or map it with glMapBuffer modify in the host side mapped memory, then glUnmapBuffer.

如果数据超出缓冲区对象,请创建一个更大的新对象,并使用glCopyBufferSubData复制.参见租赁"段落.

If the data outgrows the buffer object, create a new, larger one and copy with glCopyBufferSubData. See the lase paragraph.

  • 我应该如何渲染vbos?
  • How should i render vbos?

glBindBuffer→glDraw…

glBindBuffer → glDraw…

  • 我该如何处理不再想要呈现的vbos中的数据?
  • How should i deal with data in vbos that i don't want to render anymore?

如果数据仅消耗VBO的一部分并与其他数据共享,而您的内存还没有用完,那就不要访问它.理想情况下,您需要围绕某个索引来跟踪哪个VBO拥有哪些VBO的哪些部分可用于哪种任务.这非常类似于内存管理,特别是一种称为对象栈(obstack)的方案.

If the data consumes only a part of the VBO and shares it with other data and you're not running out of memory then, well, just don't access it. Ideally you keep around some index in which you keep track of which VBO has which parts of it available for what kind of task. This is very much like memory management, specifically a scheme known as object stacks (obstacks).

但是,最终压缩一个现有的缓冲区对象可能是有意义的.为此,您将创建一个新的缓冲区对象,将其绑定为写入目标,并选择旧的缓冲区对象作为读取目标.然后使用glCopyBufferSubData将内容复制到一个新的,更严格的缓冲区对象中.当然,您将必须更新所有对缓冲区对象名称(= OpenGL ID)和偏移量的引用.

However eventually it may make sense to compactify an existing buffer object. For this you'd create a new buffer object, bind it as writing target, with the old buffer object being selected as reading target. Then use glCopyBufferSubData to copy the contents into a new, tightened buffer object. Of course you will then have to update all references to buffer object name (=OpenGL ID) and offsets.

因此,在OpenGL缓冲区对象上编写一个薄的抽象层是有意义的,该层可以跟踪OpenGL缓冲区对象在无结构的blob中的实际类型化数据.

For this reason it makes sense to write a thin abstraction layer on top of OpenGL buffer objects that keeps track of the actual typed data within the structureless blobs OpenGL buffer objects are.

这篇关于使用VBO的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆