Como Fazer um Programa, simples, em OpenGL para Trabalhar com Iluminação (exemplo do site da Isabel Mansour) 1) Crie um Programa Simples que desenhe qualquer sólido na Tela. Há um exemplo Há Novo na Página da Disciplina, com o nome OpenBásico-I. Este programa serve também como Partida Inicial para àqueles que ainda têm dúvidas de como começar um programa em OpenGL. 2) Crie uma Função chamada Iluminação e Ponha ela em qualquer lugar antes da main. As explicações são dadas a seguir: A estrutura do código para iluminação de uma cena, que pode ficar inteiramente dentro de uma única função de Iluminação, em OpenGL possui as seguintes módulos (partes): (1) Definição das Estruturas de Dados para os Tipos de Luz, Posição da Luz e Tipo de Brilho (5)Faça as habilitações (2) Definição da Cor de Fundo e como será o sombreamento nos objetos da cena. necessárias, incluindo uso de iluminação, número da Luz, e se vai querer o uso do Z-Buffer. (3)Definição das reflectâncias (4)Define Parâmetros para cada dos Materiais e Ativar os Tipos de Luzes que prefere. Luz de 0 a 7 A explicação de cada bloco é dada a seguir: (1) Exemplo: GLfloat GLfloat GLfloat GLfloat luzAmbiente[4]={0.2,0.2,0.2,1.0}; luzDifusa[4]={0.7,0.7,0.7,1.0}; // "cor" luzEspecular[4]={1.0, 1.0, 1.0, 1.0};// "brilho" posicaoLuz[4]={0.0, 50.0, 50.0, 1.0}; Aqui, foram definidos três tipos de iluminação: ambiente, difusa e especular. Cada uma é um vetor R, G, B, A; ou seja, a luz que será utilizada de cada um desses tipos é uma combinação RGB. Note que a luz ambiente foi definida como sendo R = G = B = 0.2, para simular uma luz ambiente cinzenta, bem fraquinha. O Alfa, A = 1.0, significa que não há fog. A posição onde ficará essa luz está no vetor posicaoLuz, e representa um ponto no espaço tridimensional (x, y, z). Despreze o quarto valor. GLfloat especularidade[4]={1.0,1.0,1.0,1.0}; GLint especMaterial = 60; Aqui, o primeiro vetor define o quanto especular será o material renderizado. Lembre que uma reflexão especular é aquela que inside em um ponto e se espalha em uma única direção. Ao contrário da difusa que se espalha em todas as direções. Portanto, uma reflexão especular depende da posição do observador. Uma vez que a reflexão é 3D (uma para cada direção), somente os três primeiros valores são considerados. Finalmente, a intensidade da reflexão do material é definida por especMaterial, nesse caso, 60. (2) Exemplo: // Especifica que a cor de fundo da janela será preta glClearColor(0.0f, 0.0f, 0.0f, 1.0f); Aqui, essa função define de que cor será o fundo da cena. // Habilita o modelo de colorização de Gouraud glShadeModel(GL_SMOOTH); Essa função é interessante. Ela define como você quer que a luz se espalhe sobre o material. Por exemplo, lembre-se que os objetos renderizados são malhas triangulares. Então, cada triângulo possui a sua cor. De acordo com o ângulo de incidência da luz, ela pode insidir somente parte (se insidir inclinada) ou toda (se insidir 90 draus). Então, se o objeto for redondo, a luz vinda de um ponto, inside com diferentes intensidades em cada ponto do objeto, uma vez que o ângulo que o atinge varia. Mas, de acordo com a teoria vista em sala, existem 2 maneiras de simular essa incidência: Gouhaud e Phong. Em OpenGL, GL_SMOOTH é o modelo de Gouhaud. Mas, se quiser que nào haja nenhum desses efeitos, e que simplesmente cada ponto de cada triângulo dependa somente da direção e intensidade da luz incidente, use GL_FLAT. Faça o teste com os dois e veja a diferença. (3) Exemplo // Define a refletância do material glMaterialfv(GL_FRONT,GL_SPECULAR, especularidade); // Define a concentração do brilho glMateriali(GL_FRONT,GL_SHININESS,especMaterial); No item (1) foram definidos os valores de iluminação e reflectância que serão usados. Aqui, eles são definidos explicitamente, através da função glMaterial. O argumento GL_FONT diz para renderizar somente as partes frontais. GL_BACK diz para renderizar as partes internar (objeto vazado, por exemplo). Se quiser renderizar tudo, faça GL_FONT_BACK. O segundo argumento, informa que a reflectância da matarial é em uma única direção, como um espelho, por exemplo. Por isso é usado o argumento GL_SPECULAR e depois GL_SHININESS. Finalmente, o argumento especularidade é o vetor definido em (1) e especMaterial é a variável definida também em (1). (4) Exemplo: glLightfv(GL_LIGHT0, glLightfv(GL_LIGHT0, glLightfv(GL_LIGHT0, glLightfv(GL_LIGHT0, GL_AMBIENT, luzAmbiente); GL_DIFFUSE, luzDifusa ); GL_SPECULAR, luzEspecular ); GL_POSITION, posicaoLuz ); Aqui, finalmente definimos quantos spots de luz iremos usar. Em OPenGL, podese usar até 8, GL_LIGHT0 a GL_LIGHT7. A função glLightfv define os parâmetros de cada spot. O primeiro argumento é o próprio spot usado, o segundo é que tipo de luz será usado e o terceiro é o vetor de luz correspondente, definida em (1). Assi, as três primeiras chamadas da função glLightfv define que o spot LIGHT0 será uma mistura de luz ambiente, difusa e especular (uma salada que deixa realista). Embora a difusa e a especular sejam antagônicas, é interessante ver esse efeito misturado. A quarta chamada da função glLightfv diz apenas que o spot de Luz GL_LIGHT0 ficará na posição indicada pelo vetor posicaoluz, definido em (1). (5) Exemplo: glEnable(GL_COLOR_MATERIAL); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); Uma vez todas as luzes tenham sido definidas, ainda temos que habilitar. Isso é para que possamos ter vários tipos de spots de luz que podemos controlar habilitando e desabilitando rapidamente. Assim, chamamos 4 vezes a função glEnable com o argumento correspondente: (a) GL_COLOR_MATERIAL: Habilita a definição da cor do material a partir da cor corrente (b) GL_LIGHTING: Habilita o uso de iluminação (c) GL_LIGHT0: Habilita o uso de iluminação A última habilitação glEnable(GL_DEPTH_TEST) permite finalmente habilitar a técnica do Z-Buffer. EXERCÍCIOS (1) Que efeito acontece se compararmos os sombreamentos de Guhaud e Flat? (2) Modifique a posição da Luz de frontal, como está sugerindo no vetor posição luz, para lateral e descreva sucintamente o efeito que gerou. (3) Use 2 spots de luz, um voltado para a alça do Tepot e outro voltado para o bico, produzindo os efeitos a seguir para spots em posições infinitas e finitas: