// **********************************************************************
// StencilTeste1.cpp
//
// Autor: Márcio Serolli Pinho
// **********************************************************************
#include <windows.h>
#include <stdio.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include <glut.h>
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 ( );
}