segunda-feira, 17 de dezembro de 2012

Trabalho Individual I



Rasterização

Neste primeiro trabalho, foi solicitada a criação de três funções de rasterização. Foram elas:


  • PutPixel - Colocar um pixel na tela, dado a posição do pixel na tela bem como sua cor. 
     [  Parâmetros: (x,y,r,g,b,a)  ] - (x,y): coordenadas, (r,g,b,a): cor.
  • DrawLine -  Desenhar uma linha na tela(pelo algoritmo de Bresenham), utilizando a posição inicial e final da linha e também a  sua cor RGBA. 
     [  Parâmetros: (x1,y1,x2,y2,r,g,b,a)  ] - (x1,y1): pto inicial, (x2,y2): ponto final, (r,g,b,a): cor.
  • DrawTriangle -  Desenhar um triangulo dado três pontos e sua cor RGBA. 
     [  Parâmetros:(xa,ya,xb,yb, xc,yc, r,g,b,a)  ] - (xa,ya), (xb,yb), (xc,yc): coordenadas dos 3      pontos, (r,g,b,a): cor.

Obs: Utilizou-se apenas a linguagem C/C++ para codificar as funções e o GLUT para rodar o framework.

A função putPixel é simples de ser implementada, sendo necessário apenas conhecer o offset que é o endereço do bloco de memória para determinada coordenada e saber utiliza-lo no ponteiro FBptr que apontava para o inicio da memória.

O cálculo do offset se dá por: 4*x + 4*y*IMAGE_WIDTH, onde (x,y) são as coordenadas. Incrementando obtemos a posição das outras componentes de cor.

Offset das componente:

R = 4*x + 4*y*IMAGE_WIDTH      
G = 4*x + 4*y*IMAGE_WIDTH + 1
B = 4*x + 4*y*IMAGE_WIDTH + 2
A = 4*x + 4*y*IMAGE_WIDTH + 3

A figura abaixo mostra a execução da função PutPixel, colocando 4 pontos de cores diferentes em posições distintas na tela.

Figura 1. Exemplo da função putPixel.

Parâmetros: (200, 100, 255, 255, 0, 255); - amarelo
              (150, 110, 255, 0, 0, 255); - vermelho
              (128, 256, 0, 0, 255, 255); - azul
              (310, 335, 0, 255, 0, 255); - verde

Próxima etapa: Função drawLine.

Nesta função o algoritmo implementado foi o de Bresenham. Também conhecido como algoritmo do ponto médio, pois a partir do cálculo do mesmo, decide-se qual pixel deve ser ligado a fim de formar uma boa aproximação a uma linha reta entre dois pontos indicados.

Para as retas do 1º octante, dado um pixel sobre a reta, o próximo pixel é para direita  (E) ou para Direita acima (NE). Tendo o pixel (xi,yi), o próximo pixel é NE em (xi+1, yi+1) ou E em (xi+1, yi).
 Fazendo dy = y2 - y1,  e  dx = x2 - x1, a equação da reta em termos de sua inclinação pode 
ser escrita como:
 y = dy/dx*x + B

para:
d = 2 * dy - dx;
se d < 0
incrementamos para direita (E). Do contrário, incrementamos para direita acima (NE).

Exemplo da função drawLine com os seguintes parâmetros: (10, 255, 255, 0, 0, 255, 0, 255).

Figura 2. Exemplo da função drawLine.

E por fim, a função drawTriangle. Esta função é simples de ser implementada, pois é só chamar a função drawLine três vezes. A única ponderação a ser feita é matemática, uma vez que os pontos precisam ser não colineares para que haja a formação do triângulo.


Figura 3. Exemplo da função drawTriangle.

Parâmetros: (200, 150, 200, 350, 400, 350, 0, 0, 255, 255);

A nível de ilustração, abaixo temos a imagem da chamada de várias funções putPixel, bem como uma chamada da função drawLine e drawTriangle.

Figura 4. Exemplo de chamada das três funções: putPixel, drawLine e drawTriangle.

O algoritmo de Bresenham, inicialmente causou dificuldade de entendimento na implementação. Portanto, devido ao maior grau de complexidade, a função drawLine foi a mais custosa.
As funções ficaram com muitos parâmetros, devido a especificar a cor, porém tudo está de fácil entendimento.

Referências

http://pt.wikipedia.org/wiki/Algoritmo_de_Bresenham

http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm

http://marciobueno.com/arquivos/ensino/cg/CG_03_Primitivas_Graficas.pdf

Foley et al.; Computer Graphics - Principles and Practice with C; Addison-Wesley.

Slides das aulas.







segunda-feira, 10 de dezembro de 2012