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;
精彩评论