XNA - 渲染树旋转和平移

时间:2011-04-19 15:47:21

标签: c# tree xna rotation render

我本周开始使用XNA,目前正在构建一个很好的核心,我将能够用于未来的游戏。

我无法完成渲染树,因为我不知道如何编写以下代码:

(我以前经常使用OpenGL,所以我正在寻找与此代码相当的最快速度)

public void DrawRecursively( GameTime deltaTime )
{
    glPushMatrix();

    /* these 3 lines are what i didn't figure out with XNA */
    glTranslate3f( position[0], position[1], position[2] );
    glRotatef( theta, 0.0f, 1.0f, 0.0f );
    glRotatef( phi, 1.0f, 0.0f, 0.0f );

    this.Draw( deltaTime );

    foreach ( ComponentInterface child in childs )
    {
        child.DrawRecursively( deltaTime );
    }

    glPopMatrix();
}

我目前的尝试是这样的:

public void DrawRecursively( GameTime deltaTime, Matrix worldMatrix )
{
    Matrix backup = worldMatrix;

    // TRANSLATE HERE.
    // ROTATE HERE.

    this.Draw( deltaTime );

    foreach ( ComponentInterface child in childs )
    {
        child.DrawRecursively( deltaTime, worldMatrix );
    }

    worldMatrix = backup;
}

据我所知,worldMatrix无法从任何地方隐式访问,您必须携带对它的引用。 我如何翻译和旋转呢? 我的worldMatrix备份是否正确等同于glPushMatrix / PopMatrix块?

谢谢,

尼克


编辑:

我认为我设法向前迈出了一步,据说,它仍然没有用。 上帝我想念openGL和所有详细的文档,MSDN不会给我太多信息...... 这是我最新的方法:

public void DrawRecursively( GameTime deltaTime, BasicEffect effect )
{
    Matrix worldMatrix = effect.World;
    Matrix backup = worldMatrix;

    worldMatrix = worldMatrix * Matrix.CreateTranslation( position.ToVector3() );
    worldMatrix = worldMatrix * Matrix.CreateRotationY( theta );
    worldMatrix = worldMatrix * Matrix.CreateRotationX( phi );
    effect.Parameters["xWorld"].SetValue( worldMatrix );

    this.Draw( deltaTime );

    foreach ( ComponentInterface child in childs )
    {
        child.DrawRecursively( deltaTime, effect );
    }

    effect.Parameters["xWorld"].SetValue( backup );
}

effect.Parameters["xWorld"]返回一个空指针,因此SetValue显然会引发访问冲突错误。根据调试器,我已经仔细检查并且效果实例正确初始化。

这是正确的方法吗?


再次编辑:

感谢您的帮助,我有点接近成功,但三角形仍然是静止的,即使在增加其方向角度时也不会旋转。

public void DrawRecursively( GameTime deltaTime, BasicEffect effect )
    {
        Matrix worldMatrix = effect.World;
        Matrix backup = worldMatrix;

        effect.World = worldMatrix  * Matrix.CreateScale( scale )
                                    * Matrix.CreateRotationX( orientation.X )
                                    * Matrix.CreateRotationX( orientation.Y )
                                    * Matrix.CreateRotationX( orientation.Z )
                                    * Matrix.CreateTranslation( position.ToVector3() );

        this.Draw( deltaTime );

        foreach ( ComponentInterface child in childs )
        {
            child.DrawRecursively( deltaTime, effect );
        }

        effect.World = backup;
    }

1 个答案:

答案 0 :(得分:0)

BasicEffect具有World,View和Projection矩阵的getter和setter,但着色器本身保留一个WorldViewProj矩阵,这就是effect.Parameters["xWorld"]失败的原因。坚持使用setter,BasicEffect应该照顾其余部分。

Matrix worldMatrix = effect.World;
Matrix backup = worldMatrix;

worldMatrix *= Matrix.CreateTranslation( position.ToVector3() );
worldMatrix *= Matrix.CreateRotationY( theta );
worldMatrix *=  Matrix.CreateRotationX( phi );
effect.World = worldMatrix;