Mapeamento de Texturas -...

48
04/12/2011 Leandro Tonietto Mapeamento de Texturas Leandro Tonietto Computação Gráfica Jogos Digitais [email protected] http://professor.unisinos.brltonietto/jed/cgr/textura.pdf Abr-2012 quarta-feira, 26 de setembro de 12

Transcript of Mapeamento de Texturas -...

04/12/2011 Leandro Tonietto

Mapeamento de Texturas

Leandro ToniettoComputação GráficaJogos [email protected]://professor.unisinos.brltonietto/jed/cgr/textura.pdfAbr-2012

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 2

Sumário

IntroduçãoConceitosProcessoOpenGL e exemplosMipmappingObjetos de texturasPróximos passos.

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 3

Introdução

Modelos de iluminação e sombreamento são adequados para a modelagem de objetos monocromáticos e para simular diferentes efeitos produzidos pelas combinações das componentes de materiais.Entretanto, superfícies com detalhamento interno não são trivialmente simuladas com estes modelos. Imagine, por exemplo, a textura de uma madeira.Uma solução primária seria a simulação desses detalhes com polígonos.

Sobre um polígono base, cria-se outros polígonos que tomam como valores iniciais as informações de materiais do polígono base e embutem a variação necessária para simular o efeito mais realístico possível. A renderização dos polígonos de detalhe é feita sobre a do polígono base.

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 4

Introdução

Entretanto, o trabalho é árduo, computacionalmente oneroso e o efeito pode não ficar realístico.Solução: utilização de texturas para melhorar o realismo das cenas renderizadas.O processo chama-se mapeamento de textura.Iniciou com Catmull em 1974, que utilizou preenchimento de polígonos com imagem para simular detalhamento e realismo visual.

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 5

Conceitos

Texture mapping (mapeamento de textura)A informação de detalhe para o mapeamento pode ser uma imagem (tal como uma foto) ou uma gerada computacionalmente por uma função, chamada textura procedural.A imagem ou textura é chamada de texture map.Os elementos do mapa de textura são chamados de texels.

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 6

Conceitos

Imagem x textura:

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 7

Processo

Uma mapa de textura está num sistema de referência da própria textura e é normalizado (0 a 1).A idéia básica é que, para cada pixel [x,y] a ser renderizado, existe um texel [u,v] no espaço do mapa com a informação a ser utilizada na renderização.O valor mapeado é utilizado para substituir, ou para se somar, aos valores calculados nos modelos de iluminação e sombreamento.Um pixel pode estar relacionado a mais de um texel. Neste caso, os texels são somados e ponderados para determinar o melhor valor para o pixel.

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 8

Processo

Problema: Mapas são 2D e objetos, em geral, 3D.Para obter informação de textura:

Pontos são parametrizados para 2 coordenadas (s,t)

Para encontramos a cor da textura, pegamos um ponto (x,y,z) da superfície e mapeamos no espaço de texturaUsamos (s,t) como índices na imagem da textura

Polígonos:As coordenadas (s,t) são especificadas nos vértices(s,t) são interpolados para outros pontos

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 9

Processo

0,0

32,32

0,0

1,1

Map(0,1)

Map(1,0)

Map(0,0)

Textura (0,0,32,32)

Mapa (0,0,1,1)

Polígono mapeado

Polígono diferente com mesmo mapeamento

Map(1,1)

Map(0,1)

Map(1,0)Map(0,0)

Map(1,1)

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 10

Interpolação de textura

Especificar onde os vértices no sistema de referência do universo (SRU) são mapeados para o espaço de textura.Interpolar linearmente o mapeamento dos outros pontos diretamente no espaço de textura

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 11

Interpolação das coordenadas

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 12

Mapeamento de texturas

O mapeamento de texturas é feito no espaço de imagem quando o polígono é rasterizado Quando descrevemos uma cena, imaginamos que a textura será interpolada no espaço do universoProblema: distâncias iguais no espaço do universo não significam distâncias iguais em uma imagem projetada em perspectiva!Perspective correct texture mapping resolve o problema, mas é menos eficiente

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 13

Texturas no OpenGL

O processo de texturização de objetos no OpenGL envolve alguns passos básicos (e muitos outros para se chegar ao resultado desejado):

Primeiro passo: carregar a textura de um arquivo num formato de imagem: jpg, tga, gif, pnm, png, bmp e etc. Isto é de responsabilidade do programador.Um passo alternativo é computar alterações de tratamento de imagem para melhorar algum aspecto visual da textura (blur, sharpen, sépia, tons-de-cinza, negativo, saturação, troca de cores e etc.)

Ver especificação do formato PNM no site da disciplina de Processamento Gráfico

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 14

Texturas no OpenGL

Depois, carregar os bytes da imagem para o estado de textura do OpenGL. Pode-se usar:

void glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border,GLenum format, GLenum type, void *data);void glTexImage2D(target, level, internalformat, width, height, border, format, type, data);void glTexImage3D(target, level, internalformat, width, height, depth, border, format, type, data);

Estes métodos indicam ao OpenGL como tratar os dados recebidos

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 15

Texturas no OpenGL

Argumentos das funções:Target: GL_TEXTURE_1D, GL_TEXTURE_2D ou GL_TEXTURE_3D. Usado conforme a função.Level: nível de mipmapping, zero para não usar (veremos mais sobre mipmapping)InternalFormat: representação interna da cor. Como ela será armazenada: GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB e GL_RGBA.Width, height e depth: são as dimensões da textura, conforme o caso. Em geral são potencias de 2 (1, 2, 4, 8, 16, 32, ...), por questões de otimização de performance em hardware. Não precisam ser quadrados.Border: estabelece uma borda na textura; padrão é zero.Format: formato em que o texel aparece (ver tabela 8.2 em [3])Type: tipo de dado em que pixel está gravado.Data: são os bytes da imagem carregada do disco.

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 16

Texturas no OpenGL

Tabela dos formatos (retirado de [3]):

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 17

Texturas em OpenGL

Próximo passo é habilitar/desabilitar estado de textura no OpenGL:

glEnable(GL_TEXTURE_2D) e glDisable(GL_TEXTURE_2D)

Apenas um estado por vez pode estar habilitado.

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 18

Texturas em OpenGL

Por fim, fazer o mapeamento propriamente dito:

Para cada vértice do polígono, especifica-se uma coordenada de textura.As coordenadas são valores de ponto flutuante, normalizados: 0.0 a 1.0

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 19

Texturas em OpenGL

Comando para enviar o mapeamento:glTexCoord1f(s), glTexCoord2f(s,t) ou glTexCoord3f(s,t,r)

Usar sempre o par coordenada e vértice:glTexCoord2f(0, 1);

glVertex2f(0, 1);

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 20

Texturas em OpenGL

Exemplo do livro [3], pirâmide texturizada:

Ver executável e código fonte do exemplo.

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 21

Texturas em OpenGL

Ambiente de textura (texture environment):Modo do ambiente de textura indica ao OpenGL como misturar cores com texels:

glTexEnvi(GLenum target, GLenum pname, GLint param);Variações: f, iv e fvNo exemplo da pirâmide:

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 22

Texturas em OpenGL

Modos de ambiente de textura (texture environment modes):

Modulate (GL_MODULATE): multiplica a cor do texel pela cor da geometria (após cálculos de iluminação)

Permite que o resultado final tenha os detalhes da textura com as características de iluminação do sombreamento.

Replace (GL_REPLACE): substitui a informação de sombreamento pela cor da textura. Pode ser combinado com canal alpha para produzir efeitos de degradê.Decal (GL_DECAL): faz o efeito de um adesivo. A textura é plotada sobre as informação de sombreamento e, aonde, tiver alpha < 1.0, aparece alguma porção do sombreamento.Blend (GL_BLEND): mistura uma cor com a textura:

glTexEnvi(GL_TEXTURE_ENV, TEXTURE_ENV_MODE, GL_BLEND);glTexEnvfv(GL_TEXTURE_ENV, TEXTURE_ENV_COLOR, umaCor);

Add (GL_ADD): adiciona as cores da textura e de sombreamento. Valores acima de 1, reduzidos a 1.

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 23

Texturas em OpenGL

Um pouco além do básico...Na “vida real”, os programadores precisam mais do que simplesmente mapear pontos da imagem para vértices.Muitos parâmetros podem ser informados para favorecer a qualidade visual do mapeamento.Embora, ainda seja possível prever alguns problemas de mapeamento e embutir na textura as deformações necessárias para realizar um mapeamento ideal. É uma solução difícil e ainda assim pode necessitar de ajustes.OpenGL permite definir parâmetros de mapeamento, que influenciam a forma a textura será tratada após o mapeamento.

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 24

Texturas em OpenGL

Parâmetros em OpenGL:glTexParameterf(GLenum target, GLenum pname, GLfloat param);

Variantes: i, fv ou ivTarget: GL_TEXTURE_1D, _2D ou _3DPname é o nome do parâmetro.Param são os dados do parâmetro.

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 25

Texturas em OpenGL

Basic Filtering:Para um resultado interessante ou pelo menos bom, além do mapeamento, devemos fazer uso de alguns artefatos para melhor o resultado.Um problema comum é o que acontece quando a textura é esticada ou comprimida.Algum procedimento deve ser feito quando falta alguma informação ou quando há uma redução de pixels.O processo que trata deste problema é chamado de filtering. Ele é executado na magnificação e na minificação dos texels (magnification e minification). As constantes associadas são, respectivamente: GL_TEXTURE_MAG_FILTER e GL_TEXTURE_MIN_FILTER.

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 26

Texturas em OpenGL

Nearest Neighbor Filtering:Mais rápido e mais simplesQuanto falta algum cor, a cor do vizinho mais próximo é utilizada.Resultado é uma imagem “pixelized”

glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 27

Texturas em OpenGL

Linear Filtering:Mais complexo, melhor resultado e mais lento

Este é um problema considerado superado, pois o custo computacional se tornou desprezível com implementação em hardware.

A cor de um texel faltante é calculada pela média ponderada (interpolação linear) dos seus vizinhos.Resultado é caracterizado com “fuzzy” graphics; um resultado mais suavizado.

glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 28

Texturas em OpenGL

X

NEAREST LINEAR

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 29

Texturas em OpenGL

Textura com cartoons (cell-shading)Uso de textura 1D para desenhos animados.Preenchimento é feito com cor sólida e usando GL_NEAREST.A idéia básica é usar as normais da superfície e o vetor da luz para indicar qual é a cor de preenchimento dos pixels. Calculando o produto escalar.

Exemplo TOON do livro [3].

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 30

Texturas em OpenGL

Texture WrapO que fazer nas fronteiras da textura? Especialmente quando for necessário acessar um valor que estaria “fora” da textura? Pode-se repetir a textura ou simplesmente “cortar” nas bordas (repeat ou clamp).Deve ser indicado por dimensão da textura o procedimento a ser executado:

GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T e GL_TEXTURE_WRAP_R.

O modo GL_REPEAT, simplesmente repete a textura nas dimensões escolhidas. Bom para imagens tileble.

Influencia no filtering GL_LINEAR.O modo GL_CLAMP os pixels faltantes são obtidos da cor definida para a borda: GL_TEXTURE_BORDER_COLOR em glTexParameterfv(...).GL_CLAMP_TO_EDGE, obtém pixels faltantes repetindo os pixels das bordas.GL_CLAMP_TO_BORDER, pixels da última linha e última coluna são carregados como borda e valores são cortados até aquele ponto.

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 31

Texturas em OpenGL

Texture WrapRepeat: Textura é repetida

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)

Clamp: os valores são truncados (mantidos entre 0 e 1)glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP)

Podemos especificar uma cor de borda glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, R,G,B,A)

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 32

Texturas em OpenGL

Texture Wrap

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 33

Texturas em OpenGL

Exemplo imagem tileble:

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 34

Texturas em OpenGL

Algoritmos de síntese de texturas conseguem gerar texturas a partir de amostras de imagem.

Objetivo: gerar uma nova textura que contenha o mesmo padrão visual da amostra. Idealmente, a nova textura não deve parecer uma composição de tiles regulares.

Veremos mais sobre síntese de texturas

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 35

Mipmap

Problemas:Diferentes resoluções objeto podem parecer distorcidas por causa do tamanho da textura. Problema com a perspectivaTextura com informações prontas para o mapeamento em perspectiva consomem muita memória.

Solução:Mipmap – “multum in parvo” (Muitas coisas num mesmo lugar).A idéia é carregar muitas texturas de resoluções diferentes para atender cada a cada tamanho visualizado.Quando o objeto está próximo o maior nível é utilizado, quando o objeto está longe um nível menor (adequado) é calculado e utilizado para o mapeamento.

Suponha uma textura a ser mapeada e que seja deseja gerar todos os mipmappings possíveis de menor resolução (dividindo ao meio), qual é a quantidade de memória necessária para armazenar todos os mipmappings?

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 36

Mipmap

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 37

Mipmap

Os níveis de Mipmap são carregados com glTexImageAgora deve-se usar o parâmetro level.

Onde: primeiro nível é o zero, depois 1, 2, ...Parâmetros associados:

glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0)glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 4)glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0)glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 3)

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 38

Mipmap

Filtering com mipmapNearest ou LinearDuas etapas: primeiro o filtro de nível e depois o seletor de nível.

GL_FILTRO_MIPMAP_SELETORGL_NEAREST – executa nearest filtering sobre o primeiro nível do mipmap.

GL_LINEAR – executa filtering sobre primeiro nível do mipmap.GL_NEAREST_MIPMAP_NEAREST – executa nearest para o nível e entre vizinhos.GL_NEAREST_MIPMAP_LINEAR – executa nearest para o nível e linear entre vizinhosGL_LINEAR_MIPMAP_NEAREST – seleciona nearest nível e executa interpolação linear.GL_LINEAR_MIPMAP_LINEAR – seleciona e executa interpolação linear. Trilinear interpolation.

Mais indicado para jogos: GL_LINEAR_MIPMAP_NEARESTQualidade de filtragem da interpolação e agilidade na escolha do nível.

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 39

Mipmap

Geração “automática” de níveisAo invés de carregar todas as imagens de todos os nível é possível utilizar-se de duas soluções:

gluScaleImage() – gera uma versão escalada da imagemglBuild2DMipmaps() – cria versões escaladas de uma imagem e associa com o nível mipmap adequado:

int gluBuild2DMipmaps(GLenum target, GLint internalFormat, GLint width, GLint height, GLenum format, GLenum type, const void *data);

glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE) – gera uma versão escalada da imagem em hardware. A partir da versão 1.4 da OpenGL. A cada chamda a glTexImage() para o nível 0, os demais são computados automaticamente.

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 40

Mipmap

LOD BIASglTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -1.5)

Interfere no cálculo de escolha do nível de mipmap.

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 41

Objetos de textura

Até este ponto, vimos como definir uma textura e seus parâmetros no estado de textura do OpenGL.Algumas aplicações (jogos) requerem diversas texturas.Troca de estados com as funções glTexImage e glBuildMipmap a todo instante tornam o processo muito oneroso. No caso de jogos, proibitivo.Neste sentido, utiliza-se objetos de textura.

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 42

Objetos de textura

Primeiro passo consiste indicar uma quantidade de objetos de textura:glGenTexture(GLsizei n, GLuint *textures);n – é o tamanho do array de texturas*textures – é o array de identificadores.

Para trocar o estado de textura atual:glBindTexture(Glenum target, GLuint texture)target – GL_TEXTURE_1D, GL_TEXTURE_2D ou GL_TEXTURE_3Dtexture – é o identificador do objeto de textura.

Para remover objetos de textura:glDeleteTextures(GLsizei n, GLuint *textures);

Os dados relativos aos objetos de textura devem ser carregados na inicialização do programa e, cada etapa de redesenho, deve-se fazer a troca de estados entre os objetos, conforme a necessidade.

Ver exemplo TUNNEL do livro [3]. O exemplo demonstra o uso de mipmaps e mútiplas texturas

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 43

Objetos de texturaExemplo considerando várias texturas no modelo do OBJGeração de ids de texturas para todas as imagens lidas (uma para cada material):int *ids; Mesh *mesh = new Mesh;vector<Material> mats;int main(int argc, char **argv){ OBJReader reader; reader.open(“algumo.obj”, mesh, &mats); // descobrir quantos materiais tem textura (texCount)... ids = new int[texCount]; glGenTexture(texCount, ids); for pelos materiais if(mats[i].hasTexture()){ Image *img = mats[i].getTexture(); // associando id com textura mats[i]->setTextureId(ids[k++]); glBindTexture(GL_TEXTURE_2D, img->getId()); glTexImage2D(GL_TEXTURE_2D, GL_RGB, img->getWidth(), img->getHeight(), GL_RGB, GL_UNSIGNED_BYTE, img->getPixels()); free(img->getPixels()); // liberar memória! }

junto ao glBindTexture passar também outros parâmetros relacionados a textura.

Modificar de acordo com o tipo de dados do vetor de pixels da classe Image

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 44

Objetos de textura

Resolvendo o mapeamento na hora do desenho:for dos grupos GLuint tid = grupos[i]->getMaterial()->getTextureId(); glBindTexture(GL_TEXTURE_2D, textures[tid]); glBegin(GL_TRIANGLES); // ou a primitiva mais adequada for das faces do grupo Face *f = grupo->getFace(j); float *vt = mesh->getTextCoord(f->getTextCoord()); Vertex *v = mesh->getVertex(f->getVertex()); glTexCoord2f(vt[0], vt[1]); glVertex3f(v[0], v[1], v[2]); glEnd();

Ver exemplo TUNNEL do livro [3]. O exemplo demonstra o uso de mipmaps e mútiplas texturas

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 45

Textura Residentes

As texturas utilizadas no mapeamento são carregadas para uma área de memória de alta performance de textura, no hardware gráfico.OpenGL faz uso desta área de memória sempre que uma textura tem que ser renderizada.Entretanto, esta é uma área de memória com limite de tamanho. O OpenGL substitui as texturas conforme a necessidade.É possível, contudo, determinar quais texturas devem ficar residentes:

GLboolean glAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences);Aquelas texturas que estão definidas como GL_TRUE, ficarão nesta área de memória.

O OpenGL utiliza algoritmo MFU (most frequently used) para definir quem permanece residente na área de textura. Também é possível definir prioridades para as texturas e, desta forma, interferir no algoritmo e deixar alguma textura específica:

void glPrioritizeTextures(GLsizei n, const GLunit *textures, const GLclampf *priorities);

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 46

Texturas em OpenGL

Outros aspectos a serem estudados:Uso do color bufferAtualização de partes da textura, com glTexSubImageMatriz de texturas, que permite transformações sobre a textura (translação, escala e rotação), e que inclusive são aplicadas a parte do mapeamento.Filtragem de textura anisotrópica prove qualidade superior na filtragem.Adicionar efeitos de especularCompressão de texturas

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 47

Texturas em OpenGL

Mapeamento de texturas mais avançado:Síntese de texturas procedurais e baseado em imagemEnvironment mapping – iluminação armazenada em um mapa de texturas

Simula reflexão de superfícies brilhantes/metálicasBump-mapping altera a normal da superfície

Geometria fica mais simples, mas o contorno do objeto pode parecer estranho

Displacement mapping adiciona um deslocamento a cada ponto da superficie

Gemoetria também fica mais simplesNormal mapping

Similar ao bump-mapping, mas neste caso temos uma “textura” de normais

quarta-feira, 26 de setembro de 12

04/12/2011 Leandro Tonietto 48

Referências bibliográficas

1. Slides sobre CG dos professores: Christian Hofsetz, Cristiano Franco, Marcelo Walter e Soraia Musse.

2. FOLEY!!3. WRIGHT Jr., Richard S; LIPCHAK,

Benjamin; HAEMEL, Nicholas. OpenGL Superbible: Comprehenive Tutorial and Reference. 4 ed. Addison-Wesley, 2007.

quarta-feira, 26 de setembro de 12