160 likes | 244 Views
Computação Gráfica. Geração de Geometria - Terrenos. Mapas de Alturas. Intensidade por pixel pode representar uma altura numa grelha regular. Terrenos a partir de Imagens. Objectivo:
E N D
Computação Gráfica Geração de Geometria - Terrenos
Mapas de Alturas Intensidade por pixel pode representar uma altura numa grelha regular DI-UM Computação Gráfica 06/07
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 terrenoa partir da matriz de pixels extraída da imagem. • Colocar todas as entidades domodelo na altura correcta DI-UM Computação Gráfica 06/07
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
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
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
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
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
Geração de geometria • 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 (0,0) Mundo H-Map zt z x xt (0,0) DI-UM Computação Gráfica 06/07
Geração de geometria 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(); } (0,0) Mundo H-Map zt z x xt (0,0) DI-UM Computação Gráfica 06/07
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
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
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 mapfloat terrainGetHeight (float x, float z); DI-UM Computação Gráfica 06/07
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
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; ha = h(x1,z1)*(1-xFrac) + h(x2,z1)*xFrac; hb = h(x1,z2)*(1-xFrac) + h(x2,z2)*xFrac; h = há*(1-zFrac) + hb*zFrac; (x,z) zFrac ha z1 x1 x2 xFrac DI-UM Computação Gráfica 06/07
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: DI-UM Computação Gráfica 06/07