优化场景图

时间:2011-12-29 16:14:16

标签: c++ opengl

我有一个用c ++用opengl编写的标准场景图。

我的场景图有节点和形状。

节点是矩阵,它们在应用矩阵后绘制了所有子节点。

void Node::draw(Affine3f amatrix) const
{
   amatrix = amatrix * matrix;
   for (Drawable* child : childern)
   {
      child->draw(amatrix);
   }
}

形状只是打包的vbos,它们从绘制调用中获取矩阵,将其设置为统一的模型视图矩阵,然后绘制vbo。

void Shape::draw(Affine3f mat) const
{
   renderer.setModelView(mat);
   myVertices.draw();
}

我喜欢这种设计,非常简单灵活。但是,效率非常低,大量的CPU侧矩阵乘法和大量的绘制调用。

我的问题是:

如何优化此设计,删除不需要的矩阵乘法和不必要的绘制调用?

就像不重新计算矩阵一样,每次绘制(仅计算已更改)并将形状结合起来,以便可以通过一次调用绘制它们。

更多信息:

  • 形状是静态的(暂时),包含的顶点永远不会改变。
  • 混合了静态几何体(在根节点处没有操作)和动态几何体(操纵节点的子节点)

2 个答案:

答案 0 :(得分:4)

首先,我会为传入的矩阵传递const &。你是通过值传递的,如果你有一些draw函数不需要对矩阵做任何特殊的事情,那就是很多不必要的复制。

如果要在矩阵未更改时阻止矩阵计算,则需要使用“脏”标志来确定自上次使用矩阵后的值是否发生了变化。 RenderWare用它的矩阵做了类似的东西。

否则,就像在评论中一样,如果没有看到你的整体设计,你所拥有的东西就没有任何错误。

答案 1 :(得分:2)

您是否正在绘制树中的每个元素,即使它不可见?如果是这样,你应该检查八叉树以过滤不可见的节点。

您还可以尝试在着色器中执行大多数矩阵计算,方法是将它们作为变量传递。我也看到你的矩阵是仿射的,但也许你仍然在实现中做了一个昂贵的逆计算。如果是这种情况,您可以查看我的tutorial以了解如何降低价格。