Olá pessoal, como estamos?
Se você está “chegando agora”, talvez queira dar uma olhada nos posts anteriores dessa série.
No post anterior, mostrei como desenhar um cubo 3D que pode ser rotacionado. Hoje, vou mostrar como fazer isso com um modelo 3D mais complexo, carregado de um arquivo.
Se desejar, você pode pegar o código-fonte do post de hoje em https://github.com/ElemarJR/VamosAprenderXNA.
Por que carregar modelos 3D de arquivos?
Nos posts anteriores, você viu que é possível desenhar qualquer coisa usando apenas triângulos. Embora isso seja verdade, isso será extremamente trabalhoso. Se o código para desenhar um cubo já foi extenso, imagine desenhar um objeto mais complexo, como um “humano”.
Quando desenhamos objetos mais complexos, usamos modelos 3D. Basicamente, um modelo 3D é uma coleção de informações necessárias para desenhar os triângulos que formam um modelo 3D mais complexo.
Modelos 3D são, geralmente, construídos em programas específicos para esse propósito. Entre os programas mais populares para esse fim estão 3D Studio, Blender, Rhinoceros, entre outros. O Blender é open-source e free.
Formatos de modelo 3D suportados pelo XNA
Modelos 3D podem ser salvos em diversos formatos. XNA suporta apenas arquivos .X e .FBX (criado pela AutoDesk).
Caso você possua um arquivo em um formato diferente, poderá converter facilmente para .X ou .FBX utilizando o Blender.
Adicionando modelos 3D em um projeto XNA
Para adicionar modelos 3D em um projeto com XNA, basta adicionar os arquivos correspondente no projeto da Content Pipeline. Após adicionar o arquivo, se o projeto compilar com êxito, sabemos que o arquivo foi interpretado e entendido.
Alguns arquivos 3D tem referências para arquivos com texturas. Nesse caso, será necessário manter esses arquivos nos caminhos especificados.
No post de hoje, estou utilizando um arquivo .X que era distribuído, originalmente, junto ao SDK do DirectX.
Código para carregar um modelo 3D
Carregar um modelo 3D é uma operação trivial. Mantendo o patter que já apresentei nos últimos posts, indico a carga desse dado no método LoadContent. Observe:
Model CurrentModel; protected override void LoadContent() { this.CurrentModel = Content.Load(@"models\spaceship"); }
Note que a única mudança em relação a carga de uma textura é a substituição do parâmetro de tipo. A classe Model é utilizada para representar os dados correspondentes a um modelo 3D na memória.
Desenhando um modelo 3D
Aqui, outra operação simples. Observe:
Matrix worldRotation = Matrix.Identity; Matrix worldTranslation = Matrix.Identity; Matrix worldScale = Matrix.Identity; protected override void Draw(GameTime gameTime) { foreach (ModelMesh mesh in CurrentModel.Meshes) { foreach (BasicEffect be in mesh.Effects) { be.EnableDefaultLighting(); be.Projection = this.CurrentCamera.Projection; be.View = this.CurrentCamera.View; be.World = worldScale * worldRotation * worldTranslation * mesh.ParentBone.Transform; } mesh.Draw(); } }
Para começar, no exemplo de hoje, repeti o método Update do post anterior (para permitir rotação, translação e zoom). Vamos a informações quanto ao desenho. Perceba:
- Ao construir um modelo 3D, um desenhista pode “separar” o desenho em diversas partes. Cada uma dessas partes é representada no objeto Model como um elemento da coleção Meshes;
- Cada Mesh pode especificiar um conjunto de efeitos (onde ocorre a aplicação de texturas, cores, sombreamentos). Para fazer o desenho, é necessário percorrer todos esses efeitos;
- Mais uma vez, não estamos criando qualquer configuração de luz para nosso ambiente. Estamos utilizando uma configuração default que é suficiente para programas mais simples. Em posts futuros mostrarei técnicas avançadas de iluminação;
- Continuo utilizando o objeto Camera (que construímos na parte 4) para calcular a matriz View.
- A matriz “mundo” é computada pela combinação das matrizes de translação, rotação e escala que estamos atualizando no método Update (não apresentado aqui por ser idêntico ao que utilizamos no post anterior) e a matriz da Bone correspondente a Mesh.
- Todo Mesh tem um Bone associado. Um Bone é fundamental para modelos que desejemos animar (considere um “robo”, por exemplo).
- O desenho é efetivado pelo método Draw da mesh.
Segue alguns screenshots da execução do exemplo de hoje:
Lembre-se, o código-fonte dos exemplos todos os posts dessa série está disponível em https://github.com/ElemarJR/VamosAprenderXNA.
Por hoje, era isso
David
13/09/2011
OIlá eu gostaria de saber como vc exportou o arquivo .X do 3D MAX pq eu exportei uma espada que eu fiz com algumas texturas e quando eu fui executar o programinha ele disse que faltava um arquivo .bmp vc pode me tirar essa duvida
elemarjr
13/09/2011
Certifique-se de que adicionou todas as texturas no projeto de recursos.
David
18/09/2011
não intendi?
poderia me explicar melhor?
David
18/09/2011
Tipo quando eu exporto o arquivo .x do 3D MAX ele exporta junto as textura jpg ou bmp. e outra coisa, quando eu tento rodar o joguinho com o meu arquivo .x diz que nao foi encontrado o arquivo dasda.x Vc poderia me ajudar? estou muito entusiasmado com o XNA e sei um pouco de 3D MAX e estou na faculdade de ciencias da computação e tenho um trabalho de XNA. Obrigado pela ajuda
elemarjr
18/09/2011
Certifique-se de ter adicionado todos os arquivos (3d e texturas) no projeto da content Pipeline.