/*
 *-------------------------------------------------
 *	exemplo2.C
 *
 *	Este exemplo desenha um cubo 3D na tela
 *	A camera pode ser rotacionada ao redor
 *	do eixo especificado pela direcao (1,0,0)
 *	A rotacao eh ativada em passos fixos
 *	iguais a 13 graus, com o usuario
 *	pressionando a tecla r
 *
 *	CG - UNISINOS
 *	Autor: Marcelo Walter
 *	Versao inicial: Fevereiro 28, 2000
 *--------------------------------------------------
 */

/*
 *------------------------------------------------
 * Includes
 *------------------------------------------------
 */
#include <stdlib.h>
#include <stdio.h>
#include <GL/glut.h>

/*
 *------------------------------------------------
 * Prototipos para as funcoes globais
 *------------------------------------------------
 */
static void inic( void );
static void exibeCB( void );
static void tecladoCB( unsigned char tecla, int x, int y );
static void redesenhaCB( int w, int h );
static void setaCamera( void );
static void desenhaCena( void );

/* Definicoes Locais */
#define INC_ROTACAO    13.0    // avança rotacao em 13 graus

/* Variavel Global */
float Rotacao = 0.0;

/*
 *------------------------------------------------
 * Rotina MAIN
 *------------------------------------------------
 */
int main( int argc, char *argv[] )
{
  glutInit( &argc, argv );
  glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH );
  
  inic();
  
  glutMainLoop(); 
  return 1;
}

/*
 *------------------------------------------------
 * Esta funcao inicializa a janela OpenGL,
 * registra as rotinas callback e inicializa
 * as matrizes de transformacao
 *------------------------------------------------
 */
static void inic()
{
	glutCreateWindow( "Exemplo 2 OpenGL/GLUT" ); // Titulo da janela

	/* Registra as rotinas de callback */
	glutDisplayFunc( exibeCB );
	glutKeyboardFunc( tecladoCB );
	glutReshapeFunc( redesenhaCB );

	/* Cor de fundo default */
	glClearColor( 0, 0, 0, 0 );       
    
	/* Habilita remocao de elementos ocultos */
	glEnable( GL_DEPTH_TEST );            

	glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();
  
	glMatrixMode( GL_PROJECTION );
	glLoadIdentity();
}


/*
 *------------------------------------------------------
 * Rotina para tratamento de evento - exibicao de janela
 *------------------------------------------------------
 */
static void exibeCB()
{
	/* Estabelece parametros da camera */
	setaCamera();
	/* Desenha a cena propriamente dita */
	desenhaCena();

	/* Estamos usando double-buffering. Precisamos trocar
	   os buffers */
	glutSwapBuffers();
}


/*
 *------------------------------------------------
 * Rotina para tratamento de evento - Teclado
 * tecla - tecla pressionada pelo usuario
 * x - posicao x do mouse
 * y - posicao y do mouse
 *------------------------------------------------
 */
static void tecladoCB( unsigned char tecla, int x, int y )
{
  switch( tecla ) {
  case 'q':                     /* Encerra o programa */
  case 'Q':
    exit( 0 );
  case 'r':                     /* Rotaciona o objeto */
  case 'R':
    Rotacao += INC_ROTACAO;
    /* Verifica limites no valor da rotacao */
    if( Rotacao >= 360.0 ) Rotacao -= 360.0;
    break;
  default:
	  printf("Opcao nao definida!\n");
    break;
  }
  /* Esta chamada eh muito importante. Sem ela o programa
     nao exibe nada! */
  glutPostRedisplay();
}  

/*
 *------------------------------------------------
 * Rotina para tratamento de evento
 * Alteracao do tamanho da janela
 * w - largura atual da janela
 * h - altura atual da janela
 *------------------------------------------------
 */
static void redesenhaCB( int w, int h )
{
   glViewport( 0, 0, w, h );
}   

/*
 *------------------------------------------------
 * Estabelece o tipo de projecao, posicao e orientacao
 * da camera
 *------------------------------------------------
 */
static void setaCamera( void )
{
  glMatrixMode( GL_PROJECTION );

  glLoadIdentity();
  gluPerspective( 45.0, 1.0, 0.1, 100.0 );
  glTranslatef( 0, 0, -5 );             // Move a posicao default da camera
                                        // longe da origem
}

/*
 *------------------------------------------------
 * Esta rotina desenha a cena assumindo que a posicao
 * da camera foi estabelecida
 *------------------------------------------------
 */
static void desenhaCena( void )
{

	// glClear limpa tambem o buffer de profundidade
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	glColor3f( 1.0, 1.0, 0.0 );          // Desenha na cor amarela
	
	glMatrixMode( GL_MODELVIEW );
	glPushMatrix();
		glRotatef( Rotacao, 1.0, 1.0, 1.0 );
		glutWireCube( 1.0 );                  // desenha cubo com tamanho igual a 1
	glPopMatrix();

	glFlush();
} 
