我试图使用c ++制作一个带有OpenGL的3D渲染器,好吧,到目前为止,我有一个包含对象和材质对象列表的Scene类(我也有这些类的类,我编写了代码,所以对象可以有多个着色器(每个着色器将能够影响对象中的一组顶点)但现在我正在尝试找到一种将所有信息发送到openGL的好方法。
I've seen people suggest taking everything that uses the same shader and rendering that at once, and do the same for every shader,如果我理解得足够好,但是如果你可以获得包含在不同对象中的相同着色器,这是一个好主意,如果我合并每个具有着色器A的顶点,例如,它不会当我尝试一次绘制它们时,该组是否包含单独对象的顶点?如果我根据它们的着色器拍摄每个对象并分离每个对象,那么对于渲染,我会将对象A分割成其着色器组,然后在object1中绘制shadergroup1,然后在对象2中着色group2,依此类推。也是太多的绘制电话了。
您建议采取什么策略来实现这一目标?
答案 0 :(得分:4)
我建议的第一件事是,就渲染过程而言,你不再考虑"对象"。渲染时,唯一合理的分组是绘制批次(某个图元,点,线,三角形),执行相同的渲染步骤(渲染管道)。过去几个月发布的现代渲染API(Vulkan,DirectX 12和Metal)明确了这一点。
渲染场景时,建议的策略是迭代所有对象,将它们拆分为渲染管道组,并为每个逐个管道组执行一次绘制批处理调用。总体目标应该是尽量减少绘制调用的总数。
答案 1 :(得分:0)
如果您使用的是OpenGL 3.3,则使用的是顶点数组对象(VAO)和顶点缓冲区对象(VBO)。你有一个对象,例如一个表,它可以有三个(或多或少)VBO:s,一个用于顶点数据,一个用于普通数据,一个用于纹理坐标数据。您将该表的VBO包含在一个VAO中。因此每个对象都有自己的VAO存储在GPU内存中。
如果要渲染对象或其中的一部分,可以在使用时绑定其中一个着色器,并调用要通过该着色器渲染的那些VAO:s。在正确的顺序上渲染正确的对象并在每个VAO上使用右边的着色器(当然!)可能很重要。