RASTERIZAÇÃO

APLICAÇÕES DE TÉCNICAS DE RASTERIZAÇÃO EM COMPUTAÇÃO GRÁFICA.....

PIPELINE GRÁFICO

ETAPAS DO PIPELINE GRÁFICO.....

sexta-feira, 1 de maio de 2015

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.

Configuração Inicial

Antes de começar o trabalho foi preciso instalar o OpenGL/Glut onde foi instalado o FreeGlut e FreeGlut-Dev em ambiente Linux.

Rasterização de Ponto

Para desenhar um pixel foi utilizado um ponteiro FBptr onde o mesmo aponta para o inicio da memória de vídeo, onde especificamente trata-se do pixel(0,0).
Todo pixel da tela é formado por quatro componentes (R,G,B,A), as quais em conjunto, ocupam um espaço em memória de 4 bytes, sendo 1 byte para cada componente. Podemos acessar qualquer pixel da tela.

Foi feito uma estrutura para organizar e armazenar os valores do pixel.










Em seguida temos a função PutPixel, onde recebe como parâmetros as coordenadas do pixel e a cor ao qual será exibido na tela.









Para testar a função foram feitas modificações na função MyGlDraw, como mostrado no trecho de código abaixo:









Após compilar o código e executá-lo, temos o seguinte resultado:


Rasterização de Retas

Para determinada tarefa utilizou-se a função DrawLine onde a mesma é responsável pela rasterização da reta. Ela receberá como parâmetros dois pontos e suas respectivas cores. A reta formada por esses dois pontos, partindo do ponto inicial com coordenadas (x0, y0)  até chegar ao ponto final com coordenadas (x1, y1) . O algoritmo utilizado como base para a execução desta função será o algoritmo de Bresenham.

Algoritmo de Brasenham

O algoritmo de Bresenham é um algoritmo utilizado para criar retas, ele utiliza uma variável de decisão normalmente chamada “d”. A cada novo ponto desenhado numa determinada posição (x,y), o valor de d é recalculado para determinar onde será desenhado o próximo ponto. Se o novo valor for positivo, o próximo ponto será desenhado no pixel que se encontra nas coordenadas (x+1, y+1), caso contrário, o próximo ponto será desenhado nas coordenada (x+1, y).

void DrawLine(ponto p_inicial, ponto p_final, color cor){

    int slope;
    int dx, dy, incremento_E, incremento_NE, d, x, y;

    //inverte a linha x1 > x2
    if (p_inicial.x > p_final.x){
        DrawLine(p_final, p_inicial, cor);
         return;
    }//if
    dx = p_final.x - p_inicial.x;
    dy = p_final.y - p_inicial.y;

    if (dy < 0){ //Incremento decrescente
        slope = -1;
        dy = -dy;
    }
    else{//Incremento Crescente
       slope = 1;
    }   

    // Constante de Bresenham
    incremento_E = 2 * dy;
    incremento_NE = 2 * dy - 2 * dx;
    d = 2 * dy - dx;

    x = p_inicial.x;/**inicia x com o valor de p_inicial**/
    y = p_inicial.y;

    PutPixel(p_inicial.x, p_inicial.y, cor);

    while(x != p_final.x){
        if (d <= 0){
          d += incremento_E;
          x++;/**Adicionado incremento de x**/
        }
        else{
          d += incremento_NE;
          x++;/**Adicionado incremento de x**/
          y += slope;
        }
        PutPixel(x, y, cor);
    }

}//fim da DrawLine


Para testar este algoritmo,  a modificação na função MyGlDraw é mostrada no trecho de código a seguir e posteriormente o resultado obtido:





Interpolação Linear e Rasterização para todos os quadrantes.

O caso mais simples de resolver é quando x0 > x1. Sempre que este caso ocorrer basta inverter os pontos inicial e final da reta, o resultado será a mesma reta, só que agora com x0 < x1. Com isso é garantido que x0 < x1 sempre irá ocorrer.
Para o caso de y0 > y1, um dos problemas é que dy terá sinal negativo, a solução será inverter o sinal de dy para que ele volte a ser positivo. O outro problema é que y agora deverá ser decrementado e não somente incrementado, como o algoritmo faz. A solução será criar uma variável que permita que as coordenadas y sejam incrementadas ou decrementadas dependendo da situação.
Para o caso de dx < dy, o algoritmo é praticamente o mesmo, basta apenas trocar todos valores de dx por dy e vice-versa, levando em consideração que agora y também irá variar quando d<=0, e não x.
Feitas essas modificações e implementado a interpolação linear, o código final da função DrawLine é mostrado abaixo:
void DrawLine(ponto p_inicial, ponto p_final, color color0, color color1){
    color cor;
    int slope = 1; // Diz se o incremento de y é crescente ou decrescente
    int dx, dy, incremento_E, incremento_NE, d, x, y;
    int i = 0;
   
    // Onde inverte a linha x1 > x2
    if (p_inicial.x > p_final.x){
        DrawLine(p_final, p_inicial, color0, color1);
         return;
    }//if
    dx = p_final.x - p_inicial.x;
    dy = p_final.y - p_inicial.y;

    if(p_inicial.y > p_final.y){
    dy = -dy;
    slope = -1;
    }else{
    slope = 1;       
    }

    /*if (dy < 0){ //Incremento decrescente
        slope = -1;
        dy = -dy;
    }
    else{//Incremento Crescente
       slope = 1;
    }*/
    PutPixel(p_inicial.x, p_inicial.y, color0);
   
    /*// Constante de Bresenham
    incremento_E = 2 * dy;
    incremento_NE = 2 * dy - 2 * dx;
    d = 2 * dy - dx;
*/
    x = p_inicial.x;
    y = p_inicial.y;

    //PutPixel(p_inicial.x, p_inicial.y, color);/**Antes não tinha essa linha**/
    if(dx >= dy){
    // Constante de Bresenham
        incremento_E = 2 * dy;
        incremento_NE = 2 * dy - 2 * dx;
        d = 2 * dy - dx;

    while(x != p_final.x){
        if (d <= 0){
          d += incremento_E;
          x++;/**Adicionado incremento de x**/
        }
        else{
          d += incremento_NE;
          x++;/**Adicionado incremento de x**/
          y += slope;
        }

    /* Interpolação Linear de cores*/
    i++;
    int R = color0.R - ((i)/(float)dx) * (color0.R - color1.R);
    int G = color0.G - ((i)/(float)dx) * (color0.G - color1.G);
    int B = color0.B - ((i)/(float)dx) * (color0.B - color1.B);
    int A = color0.A - ((i)/(float)dx) * (color0.A - color1.A);
    cor.R = R;
    cor.G = G;
    cor.B = B;
    cor.A = A;   
    PutPixel(x, y, cor);
    }//while
 
  }else{
    int d = 2 * dx - dy;
        int incremento_E = 2 * dx;
        int incremento_NE = 2 * dx - 2 * dy;

        while (y != p_final.y){//Enquanto y for diferente de y1
            if (d <= 0) {//se d <= 0
                d += incremento_E;//d será somado ao valor de incr_e
                y+=slope;
            } else {//Senão,
                d += incremento_NE;//d será somado ao valor de incr_ne
                x++;
                y+=slope;
            }

    /* Interpolação Linear de cores*/
    i++;
    int R = color0.R - ((i)/(float)dx) * (color0.R - color1.R);
    int G = color0.G - ((i)/(float)dx) * (color0.G - color1.G);
    int B = color0.B - ((i)/(float)dx) * (color0.B - color1.B);
    int A = color0.A - ((i)/(float)dx) * (color0.A - color1.A);
    cor.R = R;
    cor.G = G;
    cor.B = B;
    cor.A = A;   
   
       PutPixel(x, y, cor);
    }   
}
}//fim da DrawLine
 
Ao compilar e executar temos o seguinte resultado: 
Rasterização de Triângulos

Feito todos os processos anteriores, rasterizar triângulo passa a ser o mais fácil, onde é só chamar a função DrawLine 3 vezes. Para isso, foi criado a função DrawTriangle, onde ela recebe como parâmetros os 3 pontos do triângulo e suas cores, onde a partir daí será feito as retas que formaram o triângulo.



Por fim, temos o seguinte resultado:


  

Referências

RASTERIZAÇÃO. In: WIKIPÉDIA, a enciclopédia livre. Flórida: Wikimedia Foundation, 2015. Disponível em: http://pt.wikipedia.org/w/index.php?title=Rasteriza%C3%A7%C3%A3o&oldid=35151352. Acesso em: 01 maio 2015.
 
ALGORITMO DE BRESENHAM. In: WIKIPÉDIA, a enciclopédia livre. Flórida: Wikimedia Foundation, 2015. Disponível em: http://pt.wikipedia.org/w/index.php?title=Algoritmo_de_Bresenham&oldid=34646662. Acesso em: 02 maio 2015.
 
LUCIANA MONTERA. INTERPOLAÇÃO LINEAR. Disponível em: http://www.facom.ufms.br/~montera/Interpolacao_alunos.pdf. Acesso em: 02 maio 2015.
 
 

← Anterior Página inicial