【问题标题】:XNA - Render Tree rotations and translationsXNA - 渲染树旋转和平移
【发布时间】:2011-08-08 19:28:31
【问题描述】:

本周我开始与 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;
    }

【问题讨论】:

    标签: c# tree xna rotation render


    【解决方案1】:

    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;
    

    【讨论】:

    • 没有更多的崩溃,但我的测试三角形不会按预期旋转。我在更新函数中增加了 theta,调试器确实显示 CreateRotation 是使用有效的递增 Theta 调用的。
    • @NGauthier:您针对不同的方向使用了三次 CreateRotationX。您可以使用 CreateFromYawPitchRoll(y, x, z) 来保存一些矩阵乘法。
    猜你喜欢
    • 1970-01-01
    • 2013-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多