Computação Gráfica LEI / LCC Departamento de Informática Universidade do Minho Geração de Geometria - Terrenos Imagens e Texturas António Ramires Fernandes – Computação Gráfica 09/10 Mapas de Alturas Intensidade por pixel pode representar uma altura numa grelha regular DI-UM Computação Gráfica 09/10 2 Terrenos a partir de Imagens • Objectivo: – Dada uma imagem criar uma grelha regular em que a altura de cada ponto da grelha corresponde à intensidade do pixel correspondente. Y • Tarefas: – Carregar a imagem – Criar a geometria a partir da matriz de pixels extraída da imagem. X Z DI-UM Computação Gráfica 09/10 3 Terrenos a partir de Imagens • Primeiro passo: – Construir uma grelha regular com altura 0.0 com as dimensões da imagem Y X Z DI-UM Computação Gráfica 09/10 4 Terrenos a partir de Imagens • Segundo Passo: – Atribuir as alturas de acordo com os dados da imagem (atenção às árvores) DI-UM Computação Gráfica 09/10 5 DevIL • Abrir um ficheiro de imagem ilInit(); ilGenImages(1,ima); // unsigned int ima[...] ilBindImage(ima[0]); ilLoadImage((ILstring)filename); // char *filename DI-UM Computação Gráfica 09/10 6 DevIL • Aceder aos dados e informações da imagem int width = ilGetInteger(IL_IMAGE_WIDTH); int height = ilGetInteger(IL_IMAGE_HEIGHT); unsigned char *imageData = ilGetData(); DI-UM Computação Gráfica 09/10 7 DevIL • Converter para escala de cinzentos ilConvertImage(IL_LUMINANCE,IL_UNSIGNED_BYTE); outras opções: IL_RGB, IL_RGBA DI-UM Computação Gráfica 09/10 8 Textura • Objectivo: Colocar uma textura na superfície do terreno – Carregar uma imagem e criar uma textura – definir coordenadas para a aplicação da textura DI-UM Computação Gráfica 09/10 9 DevIL + OpenGL • Exemplo para criar textura a partir de uma imagem: unsigned int t, tw, th; unsigned char *texData; ilGenImages(1,&t); ilBindImage(t); ilLoadImage((ILstring)“relva1.jpg"); tw = ilGetInteger(IL_IMAGE_WIDTH); th = ilGetInteger(IL_IMAGE_HEIGHT); ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE); texData = ilGetData(); glGenTextures(1,&texID); // unsigned int texID - variavel global; glBindTexture(GL_TEXTURE_2D,texID); glTexParameteri(GL_TEXTURE_2D, glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T, GL_REPEAT); GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_TEXTURE_MIN_FILTER, GL_LINEAR); GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData); DI-UM Computação Gráfica 09/10 10 Texturas • Activar Texturas (inicialização): glEnable(GL_TEXTURE_2D); • Antes de desenhar o terreno: glBindTexture(GL_TEXTURE_2D, texID); • Ao desenhar o terreno, definir para cada vértice as coordenadas de textura: glTexCoord2f(s,t); • Após desenhar o terreno: glBindTexture(GL_TEXTURE_2D, 0); DI-UM Computação Gráfica 09/10 11 Exercício • Dada uma imagem, interpretá-la como um mapa de alturas e gerar a geometria correspondente • Aplicar uma textura (outra imagem) ao terreno; • Colocar as árvores na altura correcta • TPC: Definir normais e activar a iluminação; • TPC: Implementar um esquema de surface following. DI-UM Computação Gráfica 09/10 12 Surface Following • Problema: determinar a altura do ponto (x,z) de uma grelha. Y Sendo h(i,j) a função que determina a altura nos vértices da grelha, é necessário determinar a altura do ponto (x,z) a partir dos cantos da célula onde o ponto se encontra X (x,z) Z DI-UM Computação Gráfica 09/10 13 Surface Following • Através da função h temos acesso às alturas dos cantos da célula (pontos amarelos). • a altura de (x11,z12) obtem-se por interpolação linear das alturas de (x1,z1) e (x1,z2). Processo semelhante para determinar a altura de (x22,z12). – • fz = z - z1; // 0 <= fz <= 1 (x11,z12) (x,z) (x22,z12) alt(x11,z12) = h(x1,z1) * (1-fz) + h(x1,z2) * fz alt(x22,z12) = h(x2,z1) * (1-fz) + h(x2,z2) * fz A altura de (x,z) obtem-se por interpolação entre as alturas de (x11,z12) e (x22,z12) – (x2,z1) seja fz a parte fraccionária de z: • – – (x1,z1) (x2,z2) (x1,z2) alt(x,z) = alt(x11,z12) * (1 - fx) + alt(x22,z12) * fx DI-UM Computação Gráfica 09/10 14 Normais numa Grelha • O cálculo da normal dentro de uma grelha pode ser realizado de uma forma simples recorrendo aos pontos vizinhos N E O S Considerando os 4 vizinhos (N,S,E,O), calculam-se dois vectores. O produto externo (normalizado) destes dois vectores é uma aproximação à normal pretendida. DI-UM Computação Gráfica 09/10 15