// ********************************************************************** // StencilTeste1.cpp // // Autor: Márcio Serolli Pinho // ********************************************************************** #include #include #include #include #include GLfloat ratio; static GLfloat ang = 0; // ********************************************************************** // void DefineLuz(void) // // // ********************************************************************** void DefineLuz(void) { // Define cores para um objeto dourado GLfloat LuzAmbiente[] = {0.24725f, 0.1995f, 0.07f } ; GLfloat LuzDifusa[] = {0.75164f, 0.60648f, 0.22648f, 1.0f }; GLfloat LuzEspecular[] = {0.626281f, 0.555802f, 0.366065f, 1.0f }; GLfloat PosicaoLuz0[] = {3.0f, 3.0f, 0.0f, 1.0f }; GLfloat PosicaoLuz1[] = {-3.0f, -3.0f, 0.0f, 1.0f }; GLfloat Especularidade[] = {1.0f, 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ção 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.2); // **************** Fonte de Luz 1 // Ativa o uso da luz ambiente glLightModelfv(GL_LIGHT_MODEL_AMBIENT, LuzAmbiente); // Define os parametros da Luz número Zero glLightfv(GL_LIGHT1, GL_AMBIENT, LuzAmbiente); glLightfv(GL_LIGHT1, GL_DIFFUSE, LuzDifusa ); glLightfv(GL_LIGHT1, GL_SPECULAR, LuzEspecular ); glLightfv(GL_LIGHT1, GL_POSITION, PosicaoLuz1 ); glEnable(GL_LIGHT1); // Ativa o "Color Tracking" glEnable(GL_COLOR_MATERIAL); // Define a reflectancia do material glMaterialfv(GL_FRONT,GL_SPECULAR, Especularidade); // Define a concentração 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,20); } // ********************************************************************** // void init(void) // Inicializa os parâmetros globais de OpenGL // // ********************************************************************** void Init(void) { glClearColor(1.0f, 1.0f, 0.0f, 1.0f); // Fundo de tela preto glShadeModel(GL_SMOOTH); // modelo de tonalização glColorMaterial ( GL_FRONT, GL_AMBIENT_AND_DIFFUSE ); glEnable(GL_DEPTH_TEST); // habilita ZBuffer glEnable ( GL_CULL_FACE ); // Habilita remoçõa de faces traseiras } // ********************************************************************** // void PosicUser() // // // ********************************************************************** void PosicUser() { // Set the clipping volume glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(80,ratio,0.01,200); gluLookAt(0, 0, 5, 0,0,0, 0.0f,1.0f,0.0f); } // ********************************************************************** // 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 InicializaStencil() // Esta função deve ser chamada toda vez que a janela for // redimensionada. // // ********************************************************************** void InicializaStencil() { // Habilita o uso do Stencil neste programa glEnable(GL_STENCIL_TEST); // Define que "0" será usado para limpar o Stencil glClearStencil(0); // limpa o Stencil glClear(GL_STENCIL_BUFFER_BIT); // ***************************** // Inicialização do Stencil // ***************************** // Define que o valor 1 será "operado" // com o valor do stencil GLint Referencia = 1; GLuint NovoValor = 1; // Define o teste a ser feito entre o valor do // stencil e o valor de "Referencia". // Se o teste for verdadeiro então NovoValor será // usado para operar sobre o valor corrente do Stencil // GL_ALWAYS = o teste é sempre verdadeiro // GL_EQUAL = o teste é verdadeiro se Referencia == Stencil // GL_LEQUAL = o teste é verdadeiro se Referencia <= Stencil // GL_NOTQUAL = o teste é verdadeiro se Referencia != Stencil glStencilFunc(GL_ALWAYS, Referencia, NovoValor); // Define como o NovoValor é colocado no Stencil: // GL_REPLACE = define que o valor atual // do stencil será trocado pelo NovoValor // GL_KEEP = define que o valor atual // do stencil será mantido glStencilOp(GL_REPLACE,GL_REPLACE,GL_REPLACE); // Define uma área de desenha com coordenadas // lógicas (0,0)->(10,10) // Ativa matriz de projeção (necessário para usar a gluOrtho2D) glMatrixMode(GL_PROJECTION); glLoadIdentity (); gluOrtho2D(0, 10, 0, 10); // define coordenadas lógicas de desenho // Volta para a matrix de transformações geométricas glMatrixMode(GL_MODELVIEW); // Desenha um retângulo glRectf(0,4.5, 10,5.5); } // ********************************************************************** // void reshape( int w, int h ) // trata o redimensionamento da janela OpenGL. // Atualiza o stencil buffer // ********************************************************************** void reshape( int w, int h ) { // evita uma divisão por 0 if(h == 0) h = 1; ratio = 1.0f * w / h; // glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Set the viewport to be the entire window glViewport(0, 0, w, h); InicializaStencil(); } // ********************************************************************** // void DesenhaNoStencil() // // // ********************************************************************** void DesenhaNoStencil() { static GLfloat DeltaX = -2; // ***************************** // Libera o desenho na área em que o // Stencil tem 1 // ***************************** // Se o conteúdo do Stencil for == 1, // então // - desenha na tela // - opera o conteúdo do stencil com o 1... // glStencilFunc(GL_EQUAL, 1, 1); glStencilOp(GL_KEEP,GL_KEEP, GL_KEEP); glMatrixMode(GL_PROJECTION); glLoadIdentity (); gluOrtho2D(0, 10, 0, 10); glMatrixMode(GL_MODELVIEW); glLoadIdentity (); glDisable(GL_DEPTH_TEST); // Desabilita o ZBuffer glColor3f(1,0,0); glRectf(2.0f, 4.7f, 8.0f, 5.3f); glTranslatef(DeltaX,0,1); glColor3f(0,1,0); glRectf(4.5f, 4.5f, 5.5f, 5.5f); DeltaX +=0.01f; if (DeltaX > 2.5f) DeltaX = -2; printf("DeltaX : %6.3f\n", DeltaX); glEnable(GL_DEPTH_TEST); // habilita o ZBuffer } // ********************************************************************** // void DesenhaForaDoStencil() // // // ********************************************************************** void DesenhaForaDoStencil() { // ***************************** // Libera o desenho no Stencil // na área em que o Stencil é // DIFERENTE de 1 // ***************************** // Se o conteúdo do Stencil for <> de 1, // então // - desenha na tela // - opera o conteúdo do stencil com o 1... // glStencilFunc(GL_NOTEQUAL, 1, 1); // ... mantendo o stencil como ele estava glStencilOp(GL_KEEP,GL_KEEP, GL_KEEP); // ***************************** // Faz o desenho 3D // ***************************** glMatrixMode(GL_MODELVIEW); glLoadIdentity (); glPushMatrix(); glTranslatef ( 1.0f, 0.0f, 0.0f ); glRotatef(ang,0,1,0); glColor3f(0.5f,0.3f,0.0f); DesenhaCubo(); glPopMatrix(); glLoadIdentity (); glPushMatrix(); glTranslatef ( -1.0f, 0.0f, -5.0f ); glRotatef(45,0,1,0); glColor3f(0.5f,0.3f,0.0f); DesenhaCubo(); glPopMatrix(); ang = ang + 2; } // ********************************************************************** // void display( void ) // // // ********************************************************************** void display( void ) { // Limpa a tela glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); DefineLuz(); PosicUser(); DesenhaForaDoStencil(); DesenhaNoStencil(); 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; default: 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: break; case GLUT_KEY_DOWN: break; default: break; } } // ********************************************************************** // void main ( int argc, char** argv ) // // // ********************************************************************** void main ( int argc, char** argv ) { glutInit ( &argc, argv ); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_STENCIL); glutInitWindowPosition (0,0); glutInitWindowSize ( 500, 500 ); glutCreateWindow ( "Tópicos em Computação Gráfica - Teste com STENCIL Buffer." ); Init (); glutDisplayFunc ( display ); glutReshapeFunc ( reshape ); glutKeyboardFunc ( keyboard ); glutSpecialFunc ( arrow_keys ); glutIdleFunc ( display ); glutMainLoop ( ); }