// ********************************************************************** // PUCRS/Escola PolitŽcnica // COMPUTA‚ĚO GRçFICA // // Programa b‡sico para criar aplicacoes 3D em OpenGL // // Marcio Sarroglia Pinho // pinho@pucrs.br // ********************************************************************** #include #include #include using namespace std; #ifdef WIN32 #include #include #else #include #endif #ifdef __APPLE__ #include #endif #ifdef __linux__ #include #endif #include "Temporizador.h" #include "ListaDeCoresRGB.h" #include "Ponto.h" Temporizador T; double AccumDeltaT=0; GLfloat AspectRatio, angulo=0; // Controle do modo de projecao // 0: Projecao Paralela Ortografica; 1: Projecao Perspectiva // A funcao "PosicUser" utiliza esta variavel. O valor dela eh alterado // pela tecla 'p' int ModoDeProjecao = 1; // Controle do modo de projecao // 0: Wireframe; 1: Faces preenchidas // A funcao "Init" utiliza esta variavel. O valor dela eh alterado // pela tecla 'e' int ModoDeExibicao = 1; double nFrames=0; double TempoTotal=0; Ponto CantoEsquerdo = {-20,-1,-10}; // ********************************************************************** // void init(void) // Inicializa os parametros globais de OpenGL // ********************************************************************** void init(void) { glClearColor(0.0f, 0.0f, 1.0f, 1.0f); // Fundo de tela preto glShadeModel(GL_SMOOTH); //glShadeModel(GL_FLAT); glColorMaterial ( GL_FRONT, GL_AMBIENT_AND_DIFFUSE ); if (ModoDeExibicao) // Faces Preenchidas?? { glEnable(GL_DEPTH_TEST); glEnable (GL_CULL_FACE ); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } else { glEnable(GL_DEPTH_TEST); glEnable (GL_CULL_FACE ); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } glEnable(GL_NORMALIZE); } // ********************************************************************** // // ********************************************************************** void animate() { double dt; dt = T.getDeltaT(); AccumDeltaT += dt; TempoTotal += dt; nFrames++; if (AccumDeltaT > 1.0/30) // fixa a atualizaŤ‹o da tela em 30 { AccumDeltaT = 0; angulo+= 1; glutPostRedisplay(); } if (TempoTotal > 5.0) { cout << "Tempo Acumulado: " << TempoTotal << " segundos. " ; cout << "Nros de Frames sem desenho: " << nFrames << endl; cout << "FPS(sem desenho): " << nFrames/TempoTotal << endl; TempoTotal = 0; nFrames = 0; } } // ********************************************************************** // void DesenhaCubo() // // // ********************************************************************** void DesenhaCubo() { glBegin ( GL_QUADS ); // Front Face glNormal3f(0,0,1); glVertex3f(-1.0f, -1.0f, 1.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Back Face glNormal3f(0,0,-1); glVertex3f(-1.0f, -1.0f, -1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Top Face glNormal3f(0,1,0); glVertex3f(-1.0f, 1.0f, -1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Bottom Face glNormal3f(0,-1,0); glVertex3f(-1.0f, -1.0f, -1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Right face glNormal3f(1,0,0); glVertex3f( 1.0f, -1.0f, -1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Left Face glNormal3f(-1,0,0); glVertex3f(-1.0f, -1.0f, -1.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glEnd(); } void DesenhaParalelepipedo() { glPushMatrix(); glTranslatef(0,0,-1); glScalef(1,1,2); DesenhaCubo(); glPopMatrix(); } // ********************************************************************** // void DesenhaLadrilho(int corBorda, int corDentro) // Desenha uma cŽlula do piso. // Eh possivel definir a cor da borda e do interior do piso // O ladrilho tem largula 1, centro no (0,0,0) e est‡ sobre o plano XZ // ********************************************************************** void DesenhaLadrilho(int corBorda, int corDentro) { defineCor(corDentro);// desenha QUAD preenchido glBegin ( GL_QUADS ); glNormal3f(0,1,0); glVertex3f(-0.5f, 0.0f, -0.5f); glVertex3f(-0.5f, 0.0f, 0.5f); glVertex3f( 0.5f, 0.0f, 0.5f); glVertex3f( 0.5f, 0.0f, -0.5f); glEnd(); defineCor(corBorda); glBegin ( GL_LINE_STRIP ); glNormal3f(0,1,0); glVertex3f(-0.5f, 0.0f, -0.5f); glVertex3f(-0.5f, 0.0f, 0.5f); glVertex3f( 0.5f, 0.0f, 0.5f); glVertex3f( 0.5f, 0.0f, -0.5f); glEnd(); } // ********************************************************************** // // // ********************************************************************** void DesenhaPiso() { srand(100); // usa uma semente fixa para gerar sempre as mesma cores no piso glPushMatrix(); glTranslated(CantoEsquerdo.x, CantoEsquerdo.y, CantoEsquerdo.z); for(int x=-20; x<20;x++) { glPushMatrix(); for(int z=-20; z<20;z++) { DesenhaLadrilho(White, rand()%40); glTranslated(0, 0, 1); } glPopMatrix(); glTranslated(1, 0, 0); } glPopMatrix(); } // ********************************************************************** // void DefineLuz(void) // ********************************************************************** void DefineLuz(void) { // Define cores para um objeto dourado GLfloat LuzAmbiente[] = {0.4, 0.4, 0.4f } ; GLfloat LuzDifusa[] = {0.7, 0.7, 0.7}; GLfloat LuzEspecular[] = {0.9f, 0.9f, 0.9 }; GLfloat PosicaoLuz0[] = {0.0f, 3.0f, 5.0f }; // PosiŤ‹o da Luz GLfloat Especularidade[] = {1.0f, 1.0f, 1.0f}; // **************** Fonte de Luz 0 glEnable ( GL_COLOR_MATERIAL ); // Habilita o uso de iluminaŤ‹o glEnable(GL_LIGHTING); // Ativa o uso da luz ambiente glLightModelfv(GL_LIGHT_MODEL_AMBIENT, LuzAmbiente); // Define os parametros da luz nśmero Zero glLightfv(GL_LIGHT0, GL_AMBIENT, LuzAmbiente); glLightfv(GL_LIGHT0, GL_DIFFUSE, LuzDifusa ); glLightfv(GL_LIGHT0, GL_SPECULAR, LuzEspecular ); glLightfv(GL_LIGHT0, GL_POSITION, PosicaoLuz0 ); glEnable(GL_LIGHT0); // Ativa o "Color Tracking" glEnable(GL_COLOR_MATERIAL); // Define a reflectancia do material glMaterialfv(GL_FRONT,GL_SPECULAR, Especularidade); // Define a concentraŤ‹oo do brilho. // Quanto maior o valor do Segundo parametro, mais // concentrado ser‡ o brilho. (Valores v‡lidos: de 0 a 128) glMateriali(GL_FRONT,GL_SHININESS,51); } // ********************************************************************** // void PosicUser() // ********************************************************************** void PosicUser() { // Define os par‰metros da projeŤ‹o Perspectiva glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Define o volume de visualizaŤ‹o sempre a partir da posicao do // observador if (ModoDeProjecao == 0) glOrtho(-10, 10, -10, 10, 0, 50); // Projecao paralela Orthografica else gluPerspective(90,AspectRatio,0.01,50); // Projecao perspectiva glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0, 4, 15, // PosiŤ‹o do Observador 0,0,0, // PosiŤ‹o do Alvo 0.0f,1.0f,0.0f); } // ********************************************************************** // void reshape( int w, int h ) // trata o redimensionamento da janela OpenGL // // ********************************************************************** void reshape( int w, int h ) { // Evita divis‹o por zero, no caso de uam janela com largura 0. if(h == 0) h = 1; // Ajusta a relaŤ‹o entre largura e altura para evitar distorŤ‹o na imagem. // Veja funŤ‹o "PosicUser". AspectRatio = 1.0f * w / h; // Reset the coordinate system before modifying glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Seta a viewport para ocupar toda a janela glViewport(0, 0, w, h); //cout << "Largura" << w << endl; PosicUser(); } // ********************************************************************** // void display( void ) // // // ********************************************************************** float PosicaoZ = -30; void display( void ) { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); DefineLuz(); PosicUser(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glTranslatef ( 5.0f, 0.0f, 3.0f ); glRotatef(angulo,0,1,0); glColor3f(0.5f,0.0f,0.0f); // Vermelho DesenhaCubo(); glPopMatrix(); glPushMatrix(); glTranslatef ( -4.0f, 0.0f, 2.0f ); glRotatef(angulo,0,1,0); glColor3f(0.6156862745, 0.8980392157, 0.9803921569); // Azul claro DesenhaCubo(); glPopMatrix(); DesenhaPiso(); glutSwapBuffers(); } // ********************************************************************** // void keyboard ( unsigned char key, int x, int y ) // // // ********************************************************************** void keyboard ( unsigned char key, int x, int y ) { switch ( key ) { case 27: // Termina o programa qdo exit ( 0 ); // a tecla ESC for pressionada break; case 'p': ModoDeProjecao = !ModoDeProjecao; glutPostRedisplay(); break; case 'e': ModoDeExibicao = !ModoDeExibicao; init(); glutPostRedisplay(); break; default: cout << key; break; } } // ********************************************************************** // void arrow_keys ( int a_keys, int x, int y ) // // // ********************************************************************** void arrow_keys ( int a_keys, int x, int y ) { switch ( a_keys ) { case GLUT_KEY_UP: // When Up Arrow Is Pressed... glutFullScreen ( ); // Go Into Full Screen Mode break; case GLUT_KEY_DOWN: // When Down Arrow Is Pressed... glutInitWindowSize ( 700, 500 ); break; default: break; } } // ********************************************************************** // void main ( int argc, char** argv ) // // // ********************************************************************** int main ( int argc, char** argv ) { glutInit ( &argc, argv ); glutInitDisplayMode (GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB ); glutInitWindowPosition (0,0); glutInitWindowSize ( 700, 700 ); glutCreateWindow ( "Computacao Grafica - Exemplo Basico 3D" ); init (); //system("pwd"); glutDisplayFunc ( display ); glutReshapeFunc ( reshape ); glutKeyboardFunc ( keyboard ); glutSpecialFunc ( arrow_keys ); glutIdleFunc ( animate ); glutMainLoop ( ); return 0; }