在构建游戏引擎时,我一直遇到这个问题,我的类希望看起来像这样:
interface Entity {
draw();
}
class World {
draw() {
for (e in entities)
e.draw();
}
}
这只是伪代码,大致展示了绘图是如何发生的。每个实体子类都实现自己的绘图。世界以不特定的顺序循环遍历所有实体,并告诉它们一一绘制自己。
但对于基于着色器的图形,这往往效率极低,甚至不可行。每个实体类型可能都有自己的着色器程序。为了最大限度地减少程序更改,需要绘制每种特定类型的所有实体together。简单类型的实体(例如粒子)可能还希望以其他方式聚合其绘图,例如共享一个大顶点数组。混合会让事情变得非常棘手,比如某些实体类型需要相对于其他实体类型在特定时间渲染,甚至需要针对不同通道多次渲染。
我通常最终得到的是每个实体类的某种渲染器单例,它保留所有实例的列表并一次绘制它们。这还不错,因为它将绘图与游戏逻辑分开。但是渲染器需要确定要绘制实体的哪个子集,并且需要访问图形管道的多个不同部分。这就是我的对象模型往往变得混乱的地方,有大量重复代码、紧密耦合和其他不好的事情。
所以我的问题是:对于这种高效、通用、模块化的游戏绘图来说,什么是一个好的架构?
使用两阶段方法:首先循环遍历所有实体,但不进行绘图,而是让它们将对自身的引用插入到绘图批处理列表中。然后按 OpenGL 状态和着色器使用对列表进行排序;排序后,在每次状态转换时插入状态更改器对象。
最后遍历列表,执行列表中引用的每个对象的绘图例程。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)