我正在学习OpenGL,并展示了我的第一批几何和纹理。
现在我正在尝试在不同的图形演员之间建立父子层次结构模型。 我知道它通常是这样实现的:
void Draw(){
glPushMatrix();
<apply all transformations>
<draw this model>
<for each child c of this actor:>
c.Draw();
glPopMatrix();
}
这样,孩子们将继承父级的所有变换(缩放,位置,旋转)。 但有时我只想要应用某些变换(例如,特效演员应该随着它的父节点一起移动,但是当头盔演员想要继承所有变换时,不要使用它的父节点旋转。)
我想出的想法是传递应该应用于绘图函数的转换参数:
class Actor{
Vec3 m_pos, m_rot, m_scale; //This object's own transformation data
std::vector<Actor*> m_children;
void Draw(Vec3 pos, Vec3 rot, Vec3 scale){
(translate by pos) //transform by the given parent data
(rotate around rot)
(scale by scale)
glPushMatrix(); //Apply own transformations
(translate by m_pos)
(rotate around m_rot)
(scale by m_scale)
(draw model)
glPopMatrix(); //discard own transformations
for( Actor a : m_children ){
glPushMatrix();
a.Draw( pass m_pos, m_rot and/or m_scale depending on what the current child wants to inherit );
glPopMatrix();
}
}
}
void StartDrawing(){
glLoadIdentity();
//g_wold is the "world actor" which everything major is attached to.
g_world.Draw( Vec3(0,0,0), Vec3(0,0,0), Vec3(0,0,0) );
}
(伪代码。可能是错误的,但应传达这个想法。)
但这似乎相当凌乱,看起来更多的工作负荷(因为有大量额外的矢量数学)。
我已经阅读了一些关于分层建模的内容,但是关于它的所有文献似乎都假设每个孩子都想要继承所有的父属性。
有没有更好的方法呢?
答案 0 :(得分:2)
首先注意:在最近的OpenGL版本中不推荐使用矩阵堆栈,用户应该自己控制转换。
您遇到的问题会出现在渲染图中使用的各种OpenGL状态。解决此问题的一种常见方法(例如在OpenSceneGraph中)是为每个状态定义一个附加属性,用于定义子图是否覆盖其子项中的属性。反过来,孩子们可以保护他们的国家免于被父母所覆盖。这适用于各种OpenGL状态。
你的案子似乎有些奇怪。通常,转换应用于整个子图。虽然这个方案也适用于此。