#ifndef _MYGL_H_
#define _MYGL_H_
//#define RAND_MAX 0xFF
#include "definitions.h"
#include "math.h"
#include "stdio.h"
#include "iostream"
using namespace std;
//*****************************************************************************
// Defina aqui as suas funções gráficas
//*****************************************************************************
//*************************************
struct scor {
short R = 255 , G = 255, B = 255, A = 255;
};
//*************************************
struct sponto{
short x, y;
scor cor;
};
//*************************************
struct slinha{
sponto p1, p2;
};
//*************************************
struct striang{
sponto p1, p2, p3;
};
//*************************************
//*************************************
//*************************************
class cVetor{
private:
public:
float m[4][1] = {{0},{0},{0},{0}};
//cria um vetor4x1.
// chamado sem parametros gera um vetor de zeros
// com 3 parametros gera um vetor homogeneo
//--------------------------------------
cVetor(){
};
//--------------------------------------
cVetor(float x, float y, float z){
m[0][0] = x;
m[0][1] = y;
m[0][2] = z;
m[0][3] = 1;
};
};
//*************************************
class TMatriz{
private:
char tipo; // identificador do tipo de matriz
short lin, col; //define dimensoes da matrix
float m[4][4] = {{0, 0, 0, 0 },{0, 0, 0, 0},{0, 0, 0, 0 },{0, 0, 0, 1}};
public:
//cria uma matriz 4x4. Tipo define se a matriz eh 's', 't', 'z' ou 'i'
// t - translacao
// s - scale
// i - identidade
// z - zeros
//--------------------------------------
TMatriz(float x, float y, float z, char tipo ){
if(tipo == 's'){
m[0][0] = x;
m[1][1] = y;
m[2][2] = z;
}
else if(tipo == 't'){
m[0][0] = 1;
m[1][1] = 1;
m[2][2] = 1;
m[0][3] = x;
m[1][3] = y;
m[2][3] = z;
}
else if(tipo == 'i'){
m[0][0] = 1;
m[1][1] = 1;
m[2][2] = 1;
m[3][3] = 1;
}
else if(tipo == 'z'){
m[3][3] = 0;
}
else{
cout << "Tipo de matriz invalido. Abortando a execucao.";
exit(0);
}
this->tipo = tipo;
};
//--------------------------------------
char getTipo(){
return tipo;
};
//--------------------------------------
TMatriz vezes(TMatriz m2){
// multiplica a matriz atual por outra informada
TMatriz MResultado(0,0,0,'z');
for(short i = 0; i < 4; i++){
for(short j = 0; j < 4; j++){
for(short n = 0; n < 4; n++)
MResultado.m[i][j] = MResultado.m[i][j] + this->m[i][n] * m2.m[n][j];
}
}
return MResultado;
};
//--------------------------------------
cVetor vezes(cVetor m2){
// multiplica a matriz atual por outra informada
cVetor MResultado;
for(short i = 0; i < 4; i++){
for(short n = 0; n < 4; n++)
MResultado.m[i][0] = MResultado.m[i][0] + this->m[i][n] * m2.m[n][0];
}
return MResultado;
};
};
//*************************************
class cponto{
//cria um ponto canonico
private:
float x, y, z;
scor cor;
//--------------------------------------
void valida( void){
// valida x, y , e z e cor
// faz, mas no final os valores são substituidos por algo aleatorio
if(x < -1.0f || x > 1.0f){
cout << "Coordenadas canonicas devem estar entre -1 e 1. \n Ajustado x para 0.\n";
x = 0.0f;
}
if(y < -1.0f || y > 1.0f){
cout << "Coordenadas canonicas devem estar entre -1 e 1. \n Ajustado y para 0.\n";
y = 0.0f;
}
if(z < -1.0f || z > 1.0f){
cout << "Coordenadas canonicas devem estar entre -1 e 1. \n Ajustado z para 0.\n";
z = 0.0f;
}
if(cor.R < 0 || cor.R > 255){
cout << "Valores de cor devem estar entre 0 e 255. \n Ajustando R para 255\n";
cor.R = 255;
}
if(cor.G < 0 || cor.G > 255){
cout << "Valores de cor devem estar entre 0 e 255. \n Ajustando G para 255\n";
cor.G = 255;
}
if(cor.B < 0 || cor.B > 255){
cout << "Valores de cor devem estar entre 0 e 255. \n Ajustando B para 255\n";
cor.B = 255;
}
cor.A = 0;
}
public:
//--------------------------------------
cponto(){
//construtor sem parametros
cout << "Digite as coordenadas e cor do ponto: \n x:";
cin >> x;
cout << " y:";
cin >> y;
cout << " z:";
cin >> z;
cout << " R:";
cin >> cor.R;
cout << " G:";
cin >> cor.G;
cout << " B:";
cin >> cor.B;
cor.A = 255;
valida();
};
//--------------------------------------
cponto(float x, float y){
//construtor com parametros x e y. z recebe 0 e cor será branco
z = 0;
cor.R = 255;
cor.G = 255;
cor.B = 255;
cor.A = 255;
valida();
};
//--------------------------------------
cponto(float x, float y, float z){
//construtor com parametros x e y. z recebe 0 e cor será branco
cor.R = 255;
cor.G = 255;
cor.B = 255;
cor.A = 255;
valida();
};
//--------------------------------------
cponto(float x1, float y1, float z1, short R, short G, short B){
//construtor com todos os parametros de coordenada e cor
cor.R = R;
cor.G = G;
cor.B = B;
cor.A = 255;
this->x = x1;
this->y = y1;
this->z = z1;
valida();
};
//--------------------------------------
void setPoint(float x1, float y1, float z1, short R, short G, short B){
this->x = x1;
this->y = y1;
this->z = z1;
cor.R = R;
cor.G = G;
cor.B = B;
}
//--------------------------------------
sponto getTpoint(){
sponto ponto;
TMatriz mTrans(256, 256, 0, 't'); // matriz de translacao de 0 para 256 para x e y
TMatriz mTemp(0, 0, 0, 'z'); // cria uma matriz auxiliar para armazenamento de resultados
TMatriz mScale(256, 256, 1,'s'); //matriz que amplia a figura nos eixos x e y
TMatriz mFlip(1, -1, 1, 's'); //cria uma matriz de escala que mantem x e inverte y
mTemp = mScale.vezes(mFlip);
mTemp = mTrans.vezes(mTemp);
cVetor cCanon(x,y,z);
cVetor cTela = mTemp.vezes(cCanon);
ponto.x = (int)cTela.m[0][0];
ponto.y = (int)cTela.m[0][1];
ponto.cor.R = cor.R;
ponto.cor.G = cor.G;
ponto.cor.B = cor.B;
return(ponto);
};
};
//*************************************
//*************************************
//*************************************
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;
//resolve o problema de dx = 0
if(dx == 0){
short i, ini, fim;
if(linha.p1.y > linha.p2.y){
ini = linha.p2.y;
fim = linha.p1.y;
}
else{
ini = linha.p1.y;
fim = linha.p2.y;
}
for(i = ini; i <= fim; i++){
pAux.x = linha.p1.x;
pAux.y = i;
pAux.cor.R = linha.p1.cor.R;
pAux.cor.G = linha.p1.cor.G;
pAux.cor.B = linha.p1.cor.B;
PutPixel(pAux);
}
return;
}
dy = linha.p2.y - linha.p1.y;
m = dy / dx; // 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
if(dx != 0){
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);
}
else{
inc_r = 0;
inc_g = 0;
inc_b = 0;
}
// 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);
// cout << quadrante << "\n";
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;
//pAux.x ++;
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;
//pAux.x ++;
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