Skip to content

Repositório utilizado para expor os resultados das implementações da disciplina de Computação Gráfica, com a utilização do Opengl

Notifications You must be signed in to change notification settings

mateustoin/Computacao-Grafica

Repository files navigation

Aqui são apresentados os resultados das atividades práticas da disciplina de Introdução à Computação Gráfica, ministrada no Período Suplementar na UFPB.

Sumário

  1. Configuração do Ambiente
  2. Atividade 1 - Rasterização
  3. Atividade 2 - OpenGL Moderno
  4. Atividade 3 - Implementação do Pipeline Gráfico
  5. Atividade 4 - Implementação de Modelos de Iluminação

Configuração do Ambiente

Para a realização das atividades a seguir, foi seguido um guia de instalação dos pacotes básicos que pode ser encontrado neste link. Os comandos básicos para realizar a instalação foram:

sudo apt-get update
sudo apt-get install libgl1-mesa-dev
sudo apt-get install build-essential
sudo apt-get install libglew1.5-dev freeglut3-dev libglm-dev

Caso ocorra algum problema com os drivers ou versão, o link citado anteriormente fala sobre possíveis soluções. Para a execução dos códigos basta acessá-los nas pastas do repositório e executar:

make
./nome-do-executável


Simulando o acesso a memória de vídeo do computador, através de um framework fornecido pelo professor, foi feita a rasterização de pontos e linhas. A partir delas, também foi feita a rasterização de triângulos, com as arestas baseadas na rasterização das linhas feitas anteriormente. E com a criação de retas, também foi feita a interpolação linear das cores das duas pontas, para que haja uma transição entre as duas cores em sua extensão

Tamanho da tela definida pelo framework é de 512x512 pixels

Struct foi utilizado para a definição das cores

Todas as cores utilizadas no trabalho foram Branco, Vermelho, Verde, Azul e uma cor randômica (próximo do Lilás) respectivamente, definidas por:

Color ColorWhite = {.red = 255, .green = 255, .blue = 255, .alpha = 255};
Color ColorRed = {.red = 255, .green = 0, .blue = 0, .alpha = 255};
Color ColorGreen = {.red = 0, .green = 255, .blue = 0, .alpha = 255};
Color ColorBlue = {.red = 0, .green = 0, .blue = 255, .alpha = 255};
Color ColorRandom = {.red = 100,.green = 59, .blue = 156, .alpha = 255};

Rasterização do ponto

A implementação da rasterização do ponto foi feita com a função PutPixel(int x, int y, cor RGBA), onde:

  • X contém a informação da coordenada x na tela
  • Y contém a informação da coordenada y na tela
  • RGBA contém as informações referentes a cor do pixel desenhado, red (vermelho), green (verde), blue (azul) e alpha (transparência)

Resultados

Neste exemplo podemos ver a ação da função PutPixel(x, y, RGBA) com a impressão de um pixel de cada cor na primeira linha da janela.

Na imagem a seguir, a fim de mostrar de uma forma mais clara a ação do PutPixel(x, y, RGBA) na tela, através de uma estrutura de repetição, foram desenhados blocos de cores em toda a tela.

Com isso foi possível mostrar que para cada espaço na tela disponível, foi possível acessar um endereço de memória e colocar as informações de cores desejadas para a criação de imagens.

Rasterização da linha

A implementação da rasterização da linha foi feita com a função DrawLine(int x1, int y1, cor RGBA1, int x2, int y2, cor RGBA2), onde:

  • X1 e Y1 contém a informação da coordenada (x1, y1) do primeiro ponto na tela, junto com RGBA1 contendo as informações da sua cor
  • X2 e Y2 contém a informação da coordenada (x2, y2) do segundo ponto na tela, junto com RGBA2 contendo as informações da sua cor

Uma reta é criada entre os dois pontos dados, utilizando uma variação do algoritmo de Bresenham, conhecida como Mid Point Line. Além disso, como foi mencionado anteriormente, também foi feita uma interpolação linear das cores entre os dois pontos.

Resultados

Na figura a seguir é possível visualizar algumas retas criadas para testar o desenho das linhas em todos os octantes do plano.

Problemas e Soluções

A parte mais dificultosa para a rasterização das linhas foram as condições que precisam ser levadas em consideração para que as linhas pudessem ser desenhadas em todos os octantes possíveis do plano. Depois de analisar o problema e definir as restrições a serem seguidas, o seguinte algoritmo foi seguido:

  • Restrição 1

    • Problema: Verifica se ΔX é negativo. Se for, é porque a linha está crescendo para o lado negativo de X.
    • Solução: Troca o ponto inicial pelo ponto final, assim em vez da reta ser desenhada para a direção negativa do X, agora será desenhada para o lado positivo.
  • Restrição 2

    • Problema: Verifica se ΔY é negativo. Se for, é porque a linha está crescendo para o lado negativo de Y.
    • Solução: Multiplica ΔY por -1. Assim a referência para os pontos Leste e Nordeste ficam corretas. Depois disso, como o ponto Y inicial é maior que o ponto Y final, para o desenho ser feito corretamente, ele deve ser decrementado em vez de incrementado.
  • Restrição 3

    • Problema: Verifica se ΔY é maior que ΔX. Se for, é porque a reta cresce mais para o lado de Y do que em X.
    • Solução: Tudo que era em relação a X, agora passará a funcionar em relação a Y. Portanto, todos os ΔY e ΔX devem ser trocados no cálculo de d inicia, incremento em Leste e incremento em Nordeste. Quando o leste é escolhido, também mudará para crescer em Y, não X. Além disso, a reta que era desenhada enquanto x1 <= x2, agora passa a ser desenhada enquanto y1 <= y2.
  • Restrição 4

    • Problema: Verifica se ΔY é maior que ΔX e também se ΔY é negativo. Se corresponder a essas duas condições, é porque a reta cresce mais para o lado de Y negativamente em relação a X.
    • Solução: A solução é semelhante a anterior, porém seguirá a mesma lógica da restrição 2. Agora crescerá em relação a Y e deverá ser decrementada, pois o ponto final de Y é menor que o inicial. Além disso, a condição y1 <= y2 não será mais válida, pois o ponto inicial naturalmente é maior que o final. Então o desenho será realizado enquanto a condição y1 > y2 acontecer.

Rasterização do Triângulo

A implementação da rasterização da linha foi feita com a função DrawLine(int x1, int y1, cor RGBA1, int x2, int y2, cor RGBA2, int x3, int y3, cor RGBA3), onde:

  • X1 e Y1 contém a informação do vértice (x1, y1) do triangulo, junto com RGBA1 contendo as informações da sua cor
  • X2 e Y2 contém a informação do vértice (x2, y2) do triangulo, junto com RGBA2 contendo as informações da sua cor
  • X3 e Y3 contém a informação da coordenada (x3, y3) do triangulo, junto com RGBA2 contendo as informações da sua cor

Resultados

O triângulo é criado utilizando a função DrawLine mostrada anteriormente. Dado os 3 vértices do triângulo, a função cria as arestas e realiza a interpolação linear das cores. Um exemplo pode ser visto a seguir:

Referências



A familiarização e configuração do ambiente para rodar o OpenGL moderno, versão 3.3 especificamente, é essencial para a execução das próximas atividades. Portanto, esta atividade consiste na execução do código oferecido pelo professor para a validação do ambiente de desenvolvimento do aluno.

Resultados

Para a execução do código bastou apenas seguir a instalação dos pacotes mencionados na seção Configuração do Ambiente. O código executado gera a imagem mostrada no gif de execução:

Referências



Resultados

Os resultados a seguir são frutos das instruções presentes no documento do trabalho 3, a fim de se obter os resultados esperados, descritos no próprio documento.

Exercício 1: Escala

Para a modificação da escala foram utilizados os seguintes valores:

(x, y, z) = (1/3, 3/2, 1)

A Matriz Model resultante pode ser vista a seguir e a figura resultante logo após.

float model_array[16] = { 0.33f, 0.0f, 0.0f, 0.0f, 
                          0.0f, 1.5f, 0.0f, 0.0f, 
                          0.0f, 0.0f, 1.0f, 0.0f, 
                          0.0f, 0.0f, 0.0f, 1.0f};

glm::mat4 model_mat = glm::make_mat4(model_array);

Exercício 2: Translação

Para a modificação da translação foram utilizados os seguintes valores:

(x, y, z) = (1, 0, 0)

A Matriz Model resultante pode ser vista a seguir e a figura resultante logo após.

float model_array[16] = { 1.0f, 0.0f, 0.0f, 0.0f, 
                          0.0f, 1.0f, 0.0f, 0.0f, 
                          0.0f, 0.0f, 1.0f, 0.0f, 
                          1.0f, 0.0f, 0.0f, 1.0f};

glm::mat4 model_mat = glm::make_mat4(model_array);

Para a modificação da translação foram utilizados os seguintes valores:

(x, y, z) = (1, 0, 0)

A Matriz Model resultante pode ser vista a seguir e a figura resultante logo após.

float model_array[16] = { 1.0f, 0.0f, 0.0f, 0.0f, 
                          0.0f, 1.0f, 0.0f, 0.0f, 
                          0.0f, 0.0f, 1.0f, 0.0f, 
                          1.0f, 0.0f, 0.0f, 1.0f};

glm::mat4 model_mat = glm::make_mat4(model_array);

Exercício 3: Projeção Perspectiva

Para a modificação da Projeção foi utilizado o seguinte valor de d (fator de projeção), mantando a distorção perspectiva anterior:

d = 0.5

A Matriz de Projeção resultante pode ser vista a seguir e a figura resultante logo após.

float proj_array[16] = { 1.0f, 0.0f, 0.0f, 0.0f, 
                         0.0f, 1.0f, 0.0f, 0.0f, 
                         0.0f, 0.0f, 1.0f, -2.0f, 
                         0.0f, 0.0f, 0.5f, 1.0f};

glm::mat4 proj_mat = glm::make_mat4(proj_array);

Exercício 4: Posição da Câmera

Nesse caso é preciso fazer uma transformação do espaço do Universo para o espaço da Câmera, como indica a figura a seguir. Para isso, um sistema de coordenadas X, Y e Z da própria câmera precisa ser criado, para que a referência visual possa ser vista a partir dela, sem modificar a cena.

Levando em consideração as mudanças realizadas nas transformações anteriores, seguindo o passo a passo visto durante as aulas, os seguintes dados da câmera foram utilizados para os cálculos dos vetores de base da câmera e matrizes.

Posição da Câmera = (-1/10, 1/10, 1/4)
Vetor Up da câmera = (0, 1, 0)
Ponto que a câmera aponta = (0, 0, 0)

Com isso, o código a seguir foi utilizado para gerar o resultado exibido na imagem após.

float camera_position[3]  = {-0.1f, 0.1f, 0.25f},
      camera_up[3]   = {0.0f, 1.0f, 0.0f},
      camera_pointer[3] = {0.0f, 0.0f, 0.0f};

glm::vec3 cam_position  = glm::make_vec3(camera_position);
glm::vec3 cam_up   = glm::make_vec3(camera_up);
glm::vec3 cam_pointer = glm::make_vec3(camera_pointer);

glm::vec3 cam_Z = glm::make_vec3(glm::normalize(cam_position - cam_pointer));
glm::vec3 cam_X = glm::make_vec3(glm::normalize(glm::cross(cam_up, cam_Z)));
glm::vec3 cam_Y = glm::make_vec3(glm::cross(cam_Z, cam_X));

glm::mat4 B = glm::mat4 ( glm::vec4(cam_X.x, cam_Y.x, cam_Z.x, 0.0f),
                            glm::vec4(cam_X.y, cam_Y.y, cam_Z.y, 0.0f),
                            glm::vec4(cam_X.z, cam_Y.z, cam_Z.z, 0.0f),
                            glm::vec4(0.0f,   0.0f,   0.0f, 1.0f));

glm::mat4 T = glm::mat4 ( glm::vec4(1.0f, 0.0f, 0.0f, 0.0f),
                        glm::vec4( 0.0f, 1.0f, 0.0f, 0.0f),
                        glm::vec4(0.0f, 0.0f, 1.0f, 0.0f),
                        glm::vec4(-cam_position.x, -cam_position.y, -cam_position.z, 1.0f));

glm::mat4 view_mat = B * T;

Exercício 5: Transformações Livres

Na transformação livre as modificações devem ser feitas nas Matrizes de Model, View e Projection. Para a matriz de projetão, foi utilizado um d = 1. As cores dos triangulos foram modificadas e o triângulo verde foi mais afastado do branco. A posição da câmera foi modificada para que a visão fosse vista pela direita e não pela esquerda, como nos exercícios anteriores. O valor da posição pode ser visto a seguir:

float camera_position[3] = {0.25f, 0.25f, 0.25f}

Por fim, a matriz model pode ser vista a seguir, gerando a imagem resultante logo após.

float model_array[16] = {0.25f, 0.0f, 0.0f, 0.0f, 
                            0.0f, 0.66f, 0.0f, 0.0f, 
                            0.0f, 0.0f, 1.0f, 0.0f, 
                            0.0f, 0.0f, 0.0f, 1.0f};

Referências



O principal objetivo desta atividade é familiarizar os alunos com os mdoelos de iluminação que são comumente utilizados na rasterização. Estes modelos podem ser classificados entre ambiente, difuso e especular. Todos devem ser feitos utilizando o vertex shader do OpengGL.

Resultados

Para a execução do código bastou apenas seguir a instalação dos pacotes mencionados na seção Configuração do Ambiente e adicionar a biblioteca glm. O código executado sem modificações gera a imagem mostrada a seguir:

Exercício 1: Implementação do Modelo de Reflexão Difuso

A implementação deste modelo consiste em adicionar o modelo de iluminação difuso, além do ambiente, mostrado na imagem anterior. As instruções fornecidas no material de apoio desta atividade foram bem claras em relação ao cálculo do vetor normal N e vetor L, que aponta do vértice para o ponto da fonte de luz. Os códigos utilizados no vertex_shader para realizar as operações podem ser vistos a seguir:

vec3 L = normalize(I_p_pos - (model_mat * vec4(obj_spc_vertex_pos, 1.0)).xyz);
vec3 N = normalize(mat3(transpose(inverse(model_mat))) * obj_spc_N);

Após o cálculo dos vetores, resta apenas calcular o modelo de iluminação difuso (note que para o cálculo do produto interno foi utilizada a função dot):

I = I_a * k_a + I_p * k_d * max(dot(L, N), 0.0f);

Com isso, foi possível obter o seguinte resultado:

Exercício 2: Implementação do Modelo de Reflexão Especular

Agora deve incluir não só o modelo de iluminação ambiente e difuso, mas também o modelo especular. As modificações realizadas no vertex_shader também foram as indicadas no documento, para o cálculo do vetor de reflexão R e o vetor da câmera V. As adições em relação aos cálculos anteriores foram:

vec3 R = -reflect (L, N);
vec3 V = normalize(cam_pos - (model_mat * vec4(obj_spc_vertex_pos, 1.0)).xyz);

Após o cálculo dos vetores, resta apenas calcular o modelo de iluminação de reflexão especular, com o valor de n = 64, com o valor sendo colocado direto no código:

I = I_a * k_a + I_p * (k_d * max(dot(L, N), 0.0f) + k_s * pow(max(dot(R, V), 0.0f), n));

Com isso, foi possível obter o seguinte resultado:

Referências



About

Repositório utilizado para expor os resultados das implementações da disciplina de Computação Gráfica, com a utilização do Opengl

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages