Com os personagens modelados e texturizados no Blender, é preciso exportá-los para um formato comum ao XNA, que é DirectX (.x) ou AutoDesk (.fbx) para que seja possível visualizá-los. Este processo é relativamente simples, e devido à grande facilidade existente na criação dos personagens no Blender o tempo de produção de um jogo pode ser reduzido sensivelmente.
O primeiro passo no Blender é ter certeza que está no modo de objetos Object mode (Figura 14), este modo permite a seleção e manipulação completa dos objetos que foram criados, e não de seus vértices, isto é necessário porque o script de importação funciona somente com os objetos selecionados.
FIGURA 14 - Object mode
Para iniciar a exportação para o formato DirectX, que é o formato escolhido para o uso neste Trabalho de Conclusão de Curso por não necessitar de manipulações
futuras nos arquivos criados, é preciso selecionar o objeto a ser exportado. O objeto selecionado ficará destacado dos demais com um contorno claro ao seu redor. Após é preciso selecionar o menu File na parte superior da interface, expandir o item Export e clicar na opção DirectX (.x) conforme a Figura 15.
FIGURA 15 - Menu do Blender para exportação do modelo selecionado para o formato
DirectX, compatível com o XNA.
Ao clicar na opção, aparecerá uma interface (Figura 16) com as opções de exportação. Nela é possível configurar a forma que o objeto será exportado. Se a opção Anim for marcada, caso o objeto tenha alguma animação configurada no Blender, esta animação será exportada juntamente com o modelo e poderá ser acessada através do XNA. A opção Flip Norm inverte as faces do objeto, virando-as para dentro do modelo. A opção Swap ZY gira o objeto, alterando seus eixos principais. Flip Z inverte a orientação do objeto, alterando o lado direito pelo esquerdo e o esquerdo pelo direito. A opção Speed permite configurar a velocidade em frames (quadros por segundo) da animação, caso esta tenha sido criada e importada juntamente com o objeto.
FIGURA 16 - Menu gerado pelo script de exportação do DirectX.
No segundo grupo de botões do menu é possível exportar todos os objetos da cena, incluindo a câmera e as lâmpadas, somente o objeto selecionado, ou sair do menu, respectivamente.
O terceiro grupo de botões permite alterar algumas configurações dos objetos a serem exportados, como manter o objeto idêntico ao criado no Blender, recalcular suas faces para verificar se não estão invertidas ou remover a suavização das vértices, obtida através da propriedade Smoth durante a criação dos modelos, respectivamente.
Ao clicar em Export Sel aparecerá a janela de arquivos, solicitando um local para salvar o objeto a ser exportado. Com isso, o uso do Blender é encerrado. Todas as etapas seguintes serão realizadas no XNA e o tratamento dos objetos exportados será realizado através de códigos.
No XNA, o arquivo gerado anteriormente será importado para a pasta Content, esta é a pasta padrão do XNA para armazenamento dos arquivos de imagem, som, vídeo e demais arquivos necessários para a execução do jogo.
selecionar a opção Add, subitem existing item. Após é necessário selecionar o objeto e clicar em abrir. O modelo importado no XNA será copiado para a pasta Content que pode ser encontrada na pasta de arquivos da solução criada no XNA (Figura 17). Se o modelo possuía uma textura, é preciso adicionar a imagem à pasta Content seguindo os mesmos passos descritos durante a importação do modelo.
FIGURA 17 - Solution Explorer do XNA, em destaque a pasta Content, o modelo importado
e sua textura.
A incorporação do modelo ao jogo é relativamente simples e exige poucas linhas de código. Primeiro, ao se trabalhar com um objeto 3D é preciso saber que a orientação espacial dele é muito diferente da orientação de um objeto 2D. A diferença está no eixo Z, que determina a profundidade do modelo na tela do jogo e inclusão de uma câmera, que determina a posição do jogo que o jogador pode visualizar.
É preciso declarar alguns objetos na classe principal do jogo, como pode ser visto no Quadro 6, que por padrão possui o nome de “Game1”.
QUADRO 6 - Declaração de objetos 1. /// <summary>
2. /// This is the main type for your game
3. /// </summary>
4. public class Game1 : Microsoft.Xna.Framework.Game
5. {
6. GraphicsDeviceManager graphics; 7. ContentManager content;
8. Vector3 modelPosition = Vector3.Zero;
10. Matrix projectionMatrix; 11. Matrix viewMatrix;
12. Model myModel; 13. float aspectRatio;
O objeto GraphicsDeviceManager é o responsável pelas configurações do adaptador de vídeo, como já foi citado anteriormente, o ContentManager é responsável pelo gerenciamento da pasta Content e dos arquivos presentes na mesma. O objeto modelPosition, do tipo Vector3, é o responsável por armazenar a posição do modelo no jogo, é um array com 3 posições armazenando os eixos X,Y e Z.
A variável cameraPosition armazena a posição da câmera no jogo, como se fosse a “visão” do jogador. Os objetos Matrix declarados são responsáveis por armazenar a posição de cada vértice de um modelo ou a posição do mesmo no jogo, como se fosse um conjunto de Vector3, bem como criar visões e atributos especiais para a câmera. Model é objeto que recebe o modelo importado e suas propriedades.
É preciso inicializar algumas variáveis com alguns valores, no caso as duas Matrix criadas, que implementarão dois métodos, um definindo a forma de visão como perspectiva e a outra mostrando a câmera onde ela apontar (Quadro 7).
QUADRO 7 - Método Initialize e a inicialização dos objetos declarados.
1. protected override void Initialize()
2. {
3. // TODO: Add your initialization logic here
4. projectionMatrix = Matrix.CreatePerspectiveFieldOfView( 5. MathHelper.ToRadians(45.0f), aspectRatio, 1.0f, 200.0f); 6.
7. viewMatrix = Matrix.CreateLookAt(cameraPosition, 8. Vector3.Zero, Vector3.Up);
9. base.Initialize(); 10. }
No método LoadContent também é preciso inicializar uma variável, neste caso, o objeto Model. É preciso informar que o modelo criado no Blender, e agora presente na pasta “Content”, irá popular o mesmo, conforme pode ser visto no Quadro 8.
QUADRO 8 - Populando o objeto myModel do tipo Model.
1. protected override void LoadContent()
2. {
3. if (loadAllContent) 4. {
5. // TODO: Load any ResourceManagementMode.Automatic
6. myModel = content.Load<Model>(@"Content\ModeloBlender"); 7. }
8. loadAllContent = false; 9.
10. // TODO: Load any ResourceManagementMode.Manual content
11. }
No método Draw, todos os objetos são desenhados na tela. É importante destacar a estrutura de repetição na linha 8, que busca por outros objetos dentro da variável myModel. Isto só é necessário se o modelo exportado for composto de mais de um objeto 3D, neste caso, a estrutura percorre todos os modelos presentes dentro do mesmo, aplica os atributos e efeitos (linha 10), bem como a posição da câmera e a posição do objeto em relação mesma (linhas15 e 16), como pode ser visto no Quadro 9, e desenha o modelo na tela, através da propriedade mesh.Draw() (linha 18).
QUADRO 9 - O método Draw e as propriedades necessárias para desenhar um objeto 3D no XNA
1. protected override void Draw(GameTime gameTime)
2. {
3. graphics.GraphicsDevice.Clear(Color.CornflowerBlue); 4.
5. Matrix[] transforms = new Matrix[myModel.Bones.Count]; 6. myModel.CopyAbsoluteBoneTransformsTo(transforms); 7.
8. foreach (ModelMesh mesh in myModel.Meshes) 9. {
10. foreach (BasicEffect effect in mesh.Effects) 11. {
12. effect.EnableDefaultLighting();
13. effect.World = transforms[mesh.ParentBone.Index] * 14. Matrix.CreateTranslation(modelPosition); 15. effect.View = this.viewMatrix;
16. effect.Projection = this.projectionMatrix; 17. }
18. mesh.Draw(); 19. }
20. base.Draw(gameTime); 21. }
Estas são as etapas necessárias para a utilização de modelos 3D no XNA, utilizando o Blender para a criação dos modelos 3D e um script interno do próprio Blender para a exportação dos modelos a um formato compatível com o XNA.