oop - 在基于着色器的游戏中渲染的 OO 架构

标签 oop opengl graphics shader

在构建我的类希望如下所示的游戏引擎时,我一直遇到这个问题:

interface Entity {
  draw();
}

class World {
  draw() {
    for (e in entities)
      e.draw();
  }
}

这只是伪代码,大致显示了绘图是如何发生的。每个实体子类实现自己的绘图。世界以没有特定顺序的方式遍历所有实体,并告诉它们一个一个地绘制自己。

但是对于基于着色器的图形,这往往是非常低效甚至不可行的。每种实体类型可能都有自己的着色器程序。为了最大限度地减少程序更改,需要将每种特定类型的所有实体绘制在一起。简单类型的实体,如粒子,也可能希望以其他方式聚合它们的绘图,如共享一个大顶点数组。并且它变得非常毛茸茸的混合和这样一些实体类型需要在某些时间相对于其他实体类型,甚至在多次不同 channel 中渲染。

我通常最终得到的是每个实体类的某种渲染器单例,它保留所有实例的列表并一次绘制它们。这还不错,因为它将绘图与游戏逻辑分开。但是渲染器需要确定要绘制哪个实体子集,并且需要访问图形管道的多个不同部分。这就是我的对象模型容易变得困惑的地方,有很多重复的代码、紧耦合和其他不好的东西。

所以我的问题是:对于这种高效、多功能和模块化的游戏绘图,什么是好的架构?

最佳答案

使用两阶段方法:首先循环遍历所有实体,但不要绘图,而是让它们将自己的引用插入到(该)绘图批处理列表中。然后按 OpenGL 状态和着色器使用对列表进行排序;在每次状态转换时对插入状态更改器对象进行排序后。

最后遍历列表,执行列表中引用的每个对象的绘图例程。

关于oop - 在基于着色器的游戏中渲染的 OO 架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6583024/

相关文章:

java - 对象管理器?设计模式

php - 如何为数据库事件创建函数并在 Laravel 5.1 的 Controller 中调用它们

java - 在 OpenGL 中获取相机在 X、Y 和 Z 轴上的弧度旋转?

delphi - 为什么 Delphi 中可以自赋值?

Java继承覆盖实例变量

java - 绘制像素时数组索引越界

android - 测量要在 Canvas 上绘制的文本高度(Android)

iPhone文字发光效果

c++ - 用于 OpenGL 的 Shapes 绘图简单库,有吗?

c++ - 如何在 OpenGL/C++ 中绘制一个居中的字符串?