quarta-feira, 9 de março de 2016

Rasterização

            Neste trabalho vamos falar um pouco sobre rasterização, utilizando as funções putPixel() (Cria um pixel), drawLine() (Desenha uma linha) e drawTriangle() (Desenha um triangulo). Como nos sistemas operacionais atuais protegem algumas áreas da memória de vídeo, utilizaremos um framework desenvolvido pelo professor Christian Pagot que simula o acesso a memória.


Mas, o que é Rasterização?  

        Rasterização,  é a tarefa de converter uma imagem vetorial em uma imagem raster (pixels ou pontos) para a saída em vídeo ou impressora. O termo raterização também é utilizado para converter uma imagem formada por vetores para um arquivo no formato bitmap (SVG para PNG).



Resultado de imagem para rasterização



Framebuffer

       É uma memória capaz de armazenar e transferir para a tela os dados de um quadro de imagem completa. Dentro do framebuffer temos algumas subdivisões, uma delas é o color buffer responsável pela representação das cores, a mais utilizada é o RGBA (Red, Green, Blue e Alpha), onde para cada cor é definido um byte.


Vamos apresentar agora três funções básicas de rasterização:


PutPixel() - Rasterização de pontos

      Inicialmente para plotar um pixel na tela, de acordo com as coordenadas do ponto e a cor, é necessário a utilização do ponteiro FBptr. Para sabermos em qual posição na memória gravar e qual cor será determinada para o pixel, usaremos o offset que é calculo da seguinte forma x*4 + y*4*IMAGE_WIDTH, logo teremos o código abaixo






Implementados na função, teremos o seguinte resultado





DrawLine() - Rasterização de linhas (Algoritmo de Bresenham)

         O algoritmo de bresenham realiza a rasterização de segmentos de reta empregando apenas operações aritméticas de inteiros, portanto permite um maior desempenho, baseando-se no critério do ponto médio.

        Para determinar a posição do ponto médio em relação a reta, consideramos a forma implícita da equação da reta

f(x,y) = ax + by + c



        Como está representado na figura acima, a linha reta intersecta duas colunas de pixels, para cada coluna existem dois pixels que se encontram mais próximos a reta, um abaixo e outro acima desta.


        
         Podemos representar o algoritmo de bresenham da seguinte forma
        





Com isso, entendemos que

         - Devemos calcular dx = x2-x1, dy = y2-y1, d= 2dy-dx, incE = 2dy, incNE = 2(dy-dx).
       
         - Inicializar as variáveis x e y marcar o pixel com esta coordenada.

         - Se d<=0, incrementar d de incE, caso contrário d de incNE e incrementar y de uma              unidade. 


       Para entendemos como funciona, devemos saber que o que determina a posição da reta no octante é o dx e dy. Assim sabemos que

       - dx>0 e dy>0  1º ou 2º octantes 
       - dx<0 e dy>0  3º ou 4º octantes
       - dx<0 e dy<0  5º ou 6º octantes 
       - dx>0 e dy<0  7º ou 8º octantes




      

         Com isso conseguimos indentificar, por exemplo, se a reta pertence ao primeiro ou segundo octante da seguinte forma, se dx>dy ela é primeiro octante, se dy>dx é segundo octante. Assim temos o seguinte código






        Com o entendimento que tivemos para desenvolver as retas do 1º e 2º octantes, conseguimos fazer os demais.








DrawTriangle() - Rasterização de triângulos

         A rasterização de triângulos é bem simples, basta chamarmos a função drawLine()
 três vezes, podemos assim fazer dessa forma







Referências

- https://pt.wikipedia.org/wiki/Rasteriza%C3%A7%C3%A3o

- http://disciplinas.ist.utl.pt/leic-cg/textos/livro/Rasterizacao.pdf

- http://webserver2.tecgraf.puc-rio.br/~mgattass/cg/pdf/06A_RasterizacaoPPT.pdf

- https://pt.wikipedia.org/wiki/Algoritmo_de_Bresenham

- http://www.univasf.edu.br/~jorge.cavalcanti/comput_graf04_prim_graficas2.pdf

- Slides da aula