2011-04-19 131 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