На этой неделе я начал работать с 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;
}