开发者

XNA - Render Tree rotations and translations

I have started working with XNA this week, currently building a good core that I will be able to use for future games.

I can't complete my render tree because I don't know how to code the following:

(I am used to work with OpenGL a lot, so I am looking for the fastest equivalent to this code)

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();
}

My current attempt is something开发者_运维技巧 like this:

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;
}

I understand that the worldMatrix can't be implicitly accessed from anywhere and that you have to carry a reference to it. How do I translate and rotate then? And is my worldMatrix backup the correct way to do the equivalent of a glPushMatrix/PopMatrix block?

Thanks,

Nick


EDIT:

I think I managed to make a few steps forward, this being said, it is still not working. God I miss openGL and all the detailed documentation, MSDN won't give me much info... Here is my latest approach :

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"] returns me a null pointer so SetValue obviously throws me an access violation error. I have double checked and the effect instance is correctly initialize, according to the debugger.

Is this the correct way to do it?


EDIT AGAIN :

Thanks to your help, I am a little close to success, but the triangle is still static and wont rotate even when incrementing its orientation angles.

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;
    }


BasicEffect has getters and setters for the World, View and Projection matrices, but the shader itself keeps a single WorldViewProj matrix, which is why effect.Parameters["xWorld"] fails. Stick to the setters and BasicEffect should take care of the rest.

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

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜