domingo, 6 de abril de 2014

mygl.h

#ifndef _MYGL_H_
#define _MYGL_H_
//#define RAND_MAX 0xFF

#include "definitions.h"
#include "math.h"
#include "stdio.h"

//*****************************************************************************
// Defina aqui as suas funções gráficas
//*****************************************************************************

struct scor {
  short R , G, B, A;
};

struct sponto{
  short x, y;
  scor cor;
};

struct slinha{
  sponto p1, p2;
};

struct striang{
  sponto p1, p2, p3;
};

sponto GeraPonto(void){
  char title[50];
  sponto ponto;

  ponto.cor.R = rand() &  0x00FF; //gera proporcao de red com os 8 bits menos significativos de rand
  ponto.cor.G = rand() &  0x00FF; //gera proporcao de green
  ponto.cor.B = rand() &  0x00FF; //gera proporcao de blue
  ponto.cor.A = 255; //gera proporcao de alpha

  ponto.x = rand() & 0x01FF ; //gera coordenada x do ponto entre 0 e tamanho da tela openGL
 
  ponto.y = rand() & 0x01FF; //gera coordenada y do ponto entre 0 e tamanho da tela openGL

  //Gera texto do titulo com o proximo ponto a ser plotado
  sprintf(title, "Proximo ponto: %d x %d  Cor: %x%x%x", ponto.x, ponto.y, ponto.cor.R, ponto.cor.G, ponto.cor.B);

  glutSetWindowTitle(title);  // Apresenta o texto na barra de titulo da janela
 
  return ponto;
}

slinha GeraLinha(void){
  char title[50];
  slinha linha;

  linha.p1 = GeraPonto(); //gera o primeiro ponto da linha
  linha.p2 = GeraPonto(); //gera o segundo ponto da linha
 
  //Gera texto do titulo com o proximo ponto a ser plotado
  sprintf(title, "Proxima linha: %d x %d  a  %d x %d", linha.p1.x, linha.p1.y, linha.p2.x, linha.p2.y);

  glutSetWindowTitle(title);  // Apresenta o texto na barra de titulo da janela
 
  return linha;
}

striang GeraTriang(void){
  char title[50];
  striang triang;

  triang.p1 = GeraPonto(); //gera o primeiro ponto do triang
  triang.p2 = GeraPonto(); //gera o segundo ponto
  triang.p3 = GeraPonto(); //gera o terceiro ponto
 
  //Gera texto do titulo com o proximo ponto a ser plotado
  sprintf(title, "Proximo triangulo: %d x %d, %d x %d,  %d x %d", triang.p1.x, triang.p1.y, triang.p2.x, triang.p2.y, triang.p3.x, triang.p3.y);

  glutSetWindowTitle(title);  // Apresenta o texto na barra de titulo da janela
 
  return triang;
}

void PutPixel(sponto ponto){

    FBptr[(ponto.y * IMAGE_WIDTH * 4) + 4 * ponto.x +  0]  = ponto.cor.R;
    FBptr[(ponto.y * IMAGE_WIDTH * 4) + 4 * ponto.x +  1]  = ponto.cor.G;
    FBptr[(ponto.y * IMAGE_WIDTH * 4) + 4 * ponto.x +  2]  = ponto.cor.B;
    FBptr[(ponto.y * IMAGE_WIDTH * 4) + 4 * ponto.x +  3]  = ponto.cor.A;
}
 
void DrawLine(slinha linha)
{
  sponto pAux;
  short inc_n, inc_ne, inc_e, inc_se, inc_s, inc_y, d, dx, dy,  quadrante;
  float m, inc_r, inc_g, inc_b, R, G, B;

  //Se o x do ponto inicial for menor que o x do ponto final, inverte os pontos
  //e reduz os casos para apenas 2 quadrantes
  if (linha.p1.x > linha.p2.x)
  {
      pAux = linha.p2;
      linha.p2 = linha.p1;
      linha.p1 = pAux;
  }       
  dx = linha.p2.x - linha.p1.x;
  dy = linha.p2.y - linha.p1.y;

  m = dy / (dx + 0.0001); // 0.0001 evita divisão por 0
 
  if(m < -1)
    quadrante = 7;
  else if (-1 <= m && m < 0)
    quadrante = 8;
  else if ( 0 <= m && m <= 1)
    quadrante = 1;
  else
      quadrante = 2;
     
  if(dy > 0)
    inc_y = 1;
  else
  {  inc_y = -1;
    dy = -dy;
  }
 

  d = 2 * dy - dx;
 
  inc_n = 2 * (-dx);
  inc_ne = 2 * (dy - dx);
  inc_e = 2 * dy;
   
  // incremento de cor
  inc_r = (float)(linha.p2.cor.R - linha.p1.cor.R)/dx;
  inc_g = (float)(linha.p2.cor.G - linha.p1.cor.G)/dx;
  inc_b = (float)(linha.p2.cor.B - linha.p1.cor.B)/dx;

  // plota o primeiro ponto
  pAux.x = linha.p1.x;
  pAux.y = linha.p1.y;
  R = linha.p1.cor.R;
  G = linha.p1.cor.G;
  B = linha.p1.cor.B;
 
  PutPixel(pAux);

    short cont, lim;
    while( pAux.x <= linha.p2.x)
    {
      if (d <= 0)
      {
    switch (quadrante)
    {
      case 1 :
        d += inc_e;
        pAux.x ++;
        R += inc_r;
        G += inc_g;
        B += inc_b;
        break;
      case 2 :
        d += inc_ne;
        pAux.x ++;
        pAux.y += inc_y;
        R += inc_r;
        G += inc_g;
        B += inc_b;
        break;
      case 7 :
        d -= inc_n;
        pAux.y += inc_y;
        break;
      case 8 :
        d -= inc_ne;
        pAux.x ++;
        pAux.y += inc_y;
        R += inc_r;
        G += inc_g;
        B += inc_b;
        break;
    }
      }
      else
      {
    switch (quadrante)
    {
      case 1 :
        d += inc_ne;
        pAux.x ++;
        pAux.y += inc_y;
        R += inc_r;
        G += inc_g;
        B += inc_b;
        break;
      case 2 :
        d += inc_n;
        pAux.y += inc_y;
        break;
      case 7 :
        d -= inc_ne;
        pAux.x ++;
        pAux.y += inc_y;
        R += inc_r;
        G += inc_g;
        B += inc_b;
        break;
      case 8 :
        d -= inc_e;
        pAux.x ++;
        R += inc_r;
        G += inc_g;
        B += inc_b;
        break;
    }
      }
      pAux.cor.R = R;
      pAux.cor.G = G;
      pAux.cor.B = B;
      PutPixel(pAux);
    }
   
}

void DrawTriangle(striang triang)
{
  slinha linha;
 
  linha.p1 = triang.p1;
  linha.p2 = triang.p2;
  DrawLine(linha);
 
  linha.p1 = triang.p2;
  linha.p2 = triang.p3;
  DrawLine(linha);
 
  linha.p1 = triang.p1;
  linha.p2 = triang.p3;
  DrawLine(linha);
}

void FillTriang(striang triang)
{
  sponto pFix, pAux;
  slinha linha, fill;
  short inc_n, inc_ne, inc_e, inc_se, inc_s, inc_y, d, dx, dy,  quadrante;
  float m, inc_r, inc_g, inc_b, R, G, B;
 
  linha.p1 = triang.p1;
  linha.p2 = triang.p2;
  pFix = triang.p3;
 
  //Se o x do ponto inicial for menor que o x do ponto final, inverte os pontos
  //e reduz os casos para apenas 2 quadrantes
  if (linha.p1.x > linha.p2.x)
  {
      pAux = linha.p2;
      linha.p2 = linha.p1;
      linha.p1 = pAux;
  }       
  dx = linha.p2.x - linha.p1.x;
  dy = linha.p2.y - linha.p1.y;

  m = dy / (dx + 0.0001); // 0.0001 evita divisão por 0
 
  if(m < -1)
    quadrante = 7;
  else if (-1 <= m && m < 0)
    quadrante = 8;
  else if ( 0 <= m && m <= 1)
    quadrante = 1;
  else
      quadrante = 2;
     
  if(dy > 0)
    inc_y = 1;
  else
  {  inc_y = -1;
    dy = -dy;
  }
 

  d = 2 * dy - dx;
 
  inc_n = 2 * (-dx);
  inc_ne = 2 * (dy - dx);
  inc_e = 2 * dy;
   
  // incremento de cor
  inc_r = (float)(linha.p2.cor.R - linha.p1.cor.R)/dx;
  inc_g = (float)(linha.p2.cor.G - linha.p1.cor.G)/dx;
  inc_b = (float)(linha.p2.cor.B - linha.p1.cor.B)/dx;

  // plota o primeiro ponto
  pAux.x = linha.p1.x;
  pAux.y = linha.p1.y;
  R = linha.p1.cor.R;
  G = linha.p1.cor.G;
  B = linha.p1.cor.B;
 
//  PutPixel(pAux);

    short cont, lim;
    while( pAux.x <= linha.p2.x)
    {
      if (d <= 0)
      {
    switch (quadrante)
    {
      case 1 :
        d += inc_e;
        pAux.x ++;
        R += inc_r;
        G += inc_g;
        B += inc_b;
        break;
      case 2 :
        d += inc_ne;
        pAux.x ++;
        pAux.y += inc_y;
        R += inc_r;
        G += inc_g;
        B += inc_b;
        break;
      case 7 :
        d -= inc_n;
        pAux.y += inc_y;
        break;
      case 8 :
        d -= inc_ne;
        pAux.x ++;
        pAux.y += inc_y;
        R += inc_r;
        G += inc_g;
        B += inc_b;
        break;
    }
      }
      else
      {
    switch (quadrante)
    {
      case 1 :
        d += inc_ne;
        pAux.x ++;
        pAux.y += inc_y;
        R += inc_r;
        G += inc_g;
        B += inc_b;
        break;
      case 2 :
        d += inc_n;
        pAux.y += inc_y;
        break;
      case 7 :
        d -= inc_ne;
        pAux.x ++;
        pAux.y += inc_y;
        R += inc_r;
        G += inc_g;
        B += inc_b;
        break;
      case 8 :
        d -= inc_e;
        pAux.x ++;
        R += inc_r;
        G += inc_g;
        B += inc_b;
        break;
    }
      }
      pAux.cor.R = R;
      pAux.cor.G = G;
      pAux.cor.B = B;

      fill.p1 = pFix;
      fill.p2 = pAux;
     
      DrawLine(fill);
    }
}

#endif // _MYGL_H_

Nenhum comentário:

Postar um comentário