Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL
Universidade Federal de Minas Gerais
Programa de Aprimoramento Discente em Modelagem Geomtrica Computacional
Curso Bsico de OpenGL
Dezembro 2003 Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL
Universidade Federal de Minas Gerais Av. Antnio Carlos, 6627 Pampulha 31.270-901 Belo Horizonte MG Brasil
Curso Bsico de OpenGL
Apostila criada como complemento do Curso Bsico de OpenGL, oferecido pelo PAD Modelagem Geomtrica Computacional, apoiado pela PROGRAD e pelo Departamento de Matemtica - UFMG.
Componentes PAD Modelagem Geomtrica Computacional:
Pedro Israel Samuel Andrade Wlamir Belchior psisrael@hotmail.com alemaost@uol.com.br wlamirm@yahoo.com.br
Orientadores:
Ricardo Takahashi Departamento de Matemtica Denise Burgarelli Departamento de Matemtica Rodney Biezuner Departamento de Matemtica Rodrigo Carceroni Departamento de Cincia da Computao Renato Mesquita Departamento Engenharia Eltrica
Dezembro 2003 Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL
Introduo Sobre a apostila Sobre a OpenGL
Captulo 1 Criando uma janela e um volume de visualizao 1.0 - Criando uma janela passo-a-passo 1.1 - Definindo um volume de visualizao 1.2 Redimensionamento de Janelas
Captulo 2 Modelagem Geomtrica 2D e 3D 2.0 - Desenhando primitivas da OpenGL 2.1 - Colorao 2.2 - Transformaes geomtricas 2.3 - Desenhando primitivas da GLUT 2.4 - Removendo superfcies escondidas 2.5 - Criando objetos transparentes 2.6 - Criando Hierarquias de Transformaes
Captulo 3 Interao e Animao 3.0 - Interao atravs do teclado 3.1 - Interao atravs do mouse 3.2 - Animao
Captulo 4 Uso de Iluminao 4.0 - Habilitando o uso de iluminao 4.1 - Definindo propriedades
Captulo 5 Tpicos bsicos sobre aplicao de textura 5.0 Compreendendo a aplicao de textura 5.1 Aspectos tericos bsicos 5.2 Aspectos prticos bsicos
Captulo 6 Tpicos bsicos sobre fractais 6.0 - Introduo 6.1 - Implementao de figuras auto-semelhantes 6.2 - Adio de adereos ao fractal 6.3 - Usando nmeros aleatrios 6.4 - Consideraes finais
Apndice I - A linguagem C II - Como instalar a OpenGL no Dev C/C++ III - Guia para consultas rpidas (funes mais utilizadas) IV - Seleo de Sites
Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL Introduo
Sobre a apostila
Esta apostila foi desenvolvida pelo grupo de estudos sobre modelagem geomtrica computacional, apoiado pela UFMG atravs do programa PAD (Programa de Aprimoramento Discente), como um complemento para o curso oferecido durante a Semana do Conhecimento. O objetivo deste trabalho capacitar pessoas com um pequeno conhecimento prvio em programao a, em poucos dias, desenvolver programas simples de computao grfica, utilizando a biblioteca OpenGL. Devido ao tempo curto proposto para aprendizagem, no ser dada nfase teoria envolvida nos processos de modelagem. Em vez disso, o tempo ser integralmente concentrado na parte prtica dos mesmos. Ao longo da apostila, sero apresentados programas-exemplos ou passagens destes que usam a teoria explicada, alm de propostas de exerccios utilizando-os. Estes programas podem ser encontrados no CD-ROM disponvel junto com esta apostila ou pelo site do grupo. Os exerccios propostos devem ser feitos medida em que forem solicitados pelo palestrante; e qualquer eventual dvida deve ser enviada para cursodeopenglufmg@yahoogrupos.com.br. O e-mail ser respondido o mais breve possvel. No se esquea de antes se inscrever na lista, mandando um e-mail para cursodeopenglufmg-subscribe@yahoogrupos.com.br. Este material divide-se em cinco captulos subdivididos em tpicos. No primeiro captulo ser dada a base para a criao de uma janela e um volume (ou plano) de visualizao adequado. Estes passos so extremamente importantes, pois formam os pilares para a construo de qualquer programa utilizando o OpenGL. O captulo dois compreende o assunto de maior nfase dado na apostila: a modelagem geomtrica. Aps seu estudo, o leitor deve ser capaz de modelar objetos 2D e 3D, tais como pontos, retas, planos, tringulos, esferas, cubos, paraleleppedos, dentre outros. E ainda: utilizando estes objetos bsicos e aproveitando as ferramentas que permitem a realizao de transformaes geomtricas e hierarquia de transformaes, o leitor estar apto a representar praticamente qualquer cena desejada, tal como uma casa, um carro ou at mesmo estruturas mais complexas como um rob. A parte de interao usurio-programa, utilizando a OpenGL e suas bibliotecas auxiliares, extremamente simplificada, e o captulo trs se encarrega de fornecer informaes para tal. Alm disso, ser explicada uma forma simples de fazer animao sem depender de nenhum tipo de interao. O captulo quatro trata de um recurso utilizado para otimizar o realismo de qualquer cena: a iluminao. Este assunto de constante pesquisa entre programadores do mundo inteiro e, de fato, apresenta-se como um diferencial entre os trabalhos de computao grfica. Ele o ltimo captulo sobre tpicos utilizando a OpenGL e a sua leitura dever ser suficiente para criar uma iluminao simples em qualquer cena. Os apndices fornecem suporte para o aprendizado: uma introduo linguagem C, um guia de como instalar a OpenGL no Dev C++, uma seleo dos melhores sites de OpenGL encontrados na web (muito importante para quem pretende se aprofundar no assunto), um guia para consultas rpidas sobre as funes mais utilizadas da OpenGL, GLUT e GLU.
Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL Sobre a OpenGL
A OpenGL (Open Graphics Library) foi desenvolvida em 1992 pela Silicon Graphics, maior empresa de computao grfica e animao em todo o mundo. Por ser uma ferramenta portvel e rpida, amplamente utilizada na construo de jogos eletrnicos, tal como Counter Strike, Quake, dentre outros. importante no confundir: OpenGL no uma linguagem de programao, e sim uma eficiente API (Aplication Programming Interface). Quando se diz que um programa escrito em OpenGL significa que so feitas uma ou mais chamadas s suas funes. A OpenGL considerada uma ferramenta relativamente simples, j que, para se alcanar a aparncia desejada, preciso apenas determinar os passos que devem ser feitos para tal finalidade, poupando assim bastante tempo na construo de qualquer programa. Para isso, so oferecidas vrias primitivas de baixo nvel, sistemas de iluminao, colorao, textura e diversos outros recursos. J o sistema de gerenciamento de janelas, em nossa apostila, ser feito pela biblioteca GLUT (OpenGL Utility Toolkit). Alm disso, outra biblioteca ser tambm incorporada aos nossos programas: a GLU (OpenGL Utility library) por nos fornecer vrias funes auxiliares, principalmente primitivas grficas como superfcies qudricas e Splines. Devido s funcionalidades providas pela OpenGL, esta API tem se tornado um padro largamente utilizado em diversos setores. Possuir rotinas estveis, boa documentao disponvel e ser de fcil aprendizado s ajudou a concretizar este fato. A maioria das implementaes, em OpenGL, segue uma ordem de operaes chamada OpenGL Pipeline. Apesar de no ser uma regra de como a OpenGL implementada, o Pipeline fornece um guia para entender melhor como e quando a OpenGL realiza suas operaes. Talvez no fique claro, de princpio, o conceito de Pipeline, muito menos sua aplicao, mas medida em que as lies forem sendo lecionadas, ser interessante consult-lo. Abaixo, um esquema muito simples e didtico do Pipeline da OpenGL:
As funes OpenGL seguem um padro em relao s suas notaes. De forma geral, podemos esquematizar da seguinte maneira:
gl {nome da funo}{nmero de variveis}{tipo de variveis}{forma vetorial}(arg 1, arg 2 ...., arg n);
Nem todas as funes seguem exatamente esse formato. Por exemplo, funes que no recebem parmetros, como "glFlush()", ou que s podem receber um tipo, como "glClearColor()", no possuem nenhum tipo de referncia aos argumentos.
Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL Exemplos: gl Color 3 f => Color o nome da funo, 3 o nmero de variveis passadas para a funo e f o tipo de varivel gl Light fv => Light o nome da funo e fv o tipo de varivel (float vector)
A OpenGL funciona como uma mquina de estado, ou seja, uma parte da memria reservada para guardar o estado atual das diversas variveis envolvidas no processo de renderizao. Ento, ao se desenhar algo, todos esses valores armazenados na memria so usados para sua representao na tela, ou seja, primeiro necessrio fornecer todas as caractersticas do objeto para s depois desenh-lo. Isto no muito intuitivo de incio, mas sua praticidade se torna evidente em pouco tempo.
Exemplo: Caso voc queira desenhar um quadrado azul rotacionado de 45 graus, primeiro necessrio especificar a cor, depois rotacion-lo (ou vice-versa, neste caso a ordem dessas alteraes no importa) e somente depois desenh-lo efetivamente.
Capitulo 1 - Criando uma janela e um volume de visualizao
1.0 Criando uma Janela
Para o processo de criao de janela, utilizamos a biblioteca GLUT, como j foi dito anteriormente. A seguir, ser apresentado um trecho, usado para criar a janela, que foi retirado do primeiro programa exemplo:
Obs.: Vale lembrar que o GLUT oferece ferramentas extremamente simples e portveis para a criao de janelas. Para um trabalho mais detalhado e completo, recomenda-se o uso de outras bibliotecas ou at mesmo o processo de criao de janelas do prprio sistema operacional.
A janela dever ser apresentada da seguinte forma: Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL
Comandos apresentados:
glutInit(&argc, argv): inicializa o GLUT. Esta chamada tem que vir antes de qualquer outra da biblioteca GLUT. glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB): determina o sistema de display: o argumento GLUT_SINGLE significa que estamos usando um buffer simples (buffer duplo pode ser usado para uma animao, por exemplo, como veremos mais na frente) e GLUT_RGB siginifica que o sistema de cores ser dado pelo sistema RGB (Fraes de Vermelho, Verde e Azul, respectivamente). glutInitWindowSize(450, 450) e glutInitWindowPosition(50, 50): dizemos que nossa janela ter um tamanho de x=450 e y=450 (comprimento e altura, respectivamente, em pixel) e estar na posio x=50 e y=50, onde o (0,0) o canto superior esquerdo da tela. glutCreateWindow("Primitivas OpenGl"): cria uma janela efetivamente com o ttulo "Primitivas OpenGL". Perceba que primeiro demos todas as coordenadas da janela para s depois cri-la. Isto porque, como j vimos antes, a OpenGL uma mquina de estado. No preocupe com os outros comandos ainda. Por enquanto, saber como criar uma janela um passo bem grande. Mas, apenas essas funes no so suficientes para se criar uma janela. Perceba que criamos uma funo INIT(). Nela existe a funo glClearColor (vermelho, verde, azul, alpha): na qual se define a cor de fundo da janela. importante saber que estes parmetros devem variar de zero a um e que tal funo apenas define a cor de preenchimento e no executa tal. Em seguida temos a funo glutDisplayFunc(funo): responsvel por chamar a funo DISPLAY(void) a cada vez que o estado da cena alterado. Caso voc no se recorde da noo de estado, aconselhvel retornar seo anterior. na funo DISPLAY(void) que esto contidas as informaes necessrias a respeito da cena e do desenho que ser feito na janela criada. Como explicamos anteriormente, em OpenGL usamos matrizes para operar sobre nossa cena. Sendo assim, devemos sempre definir em qual matriz estamos trabalhando e, para isso, existe a funo glMatrixMode(nome da matriz). Em nosso caso, estamos trabalhando com a GL_PROJECTION, que est relacionada com tudo aquilo que diz respeito ao volume de visualizao, e a matriz MODEL_VIEW, que est relacionada com o desenho em si. Muitas vezes, quando selecionamos uma matriz, necessrio que a multipliquemos pela matriz identidade. O efeito disso como se estivssemos simplesmente anulando toda a matriz. Isso ficar mais claro em captulos posteriores. Para usar a matriz identidade, basta chamar a funo glLoadIdentity(). Note que, quando estamos operando sobre a matriz de projeo, definimos nosso volume de visualizao usando a funo glOrtho(parmetros). Os valores destes parmetros Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL so os da posio de planos em relao origem absoluta do sistema. Tudo aquilo que for desenhado fora deste volume no ser exibido na tela; portanto, requerida ateno ao se passar valores ao programa. Em seguida, temos a funo glClear (parmetros), que responsvel por limpar o fundo da janela. Para tal, necessrio tambm que o parmetro assuma o valor de GL_CLEAR_BIT. A ltima funo a ser vista nesta seo a glutMainLoop(). Ela responsvel por manter todas as funes da GLUT ativas para qualquer mudana de estado ocorrida no sistema. Ou seja, ela quem gerencia os loops do nosso programa. No deixe de consultar o apndice de cores ao final desta apostila. Nele, voc encontrar vrias combinaes de nmeros que geram diferentes cores.
A funo glMatrixMode() define qual matriz ser alterada da pra frente. Se o argumento passado for GL_PROJECTION, os prximos comandos iro alterar a matriz de projeo. Se for GL_MODELVIEW, iro alterar a matriz de modelamento e viso. Todos os programas daqui para frente faro alteraes nessas duas matrizes.
Obs.: SEMPRE desenhe e posicione a cmera na MODELVIEW e SEMPRE defina o volume de visualizao na PROJECTION. Assim, vrios erros so evitados. Ainda existe uma outra matriz, a GL_TEXTURE, mas no ser vista nesse curso.
O glLoadIdentity() serve para transformar a atual pilha de matrizes em identidade. Isso tambm evita alguns erros indesejveis, se colocado logo aps o comando glMatrixMode(). O volume de visualizao definido logo aps as especificaes da janela. Ele definir tudo que ir aparecer na tela e como iro aparecer. Essas duas caractersticas nos do motivos de sobra para dar ateno redobrada a essa parte. Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL H quatro funes para especificar esse volume, duas da glu e duas da opengl:
*glOrtho(esquerda, direita, baixo, cima, perto, longe): define um volume ortogonal, ou seja, um paraleleppedo. Tudo que estiver fora desse slido no ser renderizado. No h nenhum tipo de perspectiva em profundidade (os objetos no aparentam menores medida em que se afastam do observador). Este tipo de visualizao bastante utilizada em projetos arquitetnicos e outras aplicaes nas quais a medida real do objeto seja mais importante que uma visualizao mais realstica.
*glFrustum(esquerda, direita, baixo, cima, perto, longe): define um volume na forma de um tronco de pirmide. Isto permite uma visualizao diferente, possibilitando noo de profundidade. Os parmetros so idnticos ao do glOrtho, exceto que os quatro primeiro se referem ao plano mais perto do observador (note que os planos "perto" e "longe" nesse caso so diferentes).
*gluPerspective(ngulo,distoro, perto, longe): cria um tronco de pirmide, exatamente como glFrustum. A diferena so os parmetros: nessa funo, o primeiro parmetro o ngulo do vrtice da pirmide. Sendo assim, quanto maior o valor, maior o campo de viso (o ser humano tem um ngulo de viso igual a 46 graus. Mais do que isso, somente com a ajuda de lentes chamadas de "grande angular", enquanto valores menores so obtidos com lentes chamadas "teleobjetivas"). O segundo parmetro define a razo largura/altura da pirmide. Para no distorcer a sua imagem, coloque esse valor sempre igual a 1. Os outros dois parmetros so os mesmos das outras funes anteriores. Apesar de parecer mais complicado, esse comando mais simples que o glFrustum e por esse motivo ser utilizado em todos os programas em que for desejado uma projeo em perspectiva.
*gluOrtho2D (esquerda, direita, baixo, cima): por ltimo, esse comando cria um plano ao invs de um volume de visualizao. Note que s necessrio passar coordenadas bidimensionais para a funo. Se um programa no gerar imagens tridimensionais, essa a melhor maneira de se especificar onde ser renderizada a cena. Por esse motivo, a grande maioria dos programas daqui pra frente usar esse comando.
Outro ponto importante a ser definido em um programa onde a "cmera" estar e para onde ela estar apontando. Isso pode ser feito atravs do comando:
Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL
Para uma demonstrao simples, no programa exemplo est o comando glOrtho e o gluPerspective definindo de formas diferentes o volume de visualizao para o desenho da frente de um cubo. Descomente as linhas de forma a ver o efeito que cada volume produz. Mude tambm os parmetros de gluLookAt como exerccio.
Obs.: um cubo, ao ser visto de frente, sem deformao devido distncia, seria visualizado de que forma? E com a deformao? Verifique os resultados atravs do programa exemplo.
1.2 Redimensionamento de Janelas
Imagine duas situaes: revelar uma foto num filme 3 por 4 e num filme 3 por 6. O resultado ter, na segunda situao, uma foto alongada em um dos eixos por uma escala 6/4. Situao parecida acontece quando redimensionamos a janela em que estamos trabalhando: analogamente, nosso filme foi redimensionado tambm. Para evitar tais distores, a funo glutReshapeFunc(Redimensiona) utilizada. Ela avisa ao programa que, ao ser realizada qualquer alterao na janela criada pela GLUT, a funo Redimensiona() ser chamada. Esta funo tem que, necessariamente, receber dois inteiros: largura e altura da nova configurao da tela, respectivamente. A funo abaixo usada para ajustar o volume de visualizao quando a tela redimensionada.
void Redimensiona(int x, int y) { if (y==0)y=1; glViewport(0,0,x,y); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (x>=y) gluOrtho2D(1*(float)x/y,4*(float)x/y,1,4); else gluOrtho2D(1,4,1*(float)y/x,4*(float)y/x); }
Para evitar a distoro das imagens quando aumentamos, por exemplo, o comprimento da janela, devemos provocar uma distoro igual no nosso volume (ou plano) de visualizao. Veja bem as ltimas linhas da funo abaixo:
se x>=y (comprimento for aumentado), provocada uma deformao no volume de visualizao de x/y no seu comprimento. se y<x, a deformao de y/x na altura.
Ex.: Suponha que temos um quadrado de lado unitrio dentro de uma janela de tamanho 2 por 2. Ento, redimensionamos a tela para um tamanho 4*2. Se no tiver nenhuma funo para Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL controlar alteraes na janela, o quadrado se torna um retngulo com o comprimento igual a 4. Mas, se usarmos a funo acima, provocamos uma distoro no volume de visualizao igual a no quadrado, ficando nosso volume com o comprimento igual ao dobro do anterior. Resultado: nenhuma distoro no desenho percebida. A funo glViewport () define onde, na tela, ser renderizada a imagem. como se voc, aps preparar a cmera, escolher o alvo e tirar a foto, fosse escolher qual o tamanho da foto que voc quer. Os parmetros so: as coordenadas do canto inferior esquerdo da tela e as coordenadas do canto superior direito.
Se nenhuma funo de redimensionamento for chamada, o "default" da GLUT ajustar apenas o glViewport.
Obs.: Perceba que no precisamos especificar nosso volume de visualizao na funo Desenha(). Apenas na Redimensiona() suficiente.
Captulo 2 Modelagem Geomtrica 2D e 3D
2.0 Desenhando primitivas do OpenGL
A biblioteca OpenGL capaz apenas de desenhar figuras simples, tais como linhas retas, pontos e polgonos convexos. Essas figuras so denominadas primitivas e, atravs delas, podemos montar formas mais complicadas, como uma pirmide. Para desenharmos uma primitiva, necessitaremos basicamente de quatro comandos. Logo abaixo, vemos como eles devem ser dispostos no cdigo:
Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL glBegin(parmetros); glColor3ub(parmetros); glVertex3f(parmetros); glEnd();
A funo glVertex3f() responsvel por receber quais os vrtices que iro delimitar as primitivas. Sua sintaxe simples, glVertex3f (coordenada x, coordenada y, coordenada z). A funo glColor3ub o seletor de cores do sistema de desenho. Em seguida, temos os comandos glBegin() e glEnd(), que sempre trabalham em pares. Por exemplo, temos as seguintes linhas de cdigos:
Tudo o que houver entres eles ser desenhado na janela criada, conforme o parmetro passado para a funo glBegin(). O que queremos dizer que ser esse parmetro que ir definir quais tipos de primitivas que sero desenhadas.Tal parmetro pode assumir os seguintes valores: GL_POINTS, GL_LINES , GL_LINE_LOOP , GL_LINE_STRIP, GL_QUADS, GL_QUAD_LOOP, GL_QUAD_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_POLYGON. Segue-se uma breve descrio de cada uma das primitivas.
GL_POINTS: Cada vrtice tratado como um ponto. O ensimo vrtice define o ensimo ponto. N pontos so desenhados.
GL_LINES: Cada par de vrtices gera um segmento de linha independente. Vrtices 2n-1 e 2n definem o segmento de linha n. N/2 linhas so desenhadas.
GL_LINE_STRIP: Desenha um grupo de segmentos de linhas conectados do primeiro ao ltimo vrtice. Vrtices n e n+1 definem linha n. N-1 linhas so desenhadas.
GL_LINE_LOOP: Desenha um grupo de segmentos de linhas conectados do primeiro ao ltimo vrtice, voltando ento ao primeiro. Vrtices n e n+1 definem linha n. A ltima linha, no entanto, definida pelos vrtices N e 1. N linhas so desenhadas.
GL_TRIANGLES: Cada trio de vrtices gera um tringulo independente. Vrtices 3n-2, 3n-1 e 3n definem o tringulo n. N/3 tringulos so desenhados.
GL_TRIANGLE_STRIP: Desenha um grupo de tringulos conectados. Um tringulo desenhado para cada vrtice definido depois dos dois primeiros. Vrtices n, n+1 e n+2 delimitam o tringulo n. N-2 tringulos so desenhados.
GL_TRIANGLE_FAN: Desenha um grupo de tringulos conectados. Um tringulo desenhado para cada vrtice definido depois dos dois primeiros. Vrtices 1, n+1 e n+2 definem tringulo n. N-2 tringulos so desenhados. Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL
GL_QUADS: Cada grupo de quatro vrtices tratado como um quadriltero independente. Vrtices 4n-3, 4n-2, 4n-1 e 4n definem o quadriltero n. N/4 quadrilteros so desenhados.
GL_QUAD_STRIP: Desenha um grupo de quadrilteros conectados. Um quadriltero definido para cada par de vrtices definido aps o primeiro par. Vrtices 2n-1, 2n, 2n+2 e 2n+1 definem o quadriltero n. N/2-1 quadrilteros so desenhados. Note que a ordem dos pontos utilizada para construir o quadriltero diferente da funo anterior.
GL_POLYGON: Desenha um simples polgono convexo. Todos os vrtices so usados para represent-lo.
Obs.: Para definir o tamanho do ponto a ser desenhado, utilize a funo glPointSize(int tamanho) e para escolher a espessura da reta, use glLineWidth(int tamanho). Esses dois valores so dados em pixels.
2.1 - Colorao
Quando estamos trabalhando com a OpenGL desejvel atribuirmos diferentes cores para os objetos que estamos desenhando. Para tal, temos a funo glColor3ub (vermelho, verde, azul), como j observado anteriormente. Estes parmetros so valores inteiros que podem variar de 0 a 255 e, de acordo com a combinao de valores, obteremos uma cor diferente. Uma forma de se visualizar a combinao dos nmeros seria a de se usar a palheta de cores disponveis no Windows e no Linux. Alm de definir a cor, temos tambm que escolher os tipos de efeitos de preenchimento, utilizando a funo glShadeModel(parmetro). Eles se referem ao modo de preenchimento do desenho, com a cor que voc determinou. Temos basicamente dois tipos de preenchimento: o flat e o smooth. O preenchimento flat ir colorir o objeto com a cor corrente, enquanto o smooth ir fazer um interpolao (degrad) de cores que esto associadas a cada vrtice do objeto. Observe o cdigo abaixo:
} Estamos desenhando um quadrado e para cada um dos vrtices estamos determinando uma cor diferente. Como definimos, na funo INIT(), que o sistema de preenchimento era smooth, teremos um quadrado degrad na janela. Caso fosse desejado obter um quadrado com apenas uma cor, bastava retirarmos todos glColor3ub, excetuando o primeiro.
Logo abaixo, segue uma tabela com algumas combinaes numricas para a obteno de cores.
A maioria dos programas que se encontram em outros materiais, utilizam o comando glColor3f. Definir o tipo de argumento como "f" ao invs de "ub" faz com que a escala de cores varie entre 0 e 1, ao contrrio de 0 a 255. Escolhemos esse ltimo por ser mais freqente em paleta de cores.
2.2- Transformaes Geomtricas
Voc deve ter encontrado alguma dificuldade no exerccio 2 do captulo anterior. Isso porque, at o momento, estamos trabalhando sem a utilizao de transformaes geomtricas. Quando estamos gerando uma cena, necessrio dispor os objetos que a compem de uma forma bem definida. Utilizando as transformaes geomtricas, podemos posicion-los e orient-los de forma precisa. Basicamente, temos trs transfomaes geomtricas pr-definidas na OpenGL: translao, rotao e escala. Para ficar bem claro a importncia disso, analisemos a seguinte situao: no exerccio anterior de nmero dois, foi pedido o desenho de um losango eqiltero. Mas o que vem a ser um losango eqiltero? um quadrado rotacionado de um ngulo de quarenta e cinco graus. No mdulo em que so tratadas as transformaes, temos exatamente essa situao, porm, usamos uma transformao de rotao para simplificar nosso trabalho. Analisemos ento.
Recordemos o conceito de mquina de estado: necessrio darmos as condies nas quais o desenho ser feito. Por isso, aplicamos a rotao de quarenta e cinco graus no sistema, antes de realizar o desenho do quadrado. A funo que promove a rotao do sistema coordenado em um ngulo qualquer glRotatef(ngulo, componente x, componente y, componente z), onde "ngulo" o valor, em graus, a ser rotacionado em torno de um vetor definido por componente x, componente y e componente z. A figura a seguir demonstra o efeito de rotacionarmos o sistema de coordenadas em torno do eixo z.
A funo que realiza a translao glTranslatef(posio x, posio y, posio z). A origem do sistema ser transladada para a posio fornecida como parmetro para glTranslatef. Observe a figura abaixo:
Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL
Por fim, temos a funo glScalef(fator x, fator y, fator z), que altera a escala dos eixos conforme o fator multiplicativo fornecido. O resultado o de encolhimento ou de alongamento das figuras no sentido do(s) eixo(s). Note que, se alguns dos parmetros for 0, estaremos simplesmente eliminando essa coordenada.
Obs.: Um erro bastante comum considerar que todas as transformaes geomtricas so comutativas. Estudando as transformaes disponveis na OpenGL, chegamos seguinte concluso:
Rotao / Translao: no comutativa Rotao / Escala: comutativa Escala / Translao: no comutativa
Abaixo, um pequeno exemplo mostrando translao/rotao e rotao/translao:
Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL
Exerccios
1- Execute as tarefas descritas no mdulo de transformaes geomtricas. 2- Faa o seguinte desenho: viso superior de um avio qualquer usando as primitivas e as transformaes.
2.3 Desenhando primitivas da GLUT
A biblioteca GLUT capaz de realizar diversas tarefas; dentre elas, desenhar certos tipos de figuras mais complexas, em trs dimenses, e que denominamos primitivas da GLUT. O mdulo de primitivas da GLUT contm um cdigo exemplo em que ilustramos algumas dessas primitivas. Vamos analisar algumas primitivas mais teis. Basicamente, para cada primitiva temos duas variantes: a primeira, em que o resultado um objeto representado em forma de uma malha de linha (wire); e a segunda, em que o objeto representado em forma slida (solid). Sendo assim, iremos analis-las aos pares.
Cubo: glutWireCube (tamanho da aresta); glutSolidCube (amanho da aresta); Cone: glutWireCone (raio, altura, nmero de planos, fatias horizontais); glutSolidCone (raio, altura, nmero de planos, fatias horizontais); Esfera: glutWireSphere (raio, nmero de planos, fatias horizontais); glutSolidSphere (raio,nmero de planos, fatias horizontais) ; Toride (Rosquinha): glutWireTorus (raio interno, raio externo, nmero de planos, fatias horizontais); glutSolidTorus (raio interno, raio externo, nmero de planos, fatias horizontais); Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL
O que a GLUT faz para gerar essas figuras , na verdade, desenhar uma srie de planos, aproximando assim para o objeto escolhido. Isso feito a partir dos parmetros nmero de planos e nmero de fatias; este ltimo divide a figura no determinado nmero de fatias. Para cada fatia, haver uma quantidade de planos conforme o parmetro nmero de planos. Sendo assim, se desejarmos, por exemplo, uma esfera bem redonda, iremos necessitar de passar valores relativamente altos para os parmetros, nmero de planos e fatias horizontais. Repare que, quanto maior o valor desses parmetros, maior ser o esforo computacional para ger-los. Portanto, seja prudente. Repare que podemos usar as funes que desenham cones para criar pirmides. Para isso, basta passarmos o valor trs para o parmetro nmero de planos. Existem diversas funes para se desenhar outras primitivas como dodecaedros, porm, elas no so to teis quanto as j apresentadas.
Exerccios
1 - No mdulo correspondente, altere os parmetros de cada primitiva e observe os resultados. Observe tambm se houve uma reduo na velocidade de rotao dos objetos. 2 - Gere um tetraedro.
2.4 Removendo Superfcies Escondidas
Apesar do ttulo desta seo, no iremos remover nada, mas sim utilizar uma ferramenta que cria um efeito visual que ir nos permitir diferenciar objetos que esto na frente de outros. Um exemplo seria mais conveniente para demonstrar a importncia desse efeito. Imagine dois cubos cujas faces sejam de cores distintas e opacas. Chamemos de cubo 1 aquele em que no h remoo de superfcies escondidas, e de cubo 2 aquele em que esta existe. muito mais simples e intuitivo imaginar a situao do cubo 2, pois ela que normalmente ocorre no cotidiano. No vemos aquilo que est atrs de um outro objeto a menos que este seja transparente. A situao do cubo 1 bem mais complicada, chegando a ser imprevisvel neste caso. Para evitarmos a situao do cubo 1, a OpenGL nos fornece alguns dispositivos.
No cdigo acima, foram acrescentados trs novos elementos que permitem fazer a remoo de superfcies escondidas. Em glutInitDisplayMode(parmetros), acrescentamos um novo buffer GLUT_DEPTH, que o buffer de profundidade. Ele o principal responsvel por viabilizar o efeito que desejamos. Alm desta modificao, inclumos tambm a glEnable(GL_DEPTH_TEST), que habilita o teste de profundidade; e, em glClear(parmetros), acrescentamos GL_DEPTH_BUFFER_BIT, que faz com que os pixels do buffer de profundidade assumam a cor definida em glClearColor(parmetros). Devemos observar que fundamental adicionar esses elementos ao cdigo-fonte quando estamos trabalhando com uma cena em trs dimenses. Sem a diferenciao da profundidade dos objetos, a cena ir perder, sem dvida alguma, a sua realidade.
2.5 - Criando objetos transparentes
Neste captulo, veremos como podemos adicionar transparncia a um objeto. Em seguida, temos um exemplo de como podemos criar tal caracterstica utilizando a funo glBlendFunc().
void Inicio(void) { glClearColor(1.0,1.0,1.0,1.0); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_DEPTH_TEST); } O primeiro argumento de glBlendFunc se refere ao objeto da frente (tomando o observador como referncia). O argumento GL_SRC_ALPHA significa que o objeto mais prximo ser responsvel por uma frao igual ao quarto argumento do glColor no clculo total das cores que sero exibidas na tela. Analogamente, o segundo argumento se refere ao objeto mais longe e o clculo feito da mesma forma. Vamos calcular a cor total usada para criar a cena em um ponto onde podemos ver uma esfera, um octaedro e um prisma, ou seja, as 3 cores se combinam. Comearemos os clculos de dentro pra fora. A esfera azul no interior totalmente opaca, no tem transparncia. Por isso, 100% da sua cor ser levada em conta nos clculos abaixo. Como o octaedro tem alpha=0.2, apenas 20% da sua cor utilizada nos clculos: 0.2 * (0,1,0) = (0,0.2,0). Os outros 80% so ditados pelo esfera no interior, ou seja, 0.8 * (0,0,1) = (0,0,0.8). Logo, a cor total calculada, at agora, vale: (0,0.2,0) + (0,0,0.8) = (0,0.2,0.8). Como o paraleleppedo verde tem alpha=0.2 tambm, apenas 20% da sua cor utilizada nos clculos: 0.2 * (0,1,0) = (0,0.2,0). Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL Novamente, 80% das cores dependem dos objetos em seu interior. Logo, a cor final calculada vale: (0,0.2,0) + 0.8(0,0.2,0.8) = (0,0.36,0.64). Este um exemplo simples de transparncia. So apenas 3 elementos compondo uma cena esttica. Neste caso, importante desenhar SEMPRE os objetos opacos primeiro. Tomando este cuidado, garantimos que nossa cena ter o resultado desejado. Obs.: importante lembrar de ativar o clculo de transparncia, atravs de glEnable(GL_BLEND).
Exerccios
1 - Descomente as 4 linhas do incio da funo display. Ser desenhado um paraleleppedo totalmente opaco logo acima da nossa bandeira, usando exatamente esses valores calculados acima como sua cor. 2 - Faa um teste: troque a ordem dos objetos dessa cena e veja o que acontece.
2.6 - Criando Hierarquias de Transformaes
medida em que nossas cenas vo ganhando mais e mais elementos, se torna rduo o processo de determinarmos a posio de todos eles no espao. Mas isso s ocorre se no utilizarmos uma importante ferramenta da OpenGL. Para ficar mais claro, partiremos de um exemplo: suponha um prdio qualquer onde existem vrios andares, salas, e dentro delas, mveis. Em vez de especificar as coordenadas de uma cadeira qualquer do prdio em relao a uma origem absoluta, como a porta de entrada do prdio, mais conveniente e sistemtico fornecer as coordenadas em relao ao cmodo em que ela se encontra. Este, por sua vez, tem suas coordenadas em relao ao andar no qual se encontra, cuja posio determinada usando a origem absoluta. este tipo de organizao que utilizamos para facilitar o desenho de um sistema complexo. Outra aplicao bastante interessante o modelamento de uma estrutura com alguns eixos articulados, como um brao de rob. Olhando o programa exemplo dessa seo, percebemos que essa hierarquia feita atravs da disposio correta das funes glPushMatrix() e glPopMatrix(). A grosso modo, essas funes servem, respectivamente, para salvar e carregar o estado atual da matriz de transformao. Logo abaixo, temos um exemplo genrico de como trabalhamos com os pares de funes glPushMatrix() e glPopMatrix():
void Display(void) { glRotatef(ngulo, 0.0, 0.0, 1.0); glPushMatrix(); glTranslatef(deslocamento_x, deslocamento_y, 0.0); ... desenhos-1 ... glPopMatrix(); ... desenhos-2 ... } Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL
Ao analisarmos o cdigo juntamente com a figura, percebemos que primeiro realizamos uma rotao no sistema inicial, que no foi salvo. Isto significa que, caso queiramos voltar a desenhar neste sistema inicial, ser necessrio aplicarmos uma rotao de mesmo valor, porm, com sentido contrrio. Em seguida, salvamos o sistema rotacionado para, logo aps, aplicarmos uma translao. A partir da, realizamos desenhos de quaisquer objetos (os quais chamamos de desenhos-1), o que provavelmente ir ocasionar uma mudana drstica no sistema. Feito isso, chamamos a funo glPopMatrix(), que retorna automaticamente para o sistema salvo anteriormente, ou seja, o sistema rotacionado. Mais uma vez, realizamos desenhos de quaisquer objetos, os quais chamamos de desenhos-2, dentro do sistema rotacionado. Como salvamos o estado do sistema, no foi necessrio aplicar uma transformao contrria para retorn-lo ao que era antes. Com este tipo de lgica, possvel ento relacionar um sistema relativo a um outro sistema tambm relativo, gerando ento uma espcie de hierarquia de sistemas de coordenadas. No trecho a seguir, temos um exemplo de uma hierarquia de sistemas coordenados. Este exemplo , na verdade, uma parte de um dos programas didticos que fazem parte deste curso. O trecho do programa desenha os 3 ltimos retngulos. Com base nas informaes dadas acima, o que de se esperar quando rotacionarmos o Retngulo 2? Acertou se voc respondeu que o 3 e o 4 tambm iro rodar em torno da origem relativa dele. E quando rotacionarmos o 3? Nada acontece com o 2 (ele desenhado antes dessa rotao) e nada acontece com o 4, porque tem um glPopMatrix() separando os dois, ou seja, as modificaes na varivel rotacao_retangulo_3 s altera o prprio Retngulo 3. O mesmo acontece com o Retngulo 4. Dessa forma, os dois ltimos retngulos esto no mesmo nvel da hierarquia.
glPushMatrix(); //Salvando estado atual de transformaes glColor3ub(150,150,150); glTranslatef(10, 0, 0); glRotatef(rotacao_retangulo_2, 0, 0, 1); Retangulo(10,4);
//Desenhando o Retngulo 3 glPushMatrix(); //Salvando estado atual de transformaes glColor3ub(100,100,100); glTranslatef(10, 0, 0); glRotatef(rotacao_retangulo_3+45, 0, 0, 1); Retangulo(10,4); Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL glPopMatrix();//Carregando estado de transformao do PushMatrix correspondente(retngulo3)
//Desenhando o Retngulo 4 glPushMatrix(); //Salvando estado atual de transformaes glColor3ub(100,100,100); glTranslatef(10, 0, 0); glRotatef(rotacao_retangulo_4-45, 0, 0, 1); Retangulo(10,4); glPopMatrix();//Carregando estado de transformao do PushMatrix correspondente(retngulo4) glPopMatrix();//Carregando estado de transformao do PushMatrix correspondente(retngulo 2)
Essas funes, assim como o glBegin e glEnd, funcionam aos pares. Para evitar erros, sempre tenha um PopMatrix para cada PushMatrix. A hierarquia deste programa funciona da seguinte forma: rotacionando o retngulo 1 (alterando o valor do float rotacao_retangulo_1), todos os outros so rotacionados juntos, com o eixo de rotao na origem dele. Rotacionando o retngulo 2, os de hierarquia maior so rotacionados juntos e assim por diante. A cor do retngulo indica sua hierarquia (quanto maior, mais escuro). Segue um pequeno esquema da hierarquia no programa exemplo.
Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL
Captulo 3 - Interao e Animao
3.0 - Interao atravs do teclado
Esta seo ir tratar da relao usurio/programa atravs do teclado, o que possibilita uma importante interatividade durante a execuo do programa. Aes como girar um objeto ou mudar a sua cor requerem uma interface para serem ativadas, e normalmente, usamos o teclado. Para isso, usamos recursos combinados das bibliotecas GLUT e OpenGL. Observe o seguinte cdigo:
GLfloat angulox=0.0; void DISPLAY() { glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-80.0, 80.0, -80.0, 80.0, -80.0, 80.0) glRotatef(angulox,1.0, 0.0, 0.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); .... } void KEYBOARD(unsigned char tecla, int x, int y) { switch(tecla) { case 'x': angulox=angulox+5.0; if(angulox > 360.0) angulox=angulox-360.0; glutPostRedisplay(); break; default; break; } } void main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(450, 450); glutInitWindowPosition(50, 50); glutCreateWindow("Aula sobre OpenGL"); INIT(); glutKeyboardFunc(KEYBOARD); glMainLoop(); Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL } Repare que dentro de "main" temos a funo "glutKeyboardFunc(nome da funo com as condies de interao)". Esta funo responsvel por monitorar todo o teclado, excetuando o teclado numrico e certas teclas especiais como as setas. Toda vez em que o usurio pressiona uma tecla, a "glutKeyboardFunc" ir passar para a funo " KEYBOARD" trs parmetros, dentre eles o "boto". Com esse parmetro, podemos ativar determinadas aes sobre nossa cena. No nosso caso, estamos rotacionando nosso volume de visualizao atravs do incremento de uma varivel global que est associada a um "glRotatef", operando sobre a matriz de projeo. Enquanto a tecla x estiver pressionada, a varivel angulox ser incrementada e conseqentemente o volume de visualizao ser rotacionado. Para que isso possa ser visto na tela do computador imediatamente, necessrio que chamemos a funo glutPostRedisplay(), ela responsvel por redesenhar a cena toda vez que x for pressionado.
3.1 Interao atravs do mouse
Uma outra maneira importante de interao usurio/programa o uso do mouse. A lgica de trabalho parecida, mudando apenas algumas particularidades. Vamos usar um cdigo ilustrativo, e, em seguida, faremos algumas observaes.
void DISPLAY() { glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-80.0, 80.0, -80.0, 80.0, -80.0, 80.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); .... .... } void MOUSE(unsigned char tecla, int estado, int x, int y) { switch (tecla) { case GLUT_LEFT_BUTTON: if (estato == GLUT_DOWN) funo qualquer; glutPostRedisplay(); break; case GLUT_MIDDLE_BUTTON: if (estado == GLUT_DOWN) funo qualquer; glutPostRedisplay(); break; case GLUT_RIGTH_BUTTON: if (estado == GLUT_UP) funo qualquer; glutPostRedisplay(); Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL break;
Percebemos que, tal como na funo glutKeyboardFunc, a funo glutMouseFunc(nome da funo com as condies de interao) passa para a funo MOUSE os mesmos parmetros, acrescentando porm, o parmetro estado. Toda vez que trabalhamos sobre o mouse, a funo da GLUT correspondente ir passar os novos parmetros para a funo MOUSE. Vamos analisar detalhadamente cada parmetro: boto indica qual dos trs botes est sendo usado, podendo assumir um dos trs seguintes valores: GLUT_LEFT_BUTTON, GLUT_RIGTH_ BUTTON, GLUT_MIDDLE_BUTTON; o parmetro estado indica se o boto est pressionado(GLUT_DOWN) ou no-pressionado(GLUT_UP); por fim, temos os parmetros x e y, que recebem os valores correspondentes s coordenadas em que se localiza o ponteiro do mouse. Com isso, temos uma base para podermos criar uma srie de operaes sobre nossa cena. Poderamos escrever, por exemplo, uma funo que translada um objeto para um local da janela determinado pelo clique do mouse, ou ento que um certo objeto mude de cor quando um dos botes do mouse for pressionado, etc.
3.2 Animao
Um dos objetivos da computao grfica , sem dvida, gerar animaes e simulaes que seriam muito difceis, ou at mesmo impossveis, na vida real. Com as duas ferramentas apresentadas anteriormente, demos um grande passo para podermos criar animaes controladas. Vejamos agora como poderamos criar uma cena com animao um pouco mais automatizada. A idia basicamente a mesma: ser necessrio escrevermos uma funo na qual ser incrementada uma varivel qualquer, sendo que esta estar associada a uma transformao geomtrica, ou fraes do RGB, etc. Vejamos um trecho ilustrativo de um cdigo fonte, semelhante ao anterior.
void ANIME() { angulox=angulox+5.0; Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL if(angulox > 360.0) angulox=angulox-360.0; } void DISPLAY() { glMatrixMode(GL_PROJECTION); glLoadIdentity(); glRotatef(angulox, 1.0, 0.0, 0.0); glOrtho(-80.0, 80.0, -80.0, 80.0, -80.0, 80.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); .... .... } void MOUSE(unsigned char tecla, int estado, int x, int y) { switch (tecla) { case GLUT_LEFT_BUTTON: if (estato == GLUT_DOWN) glutIdleFunc(ANIME); break; case GLUT_MIDDLE_BUTTON: if (estado == GLUT_DOWN) glutIdleFunc (NULL); break;
default: break; }
Neste exemplo, rotacionamos o nosso volume de visualizao no sentido horrio a cada clique do boto esquerdo e, conseqentemente, tudo aquilo que est dentro dele. Caso pressionemos a tecla do meio, o quadrado ir interromper o giro. Porm, neste cdigo, h a incluso de uma nova funo da GLUT, a glutIdleFunc(nome da funo que controla a animao) . Esta funo tem como objetivo gerar um loop infinito na funo em que ela tem como parmetro, caso nenhum outro evento esteja se processando no momento. Isso significa que o volume de visualizao ir girar infinitamente, a menos que a tecla do meio seja pressionada.
Exerccio
1 Estude o mdulo de animao, ele semelhante ao cdigo exemplo desta seo, logo aps execute o programa.
Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL Captulo 4 Uso de Iluminao
4.0 - Habilitando o uso de iluminao
Um recurso muito importante e amplamente utilizado para aumentar o realismo de uma cena em computao grfica a utilizao de luz. A OpenGL oferece uma maneira relativamente simples de acrescent-la em um programa. Este mecanismo ser visto abaixo. Para habilitar o uso de iluminao necessrio acrescentar glEnable (GL_LIGHTING), j que, por default, ela est desativada. Se fizermos apenas isso, nossa cena ficar escura, pois no ativamos nenhuma fonte de luz especfica. Para faz-lo, outro glEnable precisa ser acrescentado, mas com o argumento GL_LIGHTn, onde n um inteiro identificador da fonte de luz e varia de 0 a 7. Assim, glEnable(GL_LIGHT0) ativa a luz de nmero 0. Perceba que no especificamos nenhuma propriedade da luz ou do objeto ainda. Assim, utilizamos os valores "defaults" da OpenGL.
4.1 - Definindo propriedades
A OpenGL utiliza algumas aproximaes para representar a luz, de modo a otimizar a velocidade de processamento requerida, mantendo uma qualidade relativamente alta de seus grficos. Um desses recursos para modelagem considerar que existem 3 componentes bsicos de luz: a luz ambiente, a difusa e a especular (existe ainda um quarto componente, a emissiva, que no ser vista nesse curso). A propriedade ambiente uma luz que ilumina toda a cena de maneira uniforme. Esta componente uma aproximao das sucessivas reflexes ocorridas pela luz em um ambiente. Por exemplo, se ligarmos uma lanterna num quarto totalmente escuro, perceberemos que, mesmo onde no a estamos apontando, ocorre uma pequena iluminao aproximadamente uniforme, resultado das sucessivas colises dos raios de luz com as paredes. A propriedade difusa a mais notvel entre as trs: ela define a quantidade de luz que, ao encontrar a superfcie de um material, refletida em todas as direes. Por isso, a maior responsvel pela cor final do objeto.
Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL E, por ltimo, a propriedade especular define a quantidade de luz que, ao encontrar a superfcie de um material, refletida preferencialmente seguindo o mesmo ngulo de incidncia. Por isso, est intimamente ligada com o brilho dos objetos. Por exemplo, metais tm alta especularidade, ao contrrio de um tapete, que praticamente zero. Espelhos so considerados especulares perfeitos, por refletirem especularmente quase 100 % dos raios que os atingem.
Em seguida, temos uma breve explicao de como determinamos essas propriedades: Primeiramente, definimos os vetores que nos diro as propriedades da luz e do material. Ambos tm as propriedades ambiente, difusa e especular. Alm disso, necessrio especificar a posio da luz e o coeficiente de especularidade do material (define a concentrao dos raios refletidos especularmente). Os vetores que definem as propriedades ambiente, difusa e especular tm 4 valores, sendo que os 3 primeiros so as componentes RGB e o ltimo a componente alpha, que pode servir para tornar o objeto transparente. A intensidade final da luz calculada tomando como base as propriedades da luz e do material, atravs da seguinte frmula:
At = Al*Am Dt = Dl*Dm Et = [El*Em]^sh
Em suma, a intensidade de uma determinada componente que atinge o observador o produto das propriedades desta componente da luz e do material. A nica exceo a parte especular que elevada ao coeficiente de especularidade (sh). Se vrias fontes de luz estiverem atuando, basta somar as propriedades de todas e efetuar a multiplicao normalmente, como abaixo:
At = (Al1+Al2...+Aln)*Am Dt = (Dl1+Dl2...+Dln)*Dm Et = [(El1+El2...+Eln)*Em]^sh
O vetor que define a posio da luz tambm tem 4 valores: os 3 primeiros so as coordenadas x,y,z da luz e o quarto valor define se a luz local (usando-o igual a 1) ou "no infinito" (usando-o igual a 0). Este tipo de representao conhecida como homognea e Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL utilizada diversas vezes em computao grfica.
Aps definir todos os vetores, iremos associar cada propriedade com seu respectivo valor. No caso das propriedades do material, a linha de comando tem a forma: gl + Material + {tipo de varvel} {forma vetorial}, e os argumentos so, respectivamente: (face a ser renderizada, propriedade, *valores).
No caso da luz, a linha de comando da forma: gl + Light + {tipo de varivel} {forma vetorial}, e os argumentos so, respectivamente: (luz a ser trabalhada, propriedade, *valores).
Existem diversas outras propriedades que a OpenGL possibilita determinar, como propriedade emissiva de um material, ndice de atenuao da luz, ngulo de corte da luz etc, mas estas no sero vistas nesse curso. Perceba que o clculo da iluminao, como foi falado no incio da seo, depende do ngulo de incidncia dos raios de luz sobre a face do material iluminado. A OpenGL calcula esse ngulo automaticamente, desde que voc especifique o vetor normal unitrio superfcie. Isso feito atravs do comando glNormal3f(normalx, normaly, normalz). Veja um exemplo abaixo:
glBegin(GL_TRIANGLES); glNormal3f(0,1,0); glVertex3f(0,0,0); glVertex3f(1,0,0); glVertex3f(0,0,1); Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL glEnd();
Um tringulo foi desenhado no plano y=0, portanto, sua normal (0,1,0). Caso a normal passada fosse no unitria, a luz teria um comportamento imprevisvel. Para evitar esse tipo de erro, a funo glEnable tendo como argumento GL_NORMALIZE normaliza automaticamente seu vetor. No necessrio especificar as normais das primitivas da GLUT e da GLU: elas j esto devidamente calculadas. possvel passar as propriedades do material de uma forma mais rpida e barata, utilizando a funo glColor3f(). Para isso, temos que inserir a linha glEnable(GL_COLOR_MATERIAL). Assim, quando escolhemos a cor do objeto, na verdade, estamos definindo as propriedades difusa e ambiente de seu material. Se quisermos alterar outras propriedades atravs do glColor, devemos colocar, antes do Enable, a funo glColorMaterial(face do objeto, propriedade(s) da luz). Por exemplo, se colocarmos glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR), a propriedade a ser alterada atravs do comando glColor3f() a especular, ao invs das definidas por default.
Capitulo 5 - Tpicos Bsicos sobre Aplicao de Textura
5.0 - Compreendendo a aplicao de textura
Entende-se como aplicao de textura a adio de uma imagem a um polgono, como, por exemplo, adicionar uma seqncia de imagens de tijolos a um grande retngulo para simular um muro. Pense no esforo necessrio para desenhar cada tijolo utilizando as primitivas da OpenGL. Com texturas, essa tarefa muito simples, alm de conferir grande realismo cena. Dois passos so importantes nesse processo: a carga da imagem pelo computador, que transforma os dados de cores da foto em dados de cores aplicveis cena, e a aplicao, propriamente dita, desses dados ao polgono em questo. Quanto carga, pode-se utilizar uma rotina da biblioteca glaux.h para leitura de imagem de extenso .bmp. Como essa biblioteca um pouco antiga, daremos nfase carga de arquivos de extenso .raw, pois esses ltimos utilizam as bibliotecas que foram adotadas at ento. Carregadores para arquivos de imagem com extenso .tga ou .jpg podem ser facilmente encontrados na internet.
5.1 - Aspectos tericos bsicos
O mapeamento de textura consiste em, inicialmente, aplicar os dados de cor obtidos da imagem em pontos de um plano com coordenadas S (abscissa) e T (ordenada). Esse plano serve para mapear os pontos da imagem, ou seja, sabendo que a imagem possui largura e altura e que os vrtices que a delimitam so (0,0), (0,1), (1,1), (1,0) no plano (S,T), todos os pontos internos possuem uma localizao e seu respectivo dado de cor. Os dados de cor da textura so chamados de texels.
Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL
importante ressaltar que o plano (S,T) no est diretamente relacionado com as faces do polgono ou prisma a ser desenhado, pois essas ltimas dependem de trs coordenadas (x,y,z). Na verdade, o que o OpenGL faz uma correspondncia entre as coordenadas da textura mapeada e as coordenadas da face, aplicando os dados de cor em pontos no espao com coordenadas (x,y,z). Para isso, basta fornecer a correspondncia entre os vrtices da imagem de textura e do polgono; tudo o que for delimitado por esses vrtices ser mapeado no plano de textura e ter uma imagem na face delimitada do polgono. Caso a face em questo corte perpendicularmente um dos eixos coordenados, a figura geomtrica possui uma das coordenadas da face constante. Logo, para descrever essa face (seu formato, dimenso, etc.) precisamos conhecer as outras duas coordenadas dos vrtices e verificar a figura geomtrica determinada no plano por esses vrtices. O polgono que delimita a textura mapeada deve possuir a mesma forma da figura geomtrica da face, para que ocorra perfeita correspondncia entre a imagem mapeada e seu local de aplicao. Do contrrio, seria como aplicar uma imagem quadrada em um trapzio sem que haja deformao da imagem. Intuitivamente percebe-se que isso impossvel! Por exemplo, se queremos aplicar os tijolos acima em um retngulo, podemos fornecer a seguinte correspondncia:
Independentemente do tamanho do retngulo, ocorre a transferncia dos dados de cor da textura, que formam uma imagem quadrada, para pontos do retngulo. Como no aplicamos um quadrado em outro quadrado, evidentemente a imagem ficou dilatada em uma direo. Nesse caso, entram em ao os filtros de imagem. Observe o esquema:
Fonte: The Redbook
Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL Suponha, inicialmente, que um dos dado de cor da textura (texel) utilize exatamente um pixel na imagem desenhada. Sendo assim, imaginando a textura como formada por uma seqncia de pontos de cor (texels) e a imagem desenhada no monitor como um conjunto de pixels, nesse caso a correspondncia entre as dimenses da imagem de textura e da imagem desenhada seria perfeita e no ocorreria deformao. Mas, e se queremos diminuir a imagem desenhada, ou mesmo ampli-la? Veja pelo diagrama anterior que quando aumentamos uma imagem, como se dispusssemos de uma lupa, uma pequena parte de um texel preencheria totalmente um pixel, para que assim a imagem se magnifique. O contrrio vlido para a minificao. O OpenGL realiza clculos para estimar qual seria o melhor dado de cor a ser aplicado no pixel. Pode ser uma mdia ponderada dos texels que esto ocupando uma posio de correspondncia mais prxima ao centro do pixel em questo (GL_LINEAR) ou simplesmente o texel mais prximo do centro do pixel (GL_NEAREST). Dependendo da situao, podemos escolher entre velocidade de processamento ou qualidade da imagem.
5.2 - Aspectos prticos bsicos
Inicialmente, apresenta-se um programa comentado que ilustra a aplicao de uma textura de tijolos a um retngulo. No de interesse ressaltar a funo dos comandos de carga de textura. O enfoque seria a utilizao das funes OpenGL para manipulao das imagens de textura, discutindo unicamente o efeito da alterao dos parmetros mais significativos.
Abra o projeto Textura01_raw.dev
Para que a carga de uma imagem .raw genrica funcione, fornea corretamente as dimenses da figura (largura e altura) na funo Carregador_de_RAW. No caso, os valores para a figura tijolo.raw j esto ajustados. A dimenso profundidade, normalmente, assume o valor trs e relevante apenas para a carga. Um valor menor do que trs deforma a figura. Faa as seguintes alteraes no projeto:
Experimente alterar as dimenses do retngulo usando o glScalef, abaixo da matriz MODELVIEW. Note que a imagem modificada, mas mantm seus padres caractersticos. Experimente um glScalef por um fator maior que 1 na matriz TEXTURE. Mantendo sua alterao anterior, procure por glTexParameteri e altere as constantes GL_CLAMP para GL_REPEAT.
Observe que a parede se ajusta. Quando utilizado um scale, por um fator maior do que 1, na matriz de textura, a rea mapeada excede o quadrado unitrio. O que o OpenGL coloca fora desse quadrado? Se as constantes GL_CLAMP esto acionadas para ambos os eixos S e T, a ltima fileira de dados de cor, tanto horizontal quanto vertical da textura, se repete ao longo do plano (S,T). Foi essa informao que mapeamos e enviamos ao polgono.
Tente, mantendo o scale na matriz TEXTURE, alterar na funo glTexParameteri(), um dos eixos para GL_CLAMP e o outro para GL_REPEAT.
A funo glTexParameteri() define os filtros de imagem utilizados e a forma como ser aplicada a imagem no plano de textura.
Procure a funo glTexEnv() e alterne a constante GL_DECAL para GL_MODULATE. Pressione R ou shift+R no teclado. Tente o mesmo com as teclas G e B. Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL
possvel modificar as cores da textura fornecendo um parmetro float referente a cada coordenada de cor (R,G,B,A) que varia entre 0.0 e 1.0. A constante GL_DECAL define que a textura ser aplicada conservando suas cores originais. Utilizando GL_MODULATE, podemos fornecer novos valores para o vetor glColor4f(), o que modifica a cor resultante final.
Abra o projeto Textura02_raw.dev
A seguir encontram-se os comandos necessrios para habilitao de dois ou mais tipos de textura:
GLuint vetor_de_texturas[2] recebe dois inteiros que, cada um, identificam a imagem a ser utilizada. A constante TOTAL_DE_TEXTURAS identifica o nmero de texturas possveis de serem habilitadas. Comparando com o programa anterior, a chamada para Carregador_de_RAW foi generalizada, para que vrias imagens possam ser carregadas por essa funo. Um inteiro adicional identifica a linha "ocupada" pela textura no vetor_de_texturas[]. A funo glGenTextures atribui textura um valor inteiro que a identifica. Ela recebe como parmetros o nmero total de texturas a serem habilitadas e, alm disso, guarda no vetor_de_texturas[] o inteiro correspondente quela imagem. glBindTexture efetivamente cria a imagem de textura com os atributos determinados (modo de aplicao, filtros, mipmaps, etc.).
A carga da imagem efetuada uma nica vez, com a funo Carregador_de_RAW, o que permite ao programador "descarregar" dados referentes a uma das duas imagens mapeadas por meio da funo glBindTexture(). Essa funo determina uma textura corrente, ou seja, at que ela seja chamada novamente, toda textura aplicada ser aquela que foi "descarregada" por essa funo. Repare que as transformaes referentes ao mapeamento de textura, como scales e translates na matriz GL_TEXTURE foram separadas para cada imagem.
Altere os parmetros dos scales e translates e verifique que uma transformao na textura do ratinho no interfere na textura de tijolos. Abra o projeto Textura03_raw.dev Altere o valor do vetor_de_texturas[] de zero para 1 e mude o filtro de GL_LINEAR para GL_NEAREST na chamada a funo Carregador_de_RAW. Observe como a imagem perde em resoluo.
Segue-se um exemplo de aplicao de textura em um cilindro gerado pelas primitivas do OpenGL, onde possvel observar a utilizao da parametrizao de uma superfcie em funo de duas variveis. Assim, possvel relacionar os pontos que compe a superfcie com as coordenadas S e T do plano de textura. A idia na verdade a mesma: aproximar o cilindro por uma seqncia de faces planas, determinar a correspondncia entre os vrtices das coordenadas de textura e das faces aproximadas.
Abra o projeto Textura04_raw.dev
Observe o seguinte esquema: Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL
Essa figura descreve a relao entre as coordenadas de textura (S,T) e os vrtices das faces aproximadas do cilindro (x,y,z). Por fim, destaca-se o uso da funo gluBuild2DMipmaps(), que racionaliza o custo computacional ao utilizar um maior nmero de bytes para pontos da imagem mais prximos do observador, diminuindo gradativamente o nmero de bytes associados com imagens reduzidas, ou seja, mais distantes do observador. Os filtros de minificao associados ao mipmaps seriam:
Esses filtros determinam o modo de transio entre regies da imagem que utilizam maiores e menores valores de bytes de cor. A transio entre essas regies pode ser suavizada com a chamada LINEAR ao final da constante, resultando em uma imagem "smooth".
Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL Captulo 6 Tpicos bsicos sobre fractais
6.0 - Introduo
Fractais so basicamente formas geomtricas determinadas por padres de figura que se repetem infinitamente. Exemplos:
Nas figuras temos o tringulo de Waclaw Sierpinsky e uma figura do conjunto de Mandelbrot. Vemos claramente no tringulo que cada parte repete exatamente o todo, esse tipo de fractal chamado de auto-semelhante e o qual daremos nfase. Podemos observar na natureza que existem vrias formas que se aproximam da definio de fractais. o exemplo de rvores, brcolis, arbustos ou at mesmo montanhas podem ser definidas com fractais que utilizam variveis aleatrias. A partir de fractais possvel obter diversas figuras bastante complexas (como as figuras acima) mas com uma definio algortmica/matemtica bem simples.
6.1 Implementao de figuras auto-semelhantes
Como guia para fractais ser usado um fractal simples, bidimensional, que cria uma espcie esqueleto de rvore, o cdigo desse fractal poder ser obtido no mdulo1 sobre fractais.
Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL
Como dito anteriormente, um fractal uma estrutura repetida infinitamente. Na prtica, na implementao computacional, a repetio infinita da estrutura bsica determinaria um estouro de memria. Para ento possibilitar a implementao computacional de um fractal so usadas condies de parada. No caso da rvore gerada acima a funo que gera o fractal (Arvore) recebe dois parmetros de entrada. O primeiro parmetro determina qual o tamanho do menor galho, e o segundo qual o tamanho do galho inicial. O algoritmo implementa uma repetio da estrutura em V diversas vezes e a cada iterao o tamanho do galho utilizado para desenhar reduzido de um fator qualquer (no cdigo o fator 1/5) e em seguida comparado com o valor usado como parmetro do menor galho. Quando o tamanho atual for menor ou igual ao parmetro menor a repetio para. Essa parada determinada pelo comando if que compara esses dois valores antes de fazer qualquer outra coisa. Para estruturar as repeties em um fractal pode-se comumente usar a recursividade. Uma chamada recursiva caracterizada quando uma funo chama ela mesma. A recurso facilita muito a implementao do fractal porque podemos definir apenas a estrutura bsica do fractal e fazer em seguida uma nova chama da funo com os parmetros de entrada alterados conforme se deseja. Para a nossa rvore a recurso usada da seguinte maneira: desenha-se o brao direito, posiciona-se para desenhar o prximo galho e chama a funo rvore novamente com o parmetro do galho inicial reduzido. Isso far com que o programa desenhe todos os galhos do lado direito com a reduo progressiva dos galhos at que o parmetro do menor galho seja alcanado. Em seguida posiciona-se para desenhar o brao esquerdo, posiciona-se para desenhar o prximo galho e faz-se novamente a chamada da funo com reduo do tamanho do galho. Sero desenhados ento todos os galhos do lado esquerdo. Os galhos do lado direito que foram desenhados anteriormente prosseguiro no algoritmo e tambm desenharo seus respectivos braos esquerdo. Uma dica para facilitar a implementao pensar na estrutura bsica. Desenha-se a estrutura bsica, depois posicione o local no cdigo onde devero ser feitas as chamadas recursivas que onde a estrutura bsica aparecer novamente.
6.2 - Adio de adereos ao fractal
Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL
Para transformar nossa antiga rvore seca numa rvore verdinha, cheia de folhas, basta um processo bem simples. A adio de adereos pode ser feita apenas com a adio de uma estrutura condicional que testa o tamanho do galho atual. Nesta rvore o tamanho do galho atual comparado com o tamanho do galho menor multiplicado por dois. Quando o galho atual j menor ou igual ao menor feita algumas transformaes para desalinhar as folhas e, em seguida, chamada a funo que faz a folha. As folhas em desalinho conferem um aspecto mais natural figura. A folha provm da funo Folha definida previamente atravs de um conjunto de pontos dispostos num triagle_fan. O mesmo processo poder ser feito para outros fractais comparando os valores que determinam a condio de parada, ou algum outro parmetro do fractal que alterado de acordo com o andamento das iteraes. Efeitos de mudana de cor, textura, etc, podem ser obtidos desta maneira.
6.3 - Usando nmeros aleatrios
sabido que na natureza os fenmenos no ocorrem de forma uniforme. H tantos fatores na natureza que influenciam determinado evento que no possvel descr-lo de forma analtica, para melhor delimita-lo pode-se fazer atravs da matemtica probabilstica. No exemplo da rvore no so utilizadas nenhuma funo de distribuio de probabilidade, nem qualquer outra forma matemtica que descreveria com muito melhor fidelidade o que realmente ocorre no evento tratado (onde h galhos e onde no h). Apenas atribumos uma probabilidade de 90% de uma nova chamada da funo, onde seria desenhado outro galho. Essa probabilidade implementada atravs de uma varivel que pode assumir valores aleatrios. Em C, os valores aleatrios so obtidos atravs da funo rand(), mas essa funo retorna um nmero de 0 a RAND_MAX, por isso, para obtermos um nmero aleatrio no intervalo [0,1] devemos dividir o resultado por RAND_MAX. o que feito na funo aleatorio(). Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL Atribuindo ento um valor para a varivel aleatria, comparamos seu valor com 0,1. Se a varivel maior ento se faz a nova chamada da funo. Essa mesma varivel poderia ser introduzida para termos uma variao aleatria do tamanho do galho da nova chamada, da inclinao de cada galho, etc... possibilitando obter no final um fractal totalmente aleatrio. importante ressaltar que o OPEN_GL realiza os clculos de renderizao da cena toda vez que h uma alterao de estado, e a funo glutDisplayFunc() chamada para redesenhar a cena. Movimento da posio do observador, maximizao da janela, alterao no tamanho da janela, pressionamento de teclas do mouse ou teclado quando usando as funes de interao, caracterizam mudanas de estado. Quando os clculos so refeitos os valores da varivel aleatria sero diferentes do anterior e uma figura diferente gerada a cada mudana de estado. Para contornar esse problema utilizada a semente. A semente um valor inicial que a varivel aleatria assume e a partir dela calcula os demais valores, assim a seqncia de valores aleatrios sempre a mesma a partir de quando dada essa semente. Ento, para evitar o problema proposto anteriormente, devemos atribuir uma semente antes da chamada da funo que desenha o fractal utilizando valores aleatrios. Desta forma a figura desenhada sempre a mesma no importando a mudana de estado. A figura ter uma relao determinstica com a semente, para cada semente uma figura diferente. Experimente retirar a semente e faa mudanas de estado, observe o resultado, divertido...
6.4 - Consideraes finais
Todos os conceitos aqui apresentados podero ser utilizados para a construo de fractais muito mais complexos, que utilizem o espao 3D (para a visualizao, j que a dimenso de um fractal assim determinada) ou apresentam diversas coloraes; use a criatividade... A base de todo fractal a mesma, a repetio, por isso no so necessrios grandes cdigos (em tamanho) para construir figuras bem complexas, mas pensar na lgica da construo no muito fcil. Exemplos de fractais construdo pelo PADmod podero ser observados nos arquivos de exemplo.
Apndices
I - A linguagem C/C++
Como j dito a biblioteca OpenGL, assim como suas auxiliares, so implementadas utilizando a linguagem C. Sendo assim, muito conveniente que voc escreva o seu programa utilizando C ou C++. O propsito deste apndice, o de fornecer apenas a sintaxe de algumas estruturas lgicas bsicas destas linguagens.
Declarao de variveis
Tipo Declarao Exemplo Inteiro int "nome da varivel" int contador real ou ponto flutuante float "nome da varivel" float produto Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL Caractere char "nome da varivel" char inicial_do_nome
Declarao de estruturas de armazenamento
Tipo Declarao Exemplo Vetor tipo "nome da varivel"[dimenso] float vet[3] Matriz tipo "nome da varivel"[dimenso] [dimenso] char mat[4][6]
Para mais informaes sobre a linguagem C/C++ consulte nosso site, l esto disponveis diversos links.
Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL II - Como instalar o OpenGL no Dev C/C++
A OpenGL uma biblioteca altamente portvel, sendo assim pode ser instalada em diversos sistemas operacionais. Como, sobretudo no Brasil, a maior parte dos usurios de microcomputadores trabalha em ambiente Windows, resolvemos desenvolver este apndice para auxiliar na instalao da biblioteca em um compilador C/C++ open source. Primeiramente faa o download do compilador Dev C/C++ no site da empresa Bloodsheed ( http://www.bloodshed.net/devcpp.html ), e em seguida instale-o. Realize o download do arquivo OpenGL.zip e os das bibliotecas auxiliares em nosso site ou em http://mywebpage.netscape.com/PtrPck/glutming.zip e descompacte-os. A partir da siga os seguintes passos:
1. Copie o arquivo glut32.dll para a pasta C:\Windows/System ou C:\Windows/System 32, dependendo da verso do seu Windows. Normalmente no Windows 98 se copia na pasta System, enquanto no Windows XP na pasta System 32.
2. Copie todos os arquivos de exteno .o e .a, para a pasta C:\Arquivos de programas\Dev-C++\Lib.
3. Copie todos os arquivos de exteno .h, para a pasta C:\Arquivos de programas\Dev- C++\Include\Gl.
4. Toda vez que for compilar um cdigo em OpenGL no se esquea de acrescentar dentro da opo Project Options os seguintes itens na caixa Futher object files or linker options:
-lopengl32 -lglut32 -lglu32
III - Guia para consultas rpidas (funes mais utilizadas)
Nesta seo apresentam-se algumas das funes OpenGL (incluindo GLUT) utilizadas nos programas de exemplo:
void glutInitWindowPosition(int x, int y); void glutInitWindowSize(int width, int height); Define a posio e dimenses da janela a utilizar
void glutInit(int *argcp, char **argv); Inicializa a glut.
void main(int argc, char **argv) { glutInit(&argc, argv); Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL ...
#define GLUT_RGB #define GLUT_RGBA #define GLUT_INDEX #define GLUT_SINGLE #define GLUT_DOUBLE #define GLUT_DEPTH void glutInitDisplayMode(unsigned int mode); Indica o modo de apresentao a utilizar. RGA, RGBA, INDEX: modo de cor, SINGLE, DOUBLE: utilizao de buffer para animao, DEPTH: utilizao de Z buffer.
void glutMainLoop(void); Entra no ciclo principal de execuo da GLUT. A partir deste momento feita a interao com o usurio e sero chamadas as funes de usurio respectivas.
glutMainLoop();
int glutCreateWindow(const char *title); Cria uma nova janela com o ttulo indicado
glutCreateWindow("Color Cube");
void glutSwapBuffers(void); Troca o buffer utilizado (para animao).
glutSwapBuffers();
void glutDisplayFunc(void (*)(void)); void glutReshapeFunc(void (*)(int width, int height)); void glutKeyboardFunc(void (*)(unsigned char key, int x, int y)); void glutMouseFunc(void (*)(int button, int state, int x, int y)); void glutMotionFunc(void (*)(int x, int y)); void glutPassiveMotionFunc(void (*)(int x, int y)); void glutIdleFunc(void (*)(void)); Permitem definir funes que sero chamadas em resposta a certos eventos. Indicar NULL para limpar uma definio. Display: chamada quando a janela apresentada, Reshape: quando so alteradas as dimenses da janela, Keyboard: quando premida uma tecla, MouseFunc: quando o usurio move o mouse com um (ou mais) boto precionado, PassiveMouseFunc: quando o usurio move o mouse, Idle: chamada quando o sistema est espera do usurio. Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL
/* definio da funo do usurio */ void myReshape(int w, int h) { ... } ... /* indic-la GLUT */ glutReshapeFunc(myReshape); ... /* exemplos de outras definies de funo do usurio: */ void myDisplay() ... void myKeyboard(unsigned char key, int x, int y) ... void myMouse(int button, int state, int x, int y) ... void myMotion(int x, int y) ... void myPassiveMotion(int x, int y) ... void myIdle() ...
Define parmetros de uma determinada luz. O parmetro light indica a luz e pode ser: GL_LIGHT0, GL_LIGHT1, etc... Para glLightf(...) e glLighti(...), pname pode ser: GL_SPOT_EXPONENT, GL_SPOT_CUTOFF, GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION ou GL_QUADRATIC_ATTENUATION. Para glLightfv(...) e glLightiv(...), pname pode ser: GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_POSITION, GL_SPOT_DIRECTION, GL_SPOT_EXPOENT, GL_SPOT_CUTOFF, GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION ou GL_QUADRATIC_ATTENUATION.
Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL Define caractersticas das superfcies a desenhar. O parmetro face indica qual a face que estamos a definir e pode ser: GL_FRONT, GL_BACK ou GL_FRONT _AND_BACK. Para glMaterialf(...) e glMateriali(...), pname s pode ser GL_SHINNESS. Para glMaterialfv(...) e glMaterialiv(...), pname pode ser: GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_EMISSION, GL_SHINNESS, GL_AMBIENT_AND_DIFFUSE ou GL_COLOR_INDEXES.
void glEnable(GLenum cap); void glDisable(GLenum cap); Permite ativar ou desativar parmetros globais do OpenGL. Alguns valores possveis para cap: GL_COLOR_MATERIAL: as caractersticas dos materiais so derivadas da cor atual (ver glColorMaterial) GL_DEPTH_TEST: ativa a utilizao do buffer de profundidade (remoo de faces escondidas) GL_LIGHTi: ativa a luz i. GL_LIGHTING: ativa a utilizao das luzes para o clculo das cores finais de cada vrtice. GL_LINE_SMOOTH: desenha linhas suavizadas (anti-aliasing) GL_NORMALIZE: normaliza os vetores indicados em glNormal. GL_POINT_SMOOTH: equivalente a GL_LINE_SMOOTH mas para pontos. GL_POLYGON_SMOOTH: equivalente a GL_LINE_SMOOTH mas para poligonos. GL_SMOOTH: ativa sombreamento suave (interpolao entre vrtices).
glEnable(GL_SMOOTH); /*ativar shading suave */ glEnable(GL_LIGHTING); /* ativar luzes */ glEnable(GL_LIGHT0); /* ativar luz 0 */ glEnable(GL_DEPTH_TEST); /* ativar teste z buffer */ glEnable(GL_COLOR_MATERIAL); /* ativar materiais a partir da cor */
Indica a cor de fundo a ser utilizada por glClear(...).
glClearColor (0.0, 0.0, 0.0, 0.0);
void glFlush(void);
Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL Obriga o OpenGL a completar todas as operaes pendentes. glFlush(...) deve ser chamada quando necessrio garantir que a imagem est completamente definida na tela, por exemplo antes de aguardar por entrada do usurio.
glFlush();
void glPushMatrix( void ); void glPopMatrix( void ); Permitem guardar temporariamente a matriz de transformao atual. Aps a instruo glPopMatrix() todas as operaes que alteram a matriz atual (ex: glTranslatef(...), glLoadIdentity()) efetuadas aps o ltimo glPushMatrix(), so ignoradas.
void glOrtho( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far ); Define a rea de visualizao para uma projeo ortogonal. De notar que os parmetros near e far so indicados relativamente ao usurio, ou seja near deve ser menor que far. Os parmetros left, right, top e bottom devem ter em conta as dimenses atuais do viewport utilizado para que as imagens no apaream distorcidas. Todos os objetos, ou sees dos mesmos, fora do volume de visualizao indicado no so apresentadas na janela.
glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho(-2.0, 2.0, -2.0 * (GLfloat) h / (GLfloat) w, 2.0 * (GLfloat) h / (GLfloat) w, -10.0, 10.0); else glOrtho(-2.0 * (GLfloat) w / (GLfloat) h, 2.0 * (GLfloat) w / (GLfloat) h, -2.0, 2.0, -10.0, 10.0); glMatrixMode(GL_MODELVIEW);
void glFrustum( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble znear, GLdouble zfar ); Permite definir uma perspectiva. Os parmetros left, right, top, bottom e znear definem a rea de visualizao mais prxima do observador, o parmetros zfar define o plano de corte mais distante. De notar que tanto znear como zfar tem de ser maiores que zero. Da mesma forma que glOrtho, estes parmetros so indicados relativamente ao observador.
glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) glFrustum(-2.0, 2.0, -2.0 * (GLfloat) h / (GLfloat) w, 2.0 * (GLfloat) h / (GLfloat) w, 10.0, 30.0); else Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL glFrustum(-2.0 * (GLfloat) w / (GLfloat) h, 2.0 * (GLfloat) w / (GLfloat) h, -2.0, 2.0, 10.0, 30.0); glTranslatef(0.0, 0.0, -20.0); glMatrixMode(GL_MODELVIEW);
void gluPerspective( GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar ); Permite definir uma perspectiva equivalente a glFrustum. O parmetro fovy indica o ngulo (em graus) de abertura vertical, aspect a relao entre a largura e a altura do viewport. znear e zfar definem os planos de corte de profundidade. Tal como em glFrustum devem ser ambos maiores que zero.
glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) gluPerspective(90.0 * (GLfloat) h / (GLfloat) w, (GLfloat) w / (GLfloat) h, 10.0, 30.0); else gluPerspective(90.0, (GLfloat) w / (GLfloat) h, 10.0, 30.0); glTranslatef(0.0, 0.0, -20.0); glMatrixMode(GL_MODELVIEW);
void gluLookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx, GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy, GLdouble upz ); Permite alterar o ponto de vista de uma perspectiva. eye.... so as coordenadas do observador, center... as coordenadas do centro da cena e up... indica o topo da cena (permitindo rodar a vista). Deve-se notar que aps gluLookAt os parmetros znear e zfar utilizados em glFrustum ou gluPerspective so relativos ao observador indicado em gluLookAt o que pode ter alguns resultados nesperados.
glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); > glLoadIdentity(); if (w <= h) gluPerspective(90.0 * (GLfloat) h / (GLfloat) w, (GLfloat) w / (GLfloat) h, 10.0, 30.0); else gluPerspective(90.0, (GLfloat) w / (GLfloat) h, 10.0, 30.0); gluLookAt(0.0, 0.0, -20.0, 0.0, 6.0, -20.0, 0.0, 0.0, -1.0); glTranslatef(0.0, 0.0, -20.0); glMatrixMode(GL_MODELVIEW);
void glTranslatef( GLfloat x, GLfloat y, GLfloat z ); void glScalef( GLfloat x, GLfloat y, GLfloat z ); void glRotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z ); Multiplicam a matriz de transformao atual pelas matrizes de translao (glTranslatef), escala (glScalef) ou rotao (glRotatef). No caso de glRotatef o ngulo indicado em graus. Na prtica Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL os objetos desenhados aps estas instrues so deslocados, esticados ou rodados de acordo com a operao realizada. Deve-se notar que importante a ordem pela qual executamos as instrues, no exemplo a seguir o ponto atual ser (3.0, 2.0, 0.0), no entanto se efetussemos as operaes por ordem inversa seria (1.5, 2.0, 0.0).
glScalef(2.0,1.0,1.0); glTranslatef(1.5,2.0,0.0);
IV Seleo de Sites
Esta seo oferece uma seleo dos considerados melhores sites para se aprender OpenGL. Os assuntos abordados vo desde um curso de C (necessrio para o entendimento dos cdigos) at a criao de jogos em primeira pessoa. importante ressaltar a importncia dessa parte da apostila para a continuidade dos estudos aps o curso.
01) Site oficial do OpenGL. L voc encontra diversos materiais para download, alm das ltimas notcias sobre o programa.
03) timo tutorial para iniciantes de uma professora da PUC RS. O endereo abaixo leva para um menu com 17 opes de tutoriais, desde Introduo at Luzes e Malhas de Polgonos.
04) Neste tutorial h bastante exemplos (todos comentados e explicados) e alguns exerccios para treinamento.
http://dca.ufrn.br/~ambj/ele435/opengl/index.html Biblioteca: GLUT Idioma: Portugus Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL Classificao: ***
05) Site de outro professor da PUC RS. No possui um contedo muito abrangente, mas os assuntos que so tratados so abordados de forma muito clara e objetiva. Alm disso, oferece uma grande ajuda na hora de instalar as bibliotecas utilizadas.
06) Mais um timo site para iniciantes. Trata o OpenGL de forma clara, dando tpicos sobre os clculos envolvidos nas chamadas das funes. A parte de projeo e luz muito bem explicada.
08) Este endereo nos fornece vrios tutoriais para iniciantes, alm do link para baixar um excelente livro em formato .pdf que ensina, passo-a-passo a modelagem de um ser humano caminhando.
09) Site com 14 sees sobre OpenGL. Sua nfase luz, volume de visualizao e outros recursos grficos. Infelizmente, utiliza o tk ao invs do GLUT, mas nada que atrapalhe a didtica significantemente.
10) Este site possui diversos materiais que so necessrios para se aprender OpenGL: tutoriais, livros, exemplos etc. O enfoque principal a criao de jogos. Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL
11) O prximo tutorial baseado principalmente no material disponvel no site "NeHe Productions". Os textos foram traduzidos e adaptados para utilizarem a GLUT. Infelizmente, nem tudo ainda est traduzido e alguns links falham.
12) Pgina muito boa contendo diversos materiais completos. necessrio criar um usurio e uma senha para ter acesso a todo o site. A nfase, novamente, na implementao de jogos, mas fornecido diversas informaes de computao grfica no geral, inclusive OpenGL.
13) Esta pgina tambm d nfase aos jogos. So 50 programas exemplo comeando do mais bsico (desenhar um tringulo branco na tela) e terminando com uma aplicao no jogo "Quake" (alis, feito totalmente em OpenGL). Infelizmente, no utiliza a biblioteca GLUT, o que torna o sistema de gerenciamento de janelas bem mais complicado.
http://www.gametutorials.com/Tutorials/opengl/OpenGL_Pg1.htm Biblioteca: sem biblioteca auxiliar para gerenciamento de janelas. Idioma: Ingls Classificao: *****
Downloads
14) Este endereo nos leva a uma pgina que permite o download de um .zip. Este arquivo contm 7 executveis que ajudam na vizualizao de algumas das propriedades seguintes: neblina, posio e propriedades da luz, propriedade do material, projees, transformaes, texturas e formas (primitivas OpenGL).
15) Um dos sites mais importantes, j que disponibiliza o RedBook tanto para download Programa de Aprimoramento Discente em Modelagem Geomtrica - Curso de OpenGL quanto para consulta online. Pena que ainda utiliza o GLAUX (adicionando o biblioteca GLUT, retirando a GLAUX e alterando 3 linhas do main, concertamos este "problema").
16) Este site, essencialmente terico, explica atravs de equaes e exemplos vrios dos recursos grficos possveis no OpenGL. Pena que no tem nenhum exemplo ou referncia a ele. Ainda assim, este tutorial um recurso importante para improvisar o realismo usando qualquer programa de computao grfica.
18) Outro guia para consultas rpidas. Este, ao contrrio do anterior, extremamente completo, contendo mais de 100 funes do OpenGL (o que representa quase todas elas) bem explicadas alm de vrios comandos Glu. No oferece material para GLUT.
http://www.deec.uc.pt/~peixoto/dcg/opengl/opengl.html Biblioteca: sem GLUT Idioma: Ingls Classificao: ****