# Programação com OpenGL/Modern OpenGL Tutorial Leitor de OBJ

Para ser mais rápido, vamos querer carregar um modelo existente que criamos no punho. Podemos importar alguns do Blender.
Aparentimente isto não é fácil carregarmos diretamente um arquivo .blender, mas nós podemos fazer assim:
* File > Export em formato .obj, e escrevendo um leitor de OBJ.
* File > Export em formato .3ds, e usando o lib3ds
Nós pensamos que escrever um leitor de OBJ é um bom exercício, então começaremos por ele.

## Criando a Suzzane

    Ver também: Blender 3D
Suzzane é um modelo de teste do Blender. ele possui 500 polígonos, o que será um bom teste para nós.
Para criá-lo, execute o Blender(Vamos usar a versão 2.58), depois:
* Remova todos os elementos da cena (pressione A e depois X
* No menu superior, clique em Add > Mesh > Monkey
* Pressione n para mostrar o Transform panel e
** Ajuste a localização para (0, 0, 0)
** Ajuste a rotação para (90, 0, 0)
* No menu superior, clique em File > Export > Wavefront (.obj)
** Para manter a orientação do Blender, cuide que as seguintes estejam assim (para trocar para "Y-is-up" coordenadas padrão do OpenGL):
*** Forward: -Z Forward
*** Up: Y Up
** Mexa em "Triangulate" para garantir que as faces sejam trianguladas evitando faces quadradas.
O Blender então criará dois arquivos, suzanne.obj e suzzane.mtl:
* O arquivo .obj conterá as mesh(malha): de vértices e faces.
* O arquivo .mtl conterá as informação dos materiais(Material Template Library)
Por enquanto vamos apenas carregar a malha.

## Formação do arquivo

Examinando o arquivo .obj com um editor de texto, vamos ver que o formato do arquivo é muito simples:
* Estruturado em linhas
* Linhas iniciadas com # são comentários
* o : representa um novo objeto.
* v : representa um vertex
* vn : representa uma normal
* f : representa uma face, usando o índice de vértice, iniciando em 1
Precisamos preencher algumas arrays em C:
* De vértices
* De elementos
* De normals (usado em calcular a iluminação)
O formato também tem outros recursos, mas por enquanto vamos deixar eles de lado.
Aqui temos uma primeira implementação crua para trabalhamos nossos objetos.
Nosso interpretador será limitado (sem suporte para múltiplos objetos, alternado os formatos dos vértices, polígonos, etc.), mas isto será suficiente para o que precisamos.
Nós usaremos vectors C++ para simplificarmos o gerenciamento de memória(sem malloc) Vamos passar argumentos por referencia, principalmente por que o acesso à ponteiro em vector fica horrível((*elements)[i])
Então podemos carregar o arquivo .obj assim:
E passaremos para OpenGL usando:
E por ultimo, vamos ajustar nossa visualizaçao de acordo com o sistem de coordenada Y-is-top, e a camera voltada para Suzzane:
Eu enganei um pouco e implementei um modelo de iluminação de Gouraud, vamos melhorar aos poucos.

## Flat-shading - duplicando vértices e normals

Como discutimos em Tutorial de texturização, as algumas vértices obtém um valor diferente dependendo de qual face é usado.
Isto acontece se nós não compartilharmos as normals (e escolheu um rosto arbitrário quando calcularmos uma vertex' normal, como fizemos acima). Neste caso nós precisamos duplicar um vértice toda vez que for usado com uma normal diferente e depois recriando o array de elementos. Isto fará que demore mais tempo para carregar mas será mais rápido para o OpenGL processo a longo prazo. quanto menos vértices for enviado para OpenGL melhor. ou, como dizemos anteriormente, neste exemplo apenas duplicaremos as vértices uma única vez quando eles aparecem e nós podemos fazer sem a array de elementos.
Com este ajuste, nós podemos ter uma flat-shading: a variável varying atualmente varia entre os vértices no fragment shader, por que as normal serão os mesmos para as 3 vértices do triângulo.

## Calculando as normals

Nosso algoritmos funciona, mas se duas faces forem referenciadas pelo mesmo vetor, em seguida a ultima face sobrescrever a normal para este vértice, isto significa que o objeto pode ficar bem diferente dependo da ordenação das faces.
Para consertar isto, nós calcularemos as normal entre as duas faces. Para calcular dois vetores, você pega metade do primeiro vetor mais metade do segundo vetor. Usaremos o nb_seen para guardar o coeficiente do vetor, assim podemos calcular com novo vetor em qualquer numero de vezes, sem gravar toda lista de vetores:

## Normals pré calculadas

TODO: melhorar interpretador para suportar .obj com normals.
O formato OBJ suporta normal pré calculadas. Isto é interessante se ele for especificado nas faces, quando estiver presente em váris faces, podemos ter normals diferentes, que significa que temos que usar a duplicação de vertices usadas na técnica especificada acima.
Por exemplo, uma exportação basica da Suzanne referencia as verticés #1 com duas normals diferente #1 e #7:
Para comparar, o formato MD2/MD3 (usado pelo Quake e outros) também inclui normal pré calculadas, mas elas são anexas no vértices e não nas faces.