
/* 
O programa mostra um sistema de coordenadas (setas) para auxiliar na 
criação das imagens e também algumas funções de teclado: 

x e X : gira o desenho em torno do eixo x 
y e Y : gira o desenho em torno do eixo y 
z e Z : gira o desenho em torno do eixo z 
(mas para girar o desenho é melhor usar as setas) 
e ou E (toggle) : apresenta ou não as setas 
p : Aumenta a profundidade quando em perspectiva 
P : Diminui a profundidade quando em perspectiva 
o ou O (toggle) : alterna entre perspectiva e projeção ortográfica 
1 : mostra as setas somente para o semi-plano positivo. 
2 : mostra as setas para ambos os semi-planos.

setas do teclado (comportamento default) 
esquerda e direita : giram a imagem para a esquerda e para a direita 
p/ cima e p/ baixo: giram a imagem para cima e para baixo 

Ao pressionar m ou M (toggle) : o comportamento das setas mudam para: 
esquerda e direita: deslocam a imagem para esquerda e para a direita. 
p/ cima e p/ baixo: deslocam a imagem para cima e para baixo. 

também posso dar uma ajuda em como fazer o carro deslocar 
sobre a pista usando o glut.

*/


#include <windows.h>

#pragma hdrstop

#include <dos.h>
#include <stdio.h>
#include <math.h>

#include <gl/glut.h>
#include <gl/glaux.h>    // Definição do tipo AUX_RGBImageRec
                         // e função auxDIBImageLoad()


// Definições de Macros
#define drawOneLine(x1,y1,x2,y2)  glBegin(GL_LINES);  \
   glVertex2f ((x1),(y1)); glVertex2f ((x2),(y2)); glEnd(); glFlush();


void inicializacao(void);
void teclado(unsigned char tecla, int x, int y);
void desenhar(void);
void redesenhar(int w, int h);
void setas(int tecla, int x, int y);
void eixos(float tamanho, int lados);
void pista(void);
void carro(int num);
void obstaculos(void);
void cube(float tamanho);
void grama(void);
void partes(float eixotranslacao1X, float eixotranslacao1Y, float angulo,
            float eixotranslacao2X, float eixotranslacao2Y,
            float escalaX, float escalaY, float escalaZ, float cubo);

// Funções para textura
AUX_RGBImageRec *LoadBMP(char *Filename);
void LoadGLTextures(void);


float c_x=0, c_y=0, c_z=-6;
float ang_x=0, ang_y=0, ang_z=0;
float matriz_modelamento[16];
float W=1,H=1;
GLUquadricObj *qobj;
GLint textures[7];

// flags de controle
int deslocamento=0;             // Se 1 as setas controlam o deslocamento
int duplo=0;                    // Se 1 os mostradores dos eixos serão duplos
int perspectiva=1;              // 1 para perspectiva
int apresentar_eixos=1;         // 1 para eixos visíveis e 0 para nao mostrar os eixos
int wireframe=0;                // 1 para mostrar a modelagem em wireframe e 1 para cheia
int textura=0;                  // 1- textura habilitada, 0- textura desabilitada


int main(int argc, char* argv[])
{
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
        glutInitWindowPosition(100,150);
        glutInitWindowSize(500,500);
        glutCreateWindow("Projeto Corrida");
        inicializacao();
        glutDisplayFunc(desenhar);
        glutKeyboardFunc(teclado);
        glutReshapeFunc(redesenhar);
        glutIdleFunc(desenhar);
        glutSpecialFunc(setas);
        glutMainLoop();

        return 0;
}

void inicializacao(void)
{
        GLfloat light0_pos[] = {100.0, 100.0, 100.0, 1};
        GLfloat light0_color[] = {1.0, 1.0, 1.0, 1.0};
        GLfloat ambient_light[] = {1.0, 1.0, 1.0, 1.0};

        // Setando um pouco de luz
        glEnable(GL_COLOR_MATERIAL);
        glLightfv(GL_LIGHT0, GL_POSITION, light0_pos);
        glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_color);
        glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient_light);

        glEnable(GL_LIGHT0);
        glEnable(GL_LIGHTING);

        glEnable(GL_DEPTH_TEST);
        glShadeModel(GL_SMOOTH);

        glClearColor(0,0,0,0.5);
        glEnable(GL_DEPTH_TEST);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glTranslatef(c_x,c_y,c_z);

        qobj = gluNewQuadric();
        
        // Carrega as texturas
        LoadGLTextures();
}

void teclado(unsigned char tecla, int x, int y)
{
        switch(tecla)
        {
                case 'x' : glRotatef(-5,1,0,0); break;
                case 'X' : glRotatef(5,1,0,0);  break;
                case 'y' : glRotatef(-5,0,1,0); break;
                case 'Y' : glRotatef(5,0,1,0);  break;
                case 'z' : glRotatef(-5,0,0,1); break;
                case 'Z' : glRotatef(5,0,0,1);  break;

                case 'w' :
                case 'W' :
                        wireframe = !wireframe;
                        if(wireframe)
                               gluQuadricDrawStyle(qobj, GLU_LINE);
                        else
                                gluQuadricDrawStyle(qobj, GLU_FILL);

                break;

                case 'm' :
                case 'M' : deslocamento = !deslocamento; break;

                case 'e' :
                case 'E' : apresentar_eixos = !apresentar_eixos; break;

                case 'i' :
                case 'I' :
                        if(glIsEnabled(GL_LIGHTING))
                                glDisable(GL_LIGHTING);
                        else
                                glEnable(GL_LIGHTING);
                break;


                case 't' :
                case 'T' :
                        textura = !textura;
                           if(textura)
                           {
                                gluQuadricTexture(qobj, GL_TRUE);
                                glEnable(GL_TEXTURE_2D);
                           }
                           else
                           {
                                gluQuadricTexture(qobj, GL_FALSE);
                                glDisable(GL_TEXTURE_2D);
                           }

                break;

                case 'p' :
                        glGetFloatv(GL_MODELVIEW_MATRIX,matriz_modelamento);
                        glMatrixMode(GL_MODELVIEW);
                        glLoadIdentity();
                        c_z -= 0.1;
                        glTranslatef(0,0,-0.1);
                        glMultMatrixf(matriz_modelamento);
                break;
                case 'P' :
                        glGetFloatv(GL_MODELVIEW_MATRIX,matriz_modelamento);
                        glMatrixMode(GL_MODELVIEW);
                        glLoadIdentity();
                        c_z += 0.1;
                        glTranslatef(0,0,0.1);
                        glMultMatrixf(matriz_modelamento);
                break;


                case 'o' :
                case 'O' :
                        glMatrixMode(GL_PROJECTION);
                        glLoadIdentity();
                        if(perspectiva)
                        {
                                glOrtho(-3,3,-3,3,-10,10);
                                perspectiva = 0;
                        }
                        else
                        {
                                gluPerspective(45,W/H,0.1,50);
                                perspectiva = 1;
                        }
                        glMatrixMode(GL_MODELVIEW);
                break;

                case '0' :
                        {
                                GLfloat ambient_light[] = {0.2, 0.2, 0.2, 1.0};

                                glDisable(GL_LIGHT0);
                                glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient_light);
                        }
                break;


                // Controle do dia
                case '1' :
                        {
                                GLfloat light0_color[] = {1.0, 1.0, 1.0, 1.0};
                                GLfloat ambient_light[] = {1.0, 1.0, 1.0, 1.0};

                                glEnable(GL_LIGHT0);
                                glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_color);
                                glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient_light);
                        }
                break;

                case '2' :
                        {
                                GLfloat light0_color[] = {0.25, 0.25, 0.25, 1.0};
                                GLfloat ambient_light[] = {1.0, 1.0, 1.0, 1.0};

                                glEnable(GL_LIGHT0);
                                glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_color);
                                glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient_light);
                        }
                break;


                case '3' :
                        {
                                GLfloat light0_color[] = {0.25, 0.25, 0.25, 1.0};
                                GLfloat ambient_light[] = {0.5, 0.5, 0.5, 1.0};

                                glEnable(GL_LIGHT0);
                                glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_color);
                                glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient_light);
                        }
                break;

                case '4' :
                        {
                                GLfloat light0_color[] = {0.25, 0.1, 0.1, 1.0};
                                GLfloat ambient_light[] = {0.5, 0.5, 0.5, 1.0};

                                glEnable(GL_LIGHT0);
                                glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_color);
                                glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient_light);
                        }
                break;

                case '5' :
                        {
                                GLfloat light0_color[] = {0.2, 0.01, 0.01, 1.0};
                                GLfloat ambient_light[] = {0.5, 0.5, 0.5, 1.0};

                                glEnable(GL_LIGHT0);
                                glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_color);
                                glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient_light);
                        }
                break;

                case '6' :
                        {
                                GLfloat ambient_light[] = {0.5, 0.5, 0.5, 1.0};

                                glDisable(GL_LIGHT0);
                                glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient_light);
                        }
                break;

                case '7' :
                        {
                                GLfloat ambient_light[] = {0.3, 0.3, 0.3, 1.0};

                                glDisable(GL_LIGHT0);
                                glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient_light);
                        }
                break;

                case '8' :
                        {
                                GLfloat ambient_light[] = {0.2, 0.2, 0.2, 1.0};

                                glDisable(GL_LIGHT0);
                                glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient_light);
                        }
                break;


                default : exit(0);
        }
}

void desenhar(void)
{
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        if(textura) glEnable(GL_TEXTURE_2D); else glDisable(GL_TEXTURE_2D);
        
        // Verificar se os eixos coordenados serão apresentados
        if(apresentar_eixos) eixos(0.5,duplo);

        // Verificar se o desenho será cheio ou em Wireframe
        if(wireframe)
                glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
        else
                glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);

        glPushMatrix();
                //glScalef(0.01,0.02,0.01);
                //glTranslatef(-300,-150,0);
                pista();
        glPopMatrix();

        glPushMatrix();
                grama();
        glPopMatrix();

        glPushMatrix();
                obstaculos();
        glPopMatrix();

        glPushMatrix();
                carro(1);
        glPopMatrix();


/*        glPushMatrix();
                carro3();
        glPopMatrix();
  */
        glFlush();
        glutSwapBuffers();
}

void redesenhar(int w, int h)
{
        glViewport(0,0,w,h);
        if(h==0) h=1;
        W=w;
        H=h;
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        if(perspectiva)
                gluPerspective(45,w/h,0.1,50);
        else
                glOrtho(-3,3,-3,3,-10,10);
        glMatrixMode(GL_MODELVIEW);
}

void setas(int seta, int x, int y)
{
        glGetFloatv(GL_MODELVIEW_MATRIX,matriz_modelamento);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        if(!deslocamento) glTranslatef(c_x,c_y,c_z);

        switch(seta)
        {
                case GLUT_KEY_RIGHT :
                        if(deslocamento)
                        {
                                glTranslatef(0.1,0,0);
                                c_x += 0.1;
                        }
                        else
                                glRotatef(5,0,1,0);
                break;

                case GLUT_KEY_LEFT :
                        if(deslocamento)
                        {
                                glTranslatef(-0.1,0,0);
                                c_x -= 0.1;
                        }
                        else
                                glRotatef(-5,0,1,0);
                break;

                case GLUT_KEY_UP :
                        if(deslocamento)
                        {
                                glTranslatef(0,0.1,0);
                                c_y += 0.1;
                        }
                        else
                                glRotatef(-5,1,0,0);
                break;

                case GLUT_KEY_DOWN :
                        if(deslocamento)
                        {
                                glTranslatef(0,-0.1,0);
                                c_y -= 0.1;
                        }
                        else
                                glRotatef(5,1,0,0);
                break;

                default:
                        exit(0);
        }

        if(!deslocamento) glTranslatef(-c_x,-c_y,-c_z);
        glMultMatrixf(matriz_modelamento);

}

void eixos(float tamanho, int lados)
{
        // Eixo X
        glColor3f(1,0,0);
        glBegin(GL_LINES);
                if(lados)
                        glVertex3f(-tamanho,0,0);
                else
                        glVertex3f(0,0,0);
                glVertex3f( tamanho,0,0);
        glEnd();
        // Setas do eixo X
        glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
        glBegin(GL_TRIANGLES);
                glVertex3f(tamanho,0,0);
                glVertex3f(tamanho-0.2,0.05,0);
                glVertex3f(tamanho-0.2,-0.05,0);
                glVertex3f(tamanho,0,0);
                glVertex3f(tamanho-0.2,0,0.05);
                glVertex3f(tamanho-0.2,0,-0.05);
        glEnd();

        // Eixo Y
        glColor3f(0,1,0);
        glBegin(GL_LINES);
                if(lados)
                        glVertex3f(0,-tamanho,0);
                else
                        glVertex3f(0,0,0);
                glVertex3f(0, tamanho,0);
        glEnd();
        // Setas do eixo Y
        glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
        glBegin(GL_TRIANGLES);
                glVertex3f(0,tamanho,0);
                glVertex3f(0.05,tamanho-0.2,0);
                glVertex3f(-0.05,tamanho-0.2,0);
                glVertex3f(0,tamanho,0);
                glVertex3f(0,tamanho-0.2,0.05);
                glVertex3f(0,tamanho-0.2,-0.05);
        glEnd();

        // Eixo Z
        glColor3f(0,0,1);
        glBegin(GL_LINES);
                if(lados)
                        glVertex3f(0,0,-tamanho);
                else
                        glVertex3f(0,0,0);
                glVertex3f(0,0, tamanho);
        glEnd();
        // Setas do eixo Z
        glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
        glBegin(GL_TRIANGLES);
                glVertex3f(0,0,tamanho);
                glVertex3f(0.05,0,tamanho-0.2);
                glVertex3f(-0.05,0,tamanho-0.2);
                glVertex3f(0,0,tamanho);
                glVertex3f(0,0.05,tamanho-0.2);
                glVertex3f(0,-0.05,tamanho-0.2);
        glEnd();

        glFlush();
}


// Desenha o carro
void carro(int num)
{
   /* Construcao do Retangulo maior que eh a base do carro */
   if(num)
   {
        glColor3f(0.7,0,0);
        //glColor3f(1,1,1);
        glBindTexture(GL_TEXTURE_2D,textures[4]);
   }
   else
   {
        glColor3f(0,0.5,0.5);
        glBindTexture(GL_TEXTURE_2D,textures[4]);
   }
   glPushMatrix();
          glScalef(1,1,0.7);
          glTranslatef(0,0,0.45);
          partes(-1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.4, 1.0, 0.65);
   glPopMatrix();

   /* Construcao do cockpit que eh o retangulo
      menor dentro da base do carro
   */
   glColor3f(1,1,1);
   glPushMatrix();
          glTranslatef(0,0,0.300);
          partes(1.0, 0.0, 180.0, 1.0, 0.0, 1.0, 0.4, 1.0, 0.25);
   glPopMatrix();

   /* Construcao das Rodas */
   glColor3f(0.5,0.5,0.5);
   glBindTexture(GL_TEXTURE_2D,textures[6]);

   /* Roda Inferior Esquerda  */
   glPushMatrix();
          glTranslatef(0,0,0.05);
          partes(1.0, 1.0, 180.0, 1.2, 1.17, 1.5, 0.75, 1.0, 0.10);
   glPopMatrix();

   /* Roda Inferior Direita */
   glPushMatrix();
          glTranslatef(0,0,0.05);
          partes(1.0, 1.0, 180.0, 0.8, 1.17, 1.5, 0.75, 1.0, 0.10);
   glPopMatrix();

   /* Roda Superior  Esquerda  */
   glPushMatrix();
          glTranslatef(0,0,0.05);
          partes(1.0, 1.5, 180.0, 1.2, 1.34, 1.5, 0.75, 1.0, 0.10);
   glPopMatrix();

      /* Roda Superior Direita   */
   glPushMatrix();
          glTranslatef(0,0,0.05);
          partes(1.0, 1.5, 180.0, 0.8, 1.34, 1.5, 0.75, 1.0, 0.10);
   glPopMatrix();

   glFlush();
}

// Desenha os obstaculos 
void obstaculos(void)
{
   //qobj = gluNewQuadric();
   //gluQuadricNormals(qobj, GLU_NONE);
   gluQuadricNormals(qobj, GLU_SMOOTH);        // Modelo de iluminação de Gouraud
   if(textura)
   {
        gluQuadricTexture(qobj, GL_TRUE);      // Habilita textura
        glEnable(GL_TEXTURE_2D);
   }
   else
   {
        gluQuadricTexture(qobj, GL_FALSE);
        glDisable(GL_TEXTURE_2D);
   }

   /* Construcao de um carro obstaculo */
   glBindTexture(GL_TEXTURE_2D,textures[5]);
   glPushMatrix();
        glTranslatef(1.5,0,0);
        carro(0);
   glPopMatrix();

   glColor3f(1,1,0.5);
   glBindTexture(GL_TEXTURE_2D,textures[2]);
   glPushMatrix();
          glTranslatef (-1.0, -1.0, 0.15);
          gluSphere(qobj, 0.15, 15, 5);
   glPopMatrix();

   glColor3f(0.5,0.5,0.5);
   glBindTexture(GL_TEXTURE_2D,textures[3]);
   glPushMatrix();
          glTranslatef (1.5, 1.0, 0.0);
         gluCylinder(qobj, 0.1, 0.1, 0.5, 10, 5);
   glPopMatrix();

   glFlush();
}

// Desenha as partes do carro

void partes(float eixotranslacao1X, float eixotranslacao1Y, float angulo,
            float eixotranslacao2X, float eixotranslacao2Y,
            float escalaX, float escalaY, float escalaZ, float cubo)
{
   glTranslatef (eixotranslacao1X, eixotranslacao1Y, 0.0);
   glRotatef (angulo, 0.0, 0.0, 1.0);
   glTranslatef (eixotranslacao2X, eixotranslacao2Y, 0.0);
   glPushMatrix();
   glScalef (escalaX, escalaY, escalaZ);
   cube(cubo);
   glPopMatrix();
}

// Desenha um cubo em torno da origem
void cube(float tamanho)
{
        float t = tamanho/2;

        glBegin ( GL_QUADS );
                // Face Frontal
                glNormal3f(0,0,1);
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-t, -t,  t);
		glTexCoord2f(1.0f, 0.0f); glVertex3f( t, -t,  t);
		glTexCoord2f(1.0f, 1.0f); glVertex3f( t,  t,  t);
		glTexCoord2f(0.0f, 1.0f); glVertex3f(-t,  t,  t);
		// Face Traseira
                glNormal3f(0,0,-1);
		glTexCoord2f(1.0f, 0.0f); glVertex3f(-t, -t, -t);
		glTexCoord2f(1.0f, 1.0f); glVertex3f(-t,  t, -t);
		glTexCoord2f(0.0f, 1.0f); glVertex3f( t,  t, -t);
		glTexCoord2f(0.0f, 0.0f); glVertex3f( t, -t, -t);
		// Face Superior
                glNormal3f(0,1,0);
		glTexCoord2f(0.0f, 1.0f); glVertex3f(-t,  t, -t);
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-t,  t,  t);
		glTexCoord2f(1.0f, 0.0f); glVertex3f( t,  t,  t);
		glTexCoord2f(1.0f, 1.0f); glVertex3f( t,  t, -t);
		// Face Inferior
                glNormal3f(0,-1,0);
		glTexCoord2f(1.0f, 1.0f); glVertex3f(-t, -t, -t);
		glTexCoord2f(0.0f, 1.0f); glVertex3f( t, -t, -t);
		glTexCoord2f(0.0f, 0.0f); glVertex3f( t, -t,  t);
		glTexCoord2f(1.0f, 0.0f); glVertex3f(-t, -t,  t);
		// Face Direita
                glNormal3f(1,0,0);
		glTexCoord2f(1.0f, 0.0f); glVertex3f( t, -t, -t);
		glTexCoord2f(1.0f, 1.0f); glVertex3f( t,  t, -t);
		glTexCoord2f(0.0f, 1.0f); glVertex3f( t,  t,  t);
		glTexCoord2f(0.0f, 0.0f); glVertex3f( t, -t,  t);
		// Face Esquerda
                glNormal3f(-1,0,0);
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-t, -t, -t);
		glTexCoord2f(1.0f, 0.0f); glVertex3f(-t, -t,  t);
		glTexCoord2f(1.0f, 1.0f); glVertex3f(-t,  t,  t);
		glTexCoord2f(0.0f, 1.0f); glVertex3f(-t,  t, -t);
	glEnd();
        glFlush();
}

// Desenha a pista
void pista(void)
{
        float numeroRetangulos=4;
        float x=-2.5, inc_x;

        inc_x = 5/numeroRetangulos;

        glColor3f(0.4, 0.5, 0.4);
        if(textura) glEnable(GL_TEXTURE_2D); else glDisable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D,textures[0]);

        for(x=-2.5; x<2.5; x+=inc_x)
        {
        glBegin(GL_QUADS);
                glNormal3f(0,0,1);
                glTexCoord2f(0,0); glVertex3f(x,-1.5,0.0);
                glTexCoord2f(1,0); glVertex3f(x+inc_x,-1.5,0.0);
                glTexCoord2f(1,1); glVertex3f(x+inc_x,1.5,0.0);
                glTexCoord2f(0,1); glVertex3f(x,1.5,0.0);

        glEnd();
        }

        glDisable(GL_TEXTURE_2D);
        glColor3f(0.9,0.9,0.9);
        for(x=-2.5; x<2.5; x+=inc_x)
        {
        glBegin(GL_QUADS);
                glNormal3f(0,0,1);
                glTexCoord2f(0,0); glVertex3f(x,1.3,0.01);
                glTexCoord2f(1,0); glVertex3f(x+inc_x,1.3,0.01);
                glTexCoord2f(1,1); glVertex3f(x+inc_x,1.4,0.01);
                glTexCoord2f(0,1); glVertex3f(x,1.4,0.01);

        glEnd();
        }

        for(x=-2.5; x<2.5; x+=inc_x)
        {
        glBegin(GL_QUADS);
                glNormal3f(0,0,1);
                glTexCoord2f(0,0); glVertex3f(x,-1.4,0.01);
                glTexCoord2f(1,0); glVertex3f(x+inc_x,-1.4,0.01);
                glTexCoord2f(1,1); glVertex3f(x+inc_x,-1.3,0.01);
                glTexCoord2f(0,1); glVertex3f(x,-1.3,0.01);

        glEnd();
        }

        glColor3f(0.8,0.8,0);
        for(x=-2.5; x<2.5; x+=1.5*inc_x)
        {
        glBegin(GL_QUADS);
                glNormal3f(0,0,1);
                glTexCoord2f(0,0); glVertex3f(x,-0.05,0.01);
                glTexCoord2f(1,0); glVertex3f(x+inc_x,-0.05,0.01);
                glTexCoord2f(1,1); glVertex3f(x+inc_x,0.05,0.01);
                glTexCoord2f(0,1); glVertex3f(x,0.05,0.01);

        glEnd();
        }


        if(textura) glEnable(GL_TEXTURE_2D);


        glDisable(GL_TEXTURE_2D);
}

void grama(void)
{
        float numeroRetangulos=4;
        float x=-2.5, inc_x;

        inc_x = 5/numeroRetangulos;

        glColor3f(0,1,0.5);
        if(textura) glEnable(GL_TEXTURE_2D); else glDisable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D,textures[1]);

        for(x=-2.5; x<2.5; x+=inc_x)
        {
        glBegin(GL_QUADS);
                glNormal3f(0,0,1);
                glTexCoord2f(0,0); glVertex3f(x,1.5,0.0);
                glTexCoord2f(1,0); glVertex3f(x+inc_x,1.5,0.0);
                glTexCoord2f(1,1); glVertex3f(x+inc_x,2.5,0.0);
                glTexCoord2f(0,1); glVertex3f(x,2.5,0.0);

                glNormal3f(0,0,1);
                glTexCoord2f(0,0); glVertex3f(x,-2.5,0.0);
                glTexCoord2f(1,0); glVertex3f(x+inc_x,-2.5,0.0);
                glTexCoord2f(1,1); glVertex3f(x+inc_x,-1.5,0.0);
                glTexCoord2f(0,1); glVertex3f(x,-1.5,0.0);

        glEnd();
        }
        glDisable(GL_TEXTURE_2D);
}

/************************/
/* Funcoes para Textura */
/************************/

AUX_RGBImageRec *LoadBMP(char *Filename)                // Carrega uma imagem BITMAP
{
	FILE *File = NULL;                              // Handle de arquivo

	if (!Filename)		                        // Certifica sobre o nome do arquivo
	{
		return NULL;	                        // Retorna NULL se não tiver o nome do arquivo
	}

	File = fopen(Filename,"r");	                // Checa para ver se o arquivo existe

	if (File)			                // O arquivo existe?
	{
		fclose(File);		                // Fecha o handle
		return auxDIBImageLoad(Filename);       // Carrega o arquivo e retorna um ponteiro
	}

	return NULL;                                    // Retorna NULL no caso de falha
}


void LoadGLTextures(void)                                // Carrega BITMAPS e converte para texturas
{
        int i;
	AUX_RGBImageRec *TextureImage[7];                // Cria espaço para as texturas

        for(i=0;i<7;i++) TextureImage[i]=NULL;           // Zera os ponteiros

        glGenTextures(7, &textures[0]);		         // Cria a textura

         // Carrega os bitmaps
	if (TextureImage[0]=LoadBMP("Data/asfalto.bmp"))
	{
		glBindTexture(GL_TEXTURE_2D, textures[0]);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	}

        if (TextureImage[1]=LoadBMP("Data/grama.bmp"))
	{
		glBindTexture(GL_TEXTURE_2D, textures[1]);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[1]->sizeX, TextureImage[1]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[1]->data);
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	}

        if (TextureImage[2]=LoadBMP("Data/madeira.bmp"))
	{
		glBindTexture(GL_TEXTURE_2D, textures[2]);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[2]->sizeX, TextureImage[2]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[2]->data);
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	}

        if (TextureImage[3]=LoadBMP("Data/metal.bmp"))
	{
		glBindTexture(GL_TEXTURE_2D, textures[3]);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[3]->sizeX, TextureImage[3]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[3]->data);
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	}

        if (TextureImage[4]=LoadBMP("Data/metal1.bmp"))
	{
		glBindTexture(GL_TEXTURE_2D, textures[4]);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[4]->sizeX, TextureImage[4]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[4]->data);
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	}

        if (TextureImage[5]=LoadBMP("Data/metal2.bmp"))
	{
		glBindTexture(GL_TEXTURE_2D, textures[5]);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[5]->sizeX, TextureImage[5]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[5]->data);
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	}

        if (TextureImage[6]=LoadBMP("Data/borracha.bmp"))
	{
		glBindTexture(GL_TEXTURE_2D, textures[6]);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[6]->sizeX, TextureImage[6]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[6]->data);
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	}

        for(i=0;i<7;i++)
        {
	        if (TextureImage[i])			        // Se a textura existe
	        {
		        if (TextureImage[i]->data)	        // Se a imagem de textura existe
		        {
			        free(TextureImage[i]->data);	// Libera memória usada pela imagem de textura
	        	}

		        free(TextureImage[i]);			// libera a textura
	        }
        }
}

