O objetivo desta aula é aprender a utilizar mapeamento de textura em OpenGL. Para isto,
será utilizada a API JOGL e a linguagem de programação Java, tendo como resultado um programa que pode ser executado tanto
no ambiente Windows como no ambiente Linux.
Para implementação de aplicações com JOGL na linguagem de programação Java é
necessário configurar um projeto para linkar as bibliotecas. Na
primeira aula prática já foi explicado como configurar o projeto
para o ambiente Eclipse, portanto, basta criar um novo projeto no drive H, configurá-lo conforme explicado e incluir os
programas fonte e imagens que serão usados nesta aula. Para facilitar, deixe as imagens na pasta do
projeto junto com os programas fonte.
O mapeamento de textura 2D em OpenGL consiste em carregar uma imagem de um arquivo e "colar" esta imagem na
superfície do(s) objeto(s). É importante salientar que a largura e a altura desta imagem devem ser potências de 2. A utilização de mapeamento de textura
é um procedimento complexo em OpenGL, pois existem muitas variações e diversas funções de manipulação. Nesta aula prática, serão apresentados
alguns exemplos e conceitos básicos da sua utilização.
A primeira tarefa, consiste em compilar e executar o programa que exemplifica a
utilização de mapeamento de textura. A imagem abaixo deverá ser apresentada.
Observe como foram implementados os métodos loadImage, init e display, nesta ordem.
Analisando os comentários do código fonte, observa-se que, de maneira simplificada, os passos para o mapeamento de textura são:
- Ler uma imagem e armazenar num objeto adequado;
- Criar um identificador para a textura;
- Definir a textura em OpenGL;
- Especificar como a textura será aplicada em cada pixel (filtros);
- Habilitar o mapeamento de textura;
- Desenhar os objetos fornecendo uma coordenada de textura para cada coordenada geométrica.
Os parâmetros passados para o método
public void glTexImage2D(int target, int level, int internalFormat, int width, int height, int border, int format, int type, Buffer pixels), que
faz o envio da textura para OpenGL, são:
-target: GL_TEXTURE_2D;
-level: nível de detalhe da imagem de textura;
-internalFormat:número de valores de cor para cada pixel (RGB=3, RGBA=4);
-width e height: tamanho da imagem de textura (devem ser potências de 2);
-border: deve ser 0;
-format: tipo de valor de cor esperado (GL_ALPHA, GL_COLOR_INDEX, GL_BGR , GL_RGB, GL_RGBA, ...);
-type: indica o formato e tipo de dado (GL_BYTE, GL_SHORT, GL_INT, GL_FLOAT, GL_BITMAP, ...);
-pixels: textura.
OpenGL tem três modos de textura:
-GL_MODULATE: Ajusta valores de cor e iluminação com a imagem de textura (mais usado);
-GL_DECAL: Usa apenas a imagem de textura (cor e iluminação não alteram a aparência da textura)
-GL_BLEND: Usado com um ou dois componentes de textura (imagem de textura é misturada com a cor de textura e com as informações de cor e iluminação).
O método para especificação do modo de textura é: public void glTexEnvi(int target, int pname, int param). O primeiro parâmetro, neste caso,
deve ser GL_TEXTURE_ENV, o segundo deve ser GL_TEXTURE_ENV_MODE e o
terceiro pode ser GL_DECAL,GL_REPLACE, GL_MODULATE,GL_BLEND.
Para verificar como funcionam estes diferentes modos de textura, acrescente a chamada para o método abaixo
como último comando do método init. Altere também a cor para magenta(1.0f, 0.0f, 1.0f) na chamada para gl.glColor3f que aparece
logo acima de gl.glBegin(GL_QUADS) no método display.
gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE);
Compile e execute a aplicação para verificar o resultado. Experimente trocar o parâmetro GL.GL_MODULATE por GL.GL_DECAL e GL.GL_BLEND
e verifique o que acontece.
Filtros de textura são usados para interpolar pixels de textura. Dois tipos são
fornecidos em OpenGL:
-GL_TEXTURE_MIN_FILTER para polígonos que são menores que a imagem de textura;
-GL_TEXTURE_MAG_FILTER para polígonos que são maiores que a imagem de textura.
O método usado para especificar estes filtros é glTexParameteri, e o seu último
parâmetro corresponde ao filtro. Este último parâmetro pode ser GL.GL_NEAREST,
GL.GL_LINEAR, GL.GL_NEAREST_MIPMAP_NEAREST, etc.
Agora altere os filtros GL.GL_LINEAR usados no método init por GL.GL_NEAREST e, utilizando
zoom, verifique se há diferença de resolução. Experimente também usar as diferentes imagens fornecidas (ex. imagem1.jpg e imagem2.jpg)
para ver o resultado.
As coordenadas de textura associam um ponto
específico na imagem de textura com vértices de um polígono,
conforme ilustra a figura abaixo. O método usado para especificar
estas coordenadas é:
public void glTexCoord2f(float s, float t)
Os parâmetros s e t indicam as coordenadas para os
eixos horizontais e verticais da imagem, respectivamente. Neste caso,
por exemplo, t é 0.0 para o pixel mais abaixo na imagem de textura e
1.0 para o pixel mais acima.
Coordenadas de textura normalmente possuem
valores entre 0.0 e 1.0. Para valores fora deste intervalo elas são:
-Clamped (GL.GL_CLAMP);
-Repeated (GL.GL_REPEAT).
O método para especificar como serão tratados os valores fora deste intervalo
é glTexParameteri, mas, neste caso, o segundo parâmetro deve ser GL.GL_TEXTURE_WRAP_S ou
GL.GL_TEXTURE_WRAP_T, e o terceiro parâmetro pode ser GL.GL_CLAMP ou
GL.GL_REPEAT.
Para exemplificar como funciona o texture wrapping, acrescente
as linhas de código abaixo no final do método init, mas antes da chamada para o método gl.glTexEnvi.
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP);
Logo em seguida, altere as coordenadas de textura da face frontal da seguinte maneira:
gl.glTexCoord2f(-1.0f, -1.0f); gl.glVertex3f(-1.0f, -1.0f, 1.0f);
gl.glTexCoord2f(1.0f, -1.0f); gl.glVertex3f( 1.0f, -1.0f, 1.0f);
gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f( 1.0f, 1.0f, 1.0f);
gl.glTexCoord2f(-1.0f, 1.0f); gl.glVertex3f(-1.0f, 1.0f, 1.0f);
Após executar o programa, altere o parâmetro GL.GL_CLAMP para GL.GL_REPEAT e execute-o novamente.
Você deve estar se perguntando como seria possível aplicar o mapeamento de textura na esfera se não sabemos
as coordenadas dos vértices para associar com as coordenadas de textura? Bom, neste caso é necessário fazer uma geração automática das
coordenadas de textura. Para ver um exemplo, siga os passos listados a seguir:
1) Verifique no método init se estão sendo passados os parâmetros exibidos abaixo para cada chamada de método.
gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MIN_FILTER,GL.GL_LINEAR);
gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MAG_FILTER,GL.GL_LINEAR);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);
gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE);
2) Acrescente os comandos abaixo antes de desenhar o cubo e logo após o comentário "// Desenha um cubo no qual a textura é aplicada".
gl.glDisable(GL.GL_TEXTURE_GEN_S);
gl.glDisable(GL.GL_TEXTURE_GEN_T);
3) Acrescente os comandos abaixo antes de desenhar a esfera e logo após o comentário "// Desenha uma esfera azul". Cuide para que o método
glColor3f seja chamado apenas uma vez com a cor branca.
gl.glEnable(GL.GL_TEXTURE_2D);
float texgen_s[] = {0.5f, 0.0f, 0.0f, 0.5f};
float texgen_t[] = {0.0f, 0.5f, 0.0f, 0.5f};
gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE, GL.GL_EYE_LINEAR);
gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE, GL.GL_EYE_LINEAR);
gl.glTexGenfv(GL.GL_S, GL.GL_OBJECT_PLANE, texgen_s, 0);
gl.glTexGenfv(GL.GL_T, GL.GL_OBJECT_PLANE, texgen_t, 0);
gl.glEnable(GL.GL_TEXTURE_GEN_S); // Habilita a geração da textura
gl.glEnable(GL.GL_TEXTURE_GEN_T);
gl.glColor3f(1.0f, 1.0f, 1.0f);
Compile e execute a aplicação para ver o resultado.
Para finalizar a aula de hoje, experimente alterar o código desta aplicação para permitir aplicar uma
textura diferente para cada objeto. Lembre-se que através da chamada ao método gl.glBindTexture é possível especificar qual é a
"textura corrente" e que é necessário gerar um identificador para cada textura.
Comentários, dúvidas, sugestões, envie um mail para seu(sua) professor(a)

|