最正确的答案是,这取决于您对其进行编程的方式,但这是一件令人担心的好事。尽管GPU的速度变得异常快,但往返于GPU RAM的带宽却并非如此,这将是您最令人沮丧的瓶颈。
它的数据是否仅发送到GPU内存一次并永久存在?
希望是。为了提高渲染速度,您希望将尽可能多的数据放置在GPU上,而不是每帧重新发送一次。VBO正是为这个目的服务的。静态和动态VBO都有,前者是静态模型的最佳选择,后者是顶点在每一帧都会变化的模型(例如,粒子系统)的最佳选择。但是,即使涉及动态VBO,您也不想每帧都重新发送所有顶点。只是那些正在变化的。
就您的建筑物而言,顶点数据将仅位于此处,唯一发生变化的是矩阵(模型/世界,投影和视图)。
对于粒子系统,我使动态VBO足够大,以存储该系统永远存在的最大粒子数。我向每一帧发送有关该帧发出的粒子的数据,以及几套制服,仅此而已。绘制时,可以在该VBO中指定起点和终点,因此不必删除粒子数据。我可以说不要画那些。
当实际渲染模型的每个帧时,GPU处理器是否每次都必须从GPU内存中获取其数据?我的意思是-如果我有2个模型分别渲染多次-如果我先多次渲染第一个模型,然后再渲染第二个模型,或者我仅一次渲染第一个模型,第二个就渲染一次,然后一直像那样交织在一起?
发送多个抽签而不是一次抽签的行为是一个更大的限制。查看实例渲染;它可能对您有很大帮助,并使该问题的答案毫无用处。我有一些尚未解决的驱动程序问题,但是如果您可以解决问题,那么问题就解决了。
显然显卡的内存有限-当无法容纳渲染1帧所需的所有模型数据时,我猜想它一直在每帧从CPU RAM提取(部分)数据,对吗?
您不想用完GPU RAM。如果这样做了,那就改变一下,以免改变。在您可能会用完的非常假想的情况下,它可能会以某种方式崩溃,但是我从未见过它发生,所以说实话我不知道。
我忘记了一个区别:将数据发送到GPU,并将缓冲区设置/绑定为当前缓冲区。后者会引起任何数据流吗?
没有任何重要的数据流,不。这要付出一些代价,但是对于您编写的每一行代码都是如此。再次找出配置成本是多少。
通过初始化创建缓冲区
Raxvan的答案听起来不错,但不太准确。在OpenGL中,创建缓冲区不会保留任何空间。如果要保留空间而不传递任何数据,则可以调用glBufferData并仅传递null。(请参阅此处的注释部分。)
缓冲数据更新
我猜你的意思是glBufferData或类似的其他功能,对吧?这是真正的数据传输发生的地方。(除非您传递空值,就像我在上一段中所说的那样。)
将缓冲区绑定为活动状态(这是一种告诉API我希望此缓冲区在下一次绘制调用中呈现的方式,并且它本身不会执行任何操作吗?)
是的,但是它可以做的更多。例如,如果绑定VAO(顶点数组对象),然后绑定VBO,则该VBO将绑定到VAO。以后,如果再次绑定该VAO,并调用glDrawArrays,它将知道要绘制哪个VBO。
请注意,尽管许多教程将为您为每个VBO创建一个VAO,但有人告诉我这不是它们的预期用途。假设您应该创建一个VAO,并将其与每个具有相同属性的VBO一起使用。我还没有尝试过,所以不能确定是好是坏。
API绘图调用
从我们的角度来看,这里发生的事情非常简单。假设您绑定了VAO,然后调用glDrawArrays。您指定一个起点和一个计数,它会为该范围内的每个顶点运行您的顶点着色器,然后将其输出向下传递到该行。但是,整个过程本身就是另一篇文章。