2011-04-19 98 views
1

本周我已经开始与XNA合作,目前正在构建一个好的核心,我将能够用于未来的游戏。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; 
    } 

回答

0

BasicEffect具有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; 
+0

没有更多的崩溃,但我的测试三角形不会按预期旋转。我在更新函数中增加theta,调试器确实显示CreateRotation是用一个有效递增的Theta来调用的。 – NGauthier 2011-04-19 22:36:49

+0

@NGauthier:您对不同的方向使用了三次CreateRotationX。你可以使用CreateFromYawPitchRoll(y,x,z)来保存一些矩阵乘法。 – Kyte 2011-04-20 01:18:46