我在构建游戏引擎时经常遇到这个问题,我的类想要看起来像这样:
interface Entity {
draw();
}
class World {
draw() {
for (e in entities)
e.draw();
}
}
那只是伪代码,大致说明了绘图的过程。每个实体子类都会实现自己的绘制。游戏世界不按特定顺序循环遍历所有实体,并逐一告诉它们进行绘制。但是在基于着色器的图形中,这种方法往往效率低下甚至不可行。每种实体类型可能都需要拥有自己的着色器程序。为了最小化程序更改,每个特定类型的实体都需要一起绘制。像粒子之类的简单实体还可以通过其他方式聚合它们的绘制,例如共享一个大的顶点数组。而在混合等方面则更加复杂,某些实体类型需要相对于其他实体类型在特定时间渲染,甚至需要在不同的通道上渲染多次。
我通常使用每个实体类的渲染器单例来保存所有实例并一次性绘制它们,这并不算太糟糕,因为它将绘制与游戏逻辑分离。但是渲染器需要找出要绘制的实体子集,并且需要访问图形管线的多个不同部分。这就是我的对象模型往往变得混乱的地方,存在许多重复的代码、紧密的耦合以及其他问题。
所以我的问题是:对于这种游戏绘图,有什么高效、灵活和模块化的好架构?