C++ OpenGL渲染队列-我的缓冲区在哪里?

C++ OpenGL渲染队列-我的缓冲区在哪里?,c++,c,opengl,rendering,game-engine,C++,C,Opengl,Rendering,Game Engine,我正在尝试重新设计当前的渲染系统,它的工作原理与您第一次使用渲染器时所想的差不多:每一帧,游戏都调用Render(),它在世界上调用Render(),它对实体进行Z排序(这是一个2D游戏),在每个实体上调用Render(SpriteBatch&batch),然后每个实体使用给定的SpriteBatch渲染其精灵。SpriteBatch有一个VAO、一个VBO和一个EBO。它对于sprite渲染是有效的,但仍然相当幼稚。我也没有办法渲染其他东西,比如多边形和线等等。例如,我希望能够告诉渲染器渲染从

我正在尝试重新设计当前的渲染系统,它的工作原理与您第一次使用渲染器时所想的差不多:每一帧,游戏都调用Render(),它在世界上调用Render(),它对实体进行Z排序(这是一个2D游戏),在每个实体上调用Render(SpriteBatch&batch),然后每个实体使用给定的SpriteBatch渲染其精灵。SpriteBatch有一个VAO、一个VBO和一个EBO。它对于sprite渲染是有效的,但仍然相当幼稚。我也没有办法渲染其他东西,比如多边形和线等等。例如,我希望能够告诉渲染器渲染从一个点到另一个点的线。为了现在做到这一点,我必须创建一个完整的网格,将其基本类型设置为GL_线,上载顶点数据,上载元素数据,然后在某处对其调用Render()。这些行甚至不会被批处理,因为它们都有自己的OpenGL缓冲区

我想将所有渲染逻辑移到我的OpenGLRenderer类中。我已经读了很多书,似乎应该使用某种RenderQueue和RenderCommand设置。我想我非常理解这一点——每个实体都将创建一个RenderCommand,其中包含其网格/材质或精灵(只是数据),然后将其提交给渲染器。然后,渲染器将根据材质等对命令进行排序,以尽可能避免状态更改


这就是我的问题所在。我的缓冲器会去哪里?我有一个完整的RenderCommand队列,它指向我需要的所有顶点和材质数据,但如何将其传递给OpenGL?我在想,只要有一个大的VAO、VBO和EBO,然后把整个事情当作一个大批量处理。如果状态需要更改,我会刷新缓冲区,并将可以批处理的数据批处理在一起。然而,对于整个游戏来说,拥有一组庞大的OpenGL缓冲区会让人感到奇怪。

我认为这更像是一个决策。我目前正在编写一个渲染系统,非常类似于您所说的不充分的渲染系统;其目标是更容易地向用户公开底层功能。然而,我要指出,你的“一大缓冲区”实际上就是风吹的方式。查看“接近零驱动开销”以及Vulkan中的工作方式。也就是说,您首先提到的设计和这样的缓冲区管理模型并不是相互排斥的(这也是我第一手知道的)。我不完全确定您所说的“相互排斥”是什么意思。你能解释一下吗?好吧,你目前的设计是让更多的直接访问ish类与包装器/多线程/通用RenderCommand类相比较——多个不同的缓冲区与一个单一分区的缓冲区。你真的可以把任何一个选项和其他任何一个混合在一起;例如,您可以拥有非常原始的渲染类,这些渲染类是单个引擎缓冲区的给定部分,这是我正在实现的设计。但我所得到的最终结果是,您所谈论的新设计实际上已经被Vulkan很好地记录和使用了,我建议您研究一下其中的细节。不过,它确实存在一些问题。一个是你必须在单个缓冲区内有效地管理你自己的内存,并防止操作系统通常为你所做的恐怖(借助内存访问硬件):内存碎片。这不是一项小任务。仅供参考,Vulkan基本上是下一个OpenGL。我写了一个很长的答案,但我意识到这里没有定义的问题,而且您似乎意识到OpenGL中状态更改的含义。无论如何,我只想提醒您,您的应用程序只是一个客户端,您与服务器交互。您不需要知道服务器如何管理数据;它可以在RAM上,在GPU上,在不同国家的不同机器上。您只保留对该数据的引用。它在很大程度上依赖于实现。没关系。使用渲染队列的方法是正确的。随它去吧。这里没有问题要回答。