sábado, 22 de abril de 2017

Atividade 2 - Aplicação do Pipeline Gráfico a um objeto 3D

Nesta atividade, nos foi orientado a desenvolver, usando as ferramentas disponibilizadas para o primeiro trabalho, o Pipeline Gráfico que foi apresentado em sala, que converte a câmera ortogonal em perspectiva, carregar um uma malha de triângulos disponibilizada pelo professor, no formato ".obj" e em consequência disso poder aplicar transformações no mesmo, tais como translação ou rotação.

1. "Loading" do objeto para o programa

Para carregar o objeto, foram usadas duas bibliotecas recomendadas pelo professor: O loader Assimp, para extrair as informações do arquivo, e o GLM(OpenGL Mathematics) para realizar os cálculos com matrizes e vetores.
O carregamento do objeto com o Assimp é feito de maneira bem simples, até por que eu já tinha experiência com o uso dele da outra disciplina da sexta (Physically Based Rendering), usando a classe aiLoader todas as informações do obj são disponibilizadas de maneira simples. Então só foi necessário criar uma lista encadeada que guardaria todos os triângulos do objeto para serem acessados mais tarde. Também foi criada a struct Triângulo, que contém três glm::vec4(Vetor de quatro elementos) para guardar as informações dos pontos e três glm::vec3(Vetor de três elementos) para guardar os valores de cor de cada ponto.


2. Criação de Matrizes Iniciais


2.1 Criação da Câmera e do seu espaço

 

Eu não criei uma classe câmera pois não achei necessário para este trabalho, ao invés disso eu criei os três vetores no próprio main, position, lookat e up.
E com estes três vetores foi possível criar o espaço da câmera como foi ensinado pelo professor e usando o GLM para auxiliar a fazer os cálculos:


2.2 Construção da Matriz Model

 

A matriz Model é a que dita as transformações que serão feitas no objeto para que ele vá para o espaço do universo, ela é individual para cada objeto, e pode ser constituída de várias outras matrizes multiplicadas, neste caso só foi usada uma matriz identidade, já que não seriam feitas transformações no objeto inicialmente.



2.3 Construção da Matriz View

 

A matriz view é criada com os parâmetros da câmera e os vetores do seu espaço, ela transporta os vértices para o espaço da câmera, que foi criado anteriormente.


Depois as matrizes Model e View são multiplicadas para criar a ModelView.

2.4 Construção da Matriz Projection

 

A matriz Projection é a que vai transformar a cena para que ela tenha perspectiva, fazendo com que todos os vértices tenham sua posição modificada de acordo com a distância dos mesmos da câmera.



Multiplicando a Projection com a ModelView nós criamos a ModelViewProj (mvp).


3. A função PrintObj()

Como a matriz ModelViewProj é diferente para cada objeto, a função PrintObj deve receber ela e, logicamente, a lista de triângulos que corresponde ao objeto:



3.1 Levando os vértices ao espaço da câmera

Para isso nós só precisamos multiplicar todos os vértices do objeto pela matriz ModelViewProj, ou mvp, e todas as operações citadas antes serão feitas ao mesmo tempo:


3.2 Trazendo os vértices de volta para o espaço homogêneo

Depois de realizadas as transformações com a mvp, os vértices deixaram de ter seus últimos elementos iguais, para consertar isso nós precisamos dovidir todos os elementos do vértice pelo valor do último, assim fazendo com que todos tenham o último elemento igual a 1:

3.3 Criação da Matriz Viewport

A Matriz Viewport é quem é responsável por converter os vértices do espaço da câmera para as coordenadas da tela, para isso nós precisamos criar três matrizes, uma de Translação e duas de escala. A translação vai colocar a origem do espaço no centro da tela e as escalas são para inverter o y, para a imagem nçaoi ficar de cabeça para baixo e a outra é para a imagem se ajustar à resolução da tela:

Para converter os vértices do objeto para as coordenadas da tela só é preciso multiplicá-los pela matriz Viewport:

Para imprimir o objeto na tela foi necessário chamar a função DrawTriangle() do trabalho passado para cada triângulo da lista, e o resultado está na imagem abaixo:
Comparação com o Loader do professor
Para que o resultado ficasse igual ao exemplo enviado pelo professor foi necessário mudar a posição da câmera para o ponto (0,0,4) e o d da câmera perspectiva para 2.

4. Aplicando um rotação ao objeto

Para que o objeto roationasse uniformemente no programa foi criada uma matriz rotação que foi multiplicada à matriz model, onde o ângulo de rotação era incrementado em 0.01 a cada iteração do loop principal:

e o resultado é mostrado neste vídeo:



5. Conclusões

Como pode-se ver os objetivos traçados para esta atividade foram alcançados com êxito, apesar de ter passado muito tempo tentando resolver um problema que eu pensava que era na importação do objeto, mas ocorria por que as operações de marizes no GLM são feitas da esquerda para a direita, como foi visto acima o código já está da maneira correta, se eu tentasse usar a multiplicação na ordem que o professor ensinou sempre dava segmentation fault na hora de executar, mas depois de resolvido este problema tudo ocorreu normalmente.


Nenhum comentário:

Postar um comentário