Computação Gráfica
Geração de Geometria - Terrenos
António Ramires Fernandes + Luís Paulo Santos - Computação Gráfica 08/09
Mapas de Alturas
Intensidade por pixel pode representar uma altura numa grelha regular
DI-UM Computação Gráfica 06/07
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.
• Tarefas:
– Carregar a imagem
– Criar a geometria do terreno
a partir da matriz de pixels
extraída da imagem.
– Colocar todas as entidades do
modelo na altura correcta
DI-UM Computação Gráfica 06/07
3
Carregar a Imagem - tgalib
• Em www.lighthouse3d.com é disponibilizado código
para carregar TARGA (.TGA):
tgaInfo * tgaLoad(char *filename);
typedef struct {
int status;
unsigned char type, pixelDepth;
short int width, height;
unsigned char *imageData;
}tgaInfo;
DI-UM Computação Gráfica 06/07
4
Alternativa: DevIL
• http://openil.sourceforge.net/
“A full featured cross-platform image library”
• Abrir um ficheiro de imagem
ilInit();
ilGenImages(1,ima); // unsigned int ima[...]
ilBindImage(ima[0]);
ilLoadImage(filename); // char *filename
DI-UM Computação Gráfica 06/07
5
Alternativa: 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 06/07
6
Alternativa: 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 06/07
7
Alternativa: DevIL
• Exemplo para carregar uma imagem:
unsigned int t;
ilGenImages(1,&t);
ilBindImage(t);
ilLoadImage("bla.jpg");
tw = ilGetInteger(IL_IMAGE_WIDTH);
th = ilGetInteger(IL_IMAGE_HEIGHT);
imgData = ilGetData();
DI-UM Computação Gráfica 06/07
8
Geração de geometria
z
(0,0)
Mundo
zt
x
(0,0)
H-Map
xt
• Gerar o terreno como uma strip de triângulos, sendo y
dados pelo valor do h-map no ponto (xt,zt)
• Origem (0,0) no centro do mundo e canto do H-Map
• Atenção aos diferentes sistemas de eixos
DI-UM Computação Gráfica 06/07
9
Geração de geometria
z
zt
(0,0)
Mundo
(0,0)
x
for (z=0 ; z <
for (x=0 ; x
glVertex3f
glVertex3f
glEnd(); }
MapL-1
< MapW
(x0+x,
(x0+x,
H-Map
xt
; z++) { glBegin(GL_TRIANGLE_STRIP);
; x++) {
Map[x][z+1], z0-(z+1));
Map[x][z], z0-z); }
DI-UM Computação Gráfica 06/07
10
Geometria: Display Lists
• Conjunto de comandos pré-compilados que podem ser
reutilizados:
// Create the id for the display list
terrainDL = glGenLists(1);
// create the display list
glNewList(terrainDL,GL_COMPILE);
for (z=0 ; z < MapL-1 ; z++) {
glBegin(GL_TRIANGLE_STRIP);
for (x=0 ; x < MapW ; x++) {
glVertex3f (x0+x, Map[x][z+1], z0-(z+1));
glVertex3f (x0+x, Map[x][z], z0-z);
}
glEnd();
}
glEndList();
DI-UM Computação Gráfica 06/07
11
Geometria: Display Lists
• Na função que desenha a cena (ex., renderScene()) basta
chamar a display list:
glCallList (TerrainDL);
• Permite um aumento de desempenho significativo devido à précompilação dos comandos de especificação da geometria
• Uma display list pode ser alterada executando de novo
glNewList() .. glEndList()
• Uma display list pode ser removida com glDeleteLists()
DI-UM Computação Gráfica 06/07
12
Geometria: terrain.cpp
• O ficheiro terrain.cpp disponibiliza o esqueleto de
código para:
– Carregar o h-map a partir e um ficheiro (usando tgaLoad())
int terrainLoadImage (char *filename, int normals);
– Criar a display list devolvendo o seu ID
int terrainCreateDL (float xOff, float yOff, float zOff);
– Dadas as coordenadas do mundo (x,z) devolver a respectiva
altura de acordo com o height map
float terrainGetHeight (float x, float z);
DI-UM Computação Gráfica 06/07
13
Exercício
• Adapte a aplicação desenvolvida nas sessões
anteriores para que:
– Carregue um height map e desenhe o terreno de acordo com
estes
– Posicione os vários elementos (indios, cowboys, arvores,
tesouro) à altura apropriada
– A câmara móvel faça surface following, isto é, se desloque ao
longo da superfície adaptando-se à respectiva altura
DI-UM Computação Gráfica 06/07
14
Interpolação bilinear
• As coordenadas no mundo são números reais, as coordenadas no
mapa de textura são inteiros (melhor, o h-map só está definido
para coordenadas inteiras)
• Solução: interpolação bilinear
hb
z2
x1 = int(x); xFrac = frac(x); x2 = x1+1;
z1 = int(z); zFrac = frac(z); z2 = z1+1;
(x,z)
ha = h(x1,z1)*(1-xFrac) + h(x2,z1)*xFrac;
hb = h(x1,z2)*(1-xFrac) + h(x2,z2)*xFrac;
zFrac
z1
x1
ha
x2
h = há*(1-zFrac) + hb*zFrac;
xFrac
DI-UM Computação Gráfica 06/07
15
Mapeamento
• Neste momento, a área do terreno é determinado pela resolução
do h-map.
Modifique o código de forma a que o utilizador possa indicar a
resolução pretendida para o terreno, invocando a função
terrainDim (int wWidth, int wLength);
• Note que para passar de coordenadas (x,z) do mundo para (xt,
zt) do h-map deverá aplicar a função:
( xt, zt )  f ( x, z )  ( x *
GridWidth GridWidth GridLength
GridLength

,
 z*
)
2
2
wWidth
wLength
DI-UM Computação Gráfica 06/07
16
Download

tp05 - HPC