//***************************************************** // // Exemplo3DWireframe.cpp // Um programa OpenGL que abre uma janela GLUT, desenha // o wireframe de um objeto representado por uma malha // de polígonos, e permite fazer zoom in e zoom out // pressionando os botões do mouse (projeção perspectiva). // IMPORTANTE: É necessário incluir no projeto a // biblioteca bibutil.cpp // // Marcelo Cohen e Isabel H. Manssour // Este código acompanha o livro // "OpenGL - Uma Abordagem Prática e Objetiva" // //***************************************************** #include "bibutil.h" // Variáveis para controles de navegação GLfloat angle, fAspect; GLfloat rotX, rotY, rotX_ini, rotY_ini; GLfloat obsX, obsY, obsZ, obsX_ini, obsY_ini, obsZ_ini; int x_ini,y_ini,bot; // Apontador para o objeto OBJ *objeto; // Função callback de redesenho da janela de visualização void desenhaChao() { glColor3f(0,0,1); glLineWidth(1); glBegin(GL_LINES); for(float z=-1000; z<=1000; z+=10) { glVertex3f(-1000,-0.1f,z); glVertex3f( 1000,-0.1f,z); } for(float x=-1000; x<=1000; x+=10) { glVertex3f(x,-0.1f,-1000); glVertex3f(x,-0.1f,1000); } glEnd(); glLineWidth(1); } void Desenha(void) { // Limpa a janela de visualização com a cor // de fundo definida previamente glClear(GL_COLOR_BUFFER_BIT); // Desenha o wireframe do objeto 3D lido do arquivo com a cor corrente desenhaChao(); glColor3f(1.0f, 1.0f, 0.0f); glLineWidth(3); DesenhaObjeto(objeto); // Executa os comandos OpenGL //glFlush(); glutSwapBuffers(); } // Função usada para especificar a posição do observador virtual void PosicionaObservador(void) { // Especifica sistema de coordenadas do modelo glMatrixMode(GL_MODELVIEW); // Inicializa sistema de coordenadas do modelo glLoadIdentity(); // Posiciona e orienta o observador glTranslatef(-obsX,-obsY,-obsZ); glRotatef(rotX,1,0,0); glRotatef(rotY,0,1,0); } // Função usada para especificar o volume de visualização void EspecificaParametrosVisualizacao(void) { // Especifica sistema de coordenadas de projeção glMatrixMode(GL_PROJECTION); // Inicializa sistema de coordenadas de projeção glLoadIdentity(); // Especifica a projeção perspectiva(angulo,aspecto,zMin,zMax) gluPerspective(angle,fAspect,0.1,1200); PosicionaObservador(); } // Função callback chamada quando o tamanho da janela é alterado void AlteraTamanhoJanela(GLsizei w, GLsizei h) { // Para previnir uma divisão por zero if ( h == 0 ) h = 1; // Especifica as dimensões da viewport glViewport(0, 0, w, h); // Calcula a correção de aspecto fAspect = (GLfloat)w/(GLfloat)h; EspecificaParametrosVisualizacao(); } // Função callback chamada para gerenciar eventos de teclas normais (ESC) void Teclado (unsigned char tecla, int x, int y) { if(tecla==27) // ESC ? { // Libera memória e finaliza programa LiberaObjeto(objeto); exit(0); } } void TeclasEspeciais (int tecla, int x, int y) { switch (tecla) { case GLUT_KEY_HOME: if(angle>=10) angle -=5; break; case GLUT_KEY_END: if(angle<=150) angle +=5; break; } PosicionaObservador(); glutPostRedisplay(); } // Função callback para eventos de botões do mouse void GerenciaMouse(int button, int state, int x, int y) { if(state==GLUT_DOWN) { // Salva os parâmetros atuais x_ini = x; y_ini = y; obsX_ini = obsX; obsY_ini = obsY; obsZ_ini = obsZ; rotX_ini = rotX; rotY_ini = rotY; bot = button; } else bot = -1; } // Função callback para eventos de movimento do mouse #define SENS_ROT 5.0 #define SENS_OBS 15.0 #define SENS_TRANSL 20.0 void GerenciaMovim(int x, int y) { // Botão esquerdo ? if(bot==GLUT_LEFT_BUTTON) { // Calcula diferenças int deltax = x_ini - x; int deltay = y_ini - y; // E modifica ângulos rotY = rotY_ini - deltax/SENS_ROT; rotX = rotX_ini - deltay/SENS_ROT; } // Botão direito ? else if(bot==GLUT_RIGHT_BUTTON) { // Calcula diferença int deltaz = y_ini - y; // E modifica distância do observador obsZ = obsZ_ini + deltaz/SENS_OBS; } else if(bot==GLUT_MIDDLE_BUTTON) { // Calcula diferenças int deltax = x_ini - x; int deltay = y_ini - y; // E modifica posições obsX = obsX_ini + deltax/SENS_TRANSL; obsY = obsY_ini - deltay/SENS_TRANSL; } PosicionaObservador(); glutPostRedisplay(); } // Função responsável por inicializar parâmetros e variáveis void Inicializa (void) { char nomeArquivo[30]; // Define a cor de fundo da janela de visualização como branca glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Inicializa a variável que especifica o ângulo da projeção // perspectiva angle=54; // Inicializa as variáveis usadas para alterar a posição do // observador virtual rotX = 0; rotY = 0; obsX = obsY = 0; obsZ = 10; // Lê o nome do arquivo e chama a rotina de leitura printf("Digite o nome do arquivo que contem o modelo 3D: "); gets(nomeArquivo); // Carrega o objeto 3D cout << nomeArquivo << endl; objeto = CarregaObjeto(nomeArquivo,false); //escalaObjeto(objeto,30); cout << "ok\n"; system("pause"); // Seta o modo de desenho como wireframe SetaModoDesenho('w'); // 's' para sólido } // Programa Principal int main(int argc, char** argv) { glutInit(&argc, argv); // Define do modo de operação da GLUT glutInitDisplayMode(GLUT_DOUBLE| GLUT_RGB); // Especifica a posição inicial da janela GLUT glutInitWindowPosition(5,5); // Especifica o tamanho inicial em pixels da janela GLUT glutInitWindowSize(800,600); // Cria a janela passando como argumento o título da mesma glutCreateWindow("Desenho do wireframe de um objeto 3D"); // Registra a função callback de redesenho da janela de visualização glutDisplayFunc(Desenha); // Registra a função callback de redimensionamento da janela de visualização glutReshapeFunc(AlteraTamanhoJanela); // Registra a função callback para tratamento das teclas normais glutKeyboardFunc (Teclado); // Registra a função callback para tratamento das teclas especiais glutSpecialFunc (TeclasEspeciais); // Registra a função callback para eventos de botões do mouse glutMouseFunc(GerenciaMouse); // Registra a função callback para eventos de movimento do mouse glutMotionFunc(GerenciaMovim); // Chama a função responsável por fazer as inicializações Inicializa(); // Inicia o processamento e aguarda interações do usuário glutMainLoop(); return 0; }