A utilização de áreas de mascaramento telas
geradas com programas OpenGL tem o objetivo de criar regiões onde
os objetos não podem ser desenhados.
Um exemplo disto são as áreas reservadas a menus e telas
de ajuda. Estas, quando presentes na tela, não devem ser afetadas
pelos desenhos 3D gerados com comandos OpenGL.
Para dar suporte a este tipo de situação a biblioteca
OpenGL possui um recurso chamado de Stencil Buffer.
O Stencil Buffer é uma matriz bidimensional que possui o mesmo tamanho da janela de desenho usada em para exibir os objetos OpenGL. Para criá-la deve-se usar a constante GLUT_STENCIL no comando de inicialização da GLUT:
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH |GLUT_STENCIL);
// 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);
Não há, entretanto, funções que permitam o acesso direto ao Stencil Buffer.
O armazenamento de dados no Stencil é feito desenhando-se
sobre a tela OpenGL como normalmente se faz. No caso de se desejar colocar
dados no Stencil, entretato, define-se funções de teste
que irão colocar (ou não) dados na área do Stencil,
dependendo do resiltado dos testes.
Por exemplo,
definem que o valor ''NovoDado" será usado para substituir (GL_REPLACE) o conteúdo do Stencil Buffer sempre (GL_ALWAYS) que um desenho for feito na tela de OpenGL.Referencia = 1;
NovoDado = 1;
glStencilFunc(GL_ALWAYS, Referencia, NovoDado);
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);
Estas funções fazem com que sempre que o Stencil Buffer tiver valor igual (GL_EQUAL) a 1 então o desenho pode ser exibido na tela. O valor existente no Stencil Buffer, no ponto onde o desenho está sendo realizado deverá, ser mantido como está (GL_KEEP).glStencilFunc(GL_EQUAL, 1, 1);
glStencilOp(GL_KEEP,GL_KEEP, GL_KEEP);
O trecho de programa seguir exibe dois retângulos (um verde e outro vermelho) na área do Stencil. Note que se faz uso do comando glDisable(GL_DEPTH_TEST) a fim de desabilitar o teste do ZBUFFER. isto é feito pois neste caso o desenho é 2D, não necessitando do uso de teste de profundidade.
O código descrito aqui deve ser colocado na roina que trata do redesenho da tela.glStencilFunc(GL_EQUAL, 1, 1);
glStencilOp(GL_KEEP,GL_KEEP, GL_KEEP);// Ativa matriz de projeção (necessário para usar a gluOrtho2D)
glMatrixMode(GL_PROJECTION);
glLoadIdentity ();
// define coordenadas lógicas de desenho
gluOrtho2D(0, 10, 0, 10);// Volta para a matrix de transformações geométricas
glMatrixMode(GL_MODELVIEW);glDisable(GL_DEPTH_TEST); // Desabilita o ZBuffer
glColor3f(0,1,0); // Desenha um retângulo verde
glRectf(4.5f, 4.5f, 5.5f, 5.5f);glColor3f(1,0,0); // Desenha um retângulo vermelho
glRectf(2.0f, 4.7f, 8.0f, 5.3f);glEnable(GL_DEPTH_TEST); // Habilita o ZBuffer
Estas funções fazem com que sempre que o Stencil Buffer tiver valor diferente (GL_NOTEQUAL) de 1 então o desenho pode ser exibido na tela. O valor existente no Stencil Buffer, no ponto onde o desenho está sendo realizado, deverá ser mantido como está (GL_KEEP).glStencilFunc(GL_NOTEQUAL, 1, 1);
glStencilOp(GL_KEEP,GL_KEEP, GL_KEEP);
O trecho de programa seguir exibe dois cubos FORA da área do Stencil.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity ();
glPushMatrix();glTranslatef ( 1.0f, 0.0f, 0.0f );glPopMatrix();
glRotatef(ang,0,1,0);
glColor3f(0.5f,0.3f,0.0f);
DesenhaCubo();glLoadIdentity ();
glPushMatrix();glTranslatef ( -1.0f, 0.0f, -5.0f );glPopMatrix();
glRotatef(45,0,1,0);
glColor3f(0.5f,0.3f,0.0f);
DesenhaCubo();ang = ang + 2;