You are on page 1of 22

Universidade Federal de Santa Maria Departamento de Eletrnica e Computao Prof. Cesar Tadeu Pozzer Disciplina: Computao Grfica pozzer@inf.ufsm.

br 09/06/2011

OpenGL Conceitos Bsicos


1 Histrico
Antes do surgimento de APIs grficas o Eficincia: Programao em C + Assembly o Uso exclusivo da CPU APIs grficas 3D antigas o PHIGS (Programmer's Hierarchical Interactive Graphics System) [1,2] o GKS (Graphical Kernel System) [3]. APIs grficas atuais o OpenGL o Direct3D o Comparativo entre APIs Placas aceleradoras

2 Caractersticas da API OpenGL


uma interface de software (API) com o hardware grfico (Ver arquivo opengl.h) escrita em linguagem C. Na verso 3.0 da API, 112 funes tornaram-se deprecated, restando 126 funes ativas. A lista das funes pode ser encontrada em: http://www.opengl.org/sdk/docs/man/xhtml/ (OpenGL Version 2.1 - Desatualizada) ou http://pyopengl.sourceforge.net/documentation/manual-3.0/index.xhtml (OpenGL version 3.0.1 - Atualizada). Veja http://pyopengl.sourceforge.net/documentation/deprecations.html para mais detalhes. Mesmo com a remoo das funes, ainda valido estudar a API antiga, pois facilita o entendimento da nova verso do OpenGL. Baseado em mquina de estados o glClearColor() o glMatrixMode() o glEnable()/glDisable() o glPolygonMode() o glColor3f() Multi-plataforma; Arquitetura bem definida; No oferece comandos para gerenciamento de janelas, nem comandos para gerao de modelos 3D complexos. Para definio de janelas, pode-se utilizar funes da biblioteca auxiliar GLUT (GL Utility Toolkit); Conjunto de primitivas geomtricas simples; o Bsicas: ponto, linha, superfcie poligonal (tringulo, quadrado, polgono convexo) o Objetos 3D: Superfcies Bzier, qudricas, esferas, poliedros.

3 Arquitetura da API OpenGL


Uma aplicao desenvolvida em OpenGL pode acessar a API de forma direta ou indireta, como mostrado no seguinte diagrama. Pode haver uma API abstrata sobre o OpenGL que pode tornar a programao em mais alto nvel. Pode-se citar como exemplos o Java3D, GLUT, dentre outros. A aplicao do usurio no pode conversar diretamente com o hardware da placa grfica.

Aplicao API Abstrata OpenGL API Software e Hardware Dispositivo de Sada Dispositivo de Entrada

Caso um computador no tiver placa grfica, ou tiver uma placa grfica antiga que no oferece muitos recursos, cabe ao driver OpenGL realizar as funcionalidades no oferecidas. Obviamente o driver executa na CPU e isso comprometer o desempenho da aplicao como um todo. Um programa OpenGL consiste de um lao infinito onde a cada passo a aplicao, geralmente escrita em linguagem C, passa para a API um conjunto de dados que devem ser processados. Esses dados mudam medida que o usurio interage com a aplicao. Aplicao usurio OpenGL: HW e SW Monitor

Dados: Vrtices Imagens Transformaes Lao renderizao

Pipeline Grfico: Geometria Rasterizao Shaders

Imagem Gerada

Programao em OpenGL x programao em C Antes dos dados serem exibidos, eles so armazenados em buffers. O OpenGL permite a especificao de 1 ou 2 conjuntos de buffers (Single ou Double Buffer). O monitor l os dados do buffer corrente no momento. O uso de dois buffers se faz necessrio para evitar que as animaes fiquem cortadas ao meio, visto que o monitor pode exibir uma cena animada que est sendo gerada. Usando buffer duplo, quando um buffer est concludo, o OpenGL passas a escrever no outro, liberando o pronto para ser exibido (ver comando glutSwapBuffers()). OpenGL: HW e SW Buffer 1 Pipeline Grfico Buffer 2 Imagem Gerada Monitor

4 Instalao do OpenGL e Bibliotecas Auxiliares


O OpenGL disponibilizado via uma API. Dois arquivos definem esta API: gl.h e glu.h. No arquivo gl.h esto definidas as funes incorporadas na API e no arquivo glu.h funes auxiliares (GL Utility) do OpenGL. As funes mias usuais da GLU incluem definio de matriz de projeo ortogrfica 2D (gluOrtho2D()), funo para especificao da posio da cmera (gluLookAt(), gluPerspective()) e funes para manipulao de curvas do tipo NURBS. Pelo fato do OpenGL ser independente do sistema de janelas, existe uma outra API chamada GLUT - GL Utility Toolkit (glut.h) que oferece recursos de manipulao de janelas, popup menu, tratamento de eventos de mouse e teclado e algumas primitivas grficas 3D. Por ser uma API muito difundida, distribuda juntamente com o OpenGL. A prxima seo oferece mais detalhes dos sistemas de janelas. Existem outras alternativas para o uso da GLUT. Pode-se tambm fazer uso da Freeglut, cuja interface muito semelhante (http://freeglut.sourceforge.net/), e opensource. Outra opo o uso da prpria API do Windows para fazer o gerenciamento de janelas e tratamento de eventos. Pode-se tambm utilizar a API GLFW (http://www.glfw.org/), que ser apresentada na prxima seo. Outra alternativa o uso da lib SDL (http://www.libsdl.org/). Tambm oferece recursos para mdias de udio e vdeo. Para configurar o OpenGL necessrio que os seguintes arquivos (.h, .lib e .dll) estejam nas seguintes localizaes. Arquivo gl.h glut.h glu.h opengl32.lib glut32.lib glu32.lib opengl32.dll glut32.dll glu32.dll Localizao [compiler]\include\GL

[compiler]\lib

[system]

Todos estes arquivos podem ser colocados juntamente com o projeto. Neste caso deve-se alterar os parmetros do projeto. Para o Dev-C++, o arquivo opengl32.lib, por exemplo, chamado libopengl.a. A sintaxe do makefile semelhante forma como as libs so especificadas no projeto do Dev-C++. g++ -O0 -g3 -Wall -c *.cpp g++ -oapp meu_programa.o -L"./" -lglut -lGLU -lGL -lm Para mais detalhes de configurao de parmetros nos compiladores DEV-C++ e Microsoft .NET, consulte a documentao da API Canvas2D.

4.1 GLFW
A GLFW (http://www.glfw.org/) ama API aberta para a criao de aplicaes baseadas em OpenGL. A maior diferena em relao Glut que esta deixa o controle do loop de renderizao no cdigo do usurio. Pode-se tambm fazer uma aplicao sem o uso de callbacks. A distribuio possui uma verso da lib que no exige biblioteca dinmica (dll) para execuo. Um programa feito com a GLFW tem a seguinte estrutura bsica: 3

#include <GL/glfw.h> int main() { glfwInit(); glfwOpenWindowHint(GLFW_WINDOW_NO_RESIZE, GL_TRUE); glfwOpenWindow(800, 600, 8, 8, 8, 8, 24, 8, GLFW_WINDOW); bool running = true; while (running) { // trata eventos // Exibe algo na tela glfwSwapBuffers(); running = glfwGetWindowParam(GLFW_OPENED) != 0; } glfwTerminate(); }

Para maiores detalhes, veja demo no site da disciplina ou consulte seu manual.

4.2 GLUT e Sistemas de Janelas


O OpenGL foi projetado para ser independente do sistema de janelas e sistema operacional. Deste modo, no possui comandos para abertura de janelas e leitura de eventos do teclado e mouse. A biblioteca mais difundida para gerenciamento de janelas em OpenGL a GLUT. Ela muito limitada quando comparada com outras APIs mas simples de usar e oferece recursos para construo de aplicativos com interface simples, o que a torna uma atrativa ferramenta de auxlio ao aprendizado do OpenGL. A GLUT tambm possui diversas rotinas para especificao de objetos 3D como esfera, torus e o famoso bule de ch chamado Utha Teapot. Funes para gerenciamento de Janelas Existem 5 rotinas principais para inicializao de uma janela: void glutInit(int *argcp, char **argv): Inicializa a GLUT. void glutInitDisplayMode(unsigned int mode): Especifica o nmero de buffers a serem utilizados e parmetros dos buffers: GLUT_SINGLE, GLUT_DOUBLE, GLUT_DEPTH, GLUT_STENCIL, GLUT_ACCUM). void glutInitWindowPosition(int x, int y): Especifica a posio do canto esquerdo superior da janela. void glutInitWindowSize(int width, int height): Especifica o tamanho da janela em pixels. int glutCreateWindow(const char *title): Cria uma janela com um contexto OpenGL.

Janela padro Windows

Popup menu da GLUT

Funes de Callback As funes de callbacks so utilizadas para registrar na GLUT funes definidas pelo usurio (ponteiros para funo) que vo tratar os eventos da aplicao. Isso necessrio porque a GLUT assume o controle da aplicao to logo seja chamada a funo glutMainLoop(), podendo a aplicao do usurio intervir somente quando estes eventos ocorrerem. Os principais comandos so listados a seguir. Para uma lista completa de funes, veja [4, 5, 6].

user.cpp
Inicializaes glut Registro callbacks
glutMainLoop()

glut

opengl

Callback Mouse Callback Teclado Outras callbacks

void glutDisplayFunc(void (*func)(void)): Callback mais importante. Usada para especificao da funo de desenho. Chamada sempre que o contexto da janela precisa ser reexibido. Todas as rotinas usadas para redesenho da cena devem estar nesta callback de display (ver glutIdleFunc()). void glutReshapeFunc(void (*func)(int width, int height)): Registra a funo para tratar o redimensionamento da janela.

void glutKeyboardFunc(void (*func)(unsigned char key, int x, int y)) e void glutMouseFunc(void (*func)(int button, int state, int x, int y)): funes para tratamento de teclado ou boto de mouse. void glutMotionFunc(void (*func)(int x, int y)): trata movimento do mouse enquanto algum boto estiver pressionado. void glutPassiveMotionFunc(void (*func)(int x, int y)): trata movimento do mouse. void glutKeyboardUpFunc(void (*func)(unsigned char k, int x, int y)): tratamento de liberao de teclas pressionadas. void glutIdleFunc(void (*func)(void)): funo chamada sempre que no existem evento a serem tratados. Pode ser usada para processamento de tarefas em background ou de animaes, por exemplo.

Uma aplicao desenvolvida com a GLUT tem a seguinte estrutura:


#include <gl/glut.h> void init() { //comandos de inicializao do opengl (definio dos estados). } void render() { //todos os dados e parmetros a serem passados ao OpenGL para renderizar cada quadro da cena devem ser colocados nesta funo que est associada callback display e a callback idle. } void OnReshape(int w, int w) { //ao a ser realizada quando a janela redimensionada } void OnKeyPress() { //ao a ser realizada quando uma tecla pressionada } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DEPTH | GLUT_RGBA | GLUT_DOUBLE); glutInitWindowSize(640,480); glutCreateWindow("Titulo da janela"); glutDisplayFunc(render); glutIdleDisplayFunc(render); glutReshapeFunc(OnReshape); glutKeyboardFunc(OnKeyPress); OnInit(); //inicializacoes customizadas glutMainLoop(); return 0; }

Na callbak onReshape() deve-se especificar aes a serem tomadas quando a janela for redimensionada. Nesta situao, os comandos mais comuns a serem utilizados so o de viewport e projeo A funo render() a responsvel pela renderizao da cena. Antes de gerar cada cena, geralmente devese limpar os dados gerados na cena anterior. Para isso existe o comando glClear(), que aceita como parmetros os mesmos buffers que podem ser definidos na inicializao da GLUT pela execuo do comando glutInitDisplayMode(): GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_ACCUM_BUFFER_BIT e GL_STENCIL_BUFFER_BIT. void glClear(GLbitfield mask); void glClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a); Ao se utilizar o comando glClear(GL_COLOR_BUFFER_BIT), utiliza-se a cor de limpeza definida pelo comando glClearColor(), usualmente chamado na funo OnInit().
void render() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); renderScene(); glutSwapBuffers(); }

4.3 Outros Sistemas de Janelas


Alm da GLUT, existem outras APIs independentes de sistema operacional que oferecem diversos recursos mais avanados para gerao de interfaces grficas. So exemplos as APIs QT [7], GTK [8], wxWidget [9] e Fox [10], dentre outras.

wxWidget

Fox

http://www-usr.inf.ufsm.br/~avelar/tutorial_qt/ www.vconrado.com/wx

5 Primitivas Geomtricas
O OpenGL oferece uma srie de primitivas geomtricas para definio dos objetos grficos. Basicamente existem 3 tipos de primitivas: pontos, linhas ou superfcies (tringulos, quadrilteros e polgonos convexos). A escolha de qual primitiva utilizar vai depender da aplicao. Deve-se observar que a mesma geometria pode ser definida por vrios tipos de primitivas, porm o nmero de vrtices utilizados pode ser diferente. Para definio de malhas poligonais triangulares deve-se preferencialmente utilizar GL_TRIANGLE _STRIP ou GL_TRIANGLE_FAN ao invs de GL_TRIANGLES. Com o uso do comando GL_TRIANGLE_FAN pode-se definir por exemplo 3 tringulos com apenas 5 vrtices. Utilizando-se GL_TRIANGLE seriam necessrios 9 vrtices. Quanto mais vrtices forem passados para o OpenGL processar, menor poder ser o desempenho geral 4 aplicao. da 2 1 3 3 1 3 5 1
0 2 0 2
GL_POINTS GL_LINES

1
GL_LINE_LOOP

GL_LINE_STRIP

2 1 0 3 4 5 0 1 3 5 1

2 1

4 0
GL_TRIANGLE_FAN

GL_TRIANGLES

GL_TRIANGLE_STRIP

5 1 4

2 3

0 3

4
GL_QUADS

0 2
GL_QUAD_STRIP

4
GL_POLYGON

Primitivas geomtricas OpenGL. Extrada de [12] Para a especificao de vrtices, deve-se utilizar o comando do OpenGL glVertex*(). Este comando, como diversos outros (glColor*(), glNormal*(), glFog*(), glLight*(), glMaterial*(), glRotate*(), glTranslate*(), glScale*()), aceitam at 8 diferentes tipos de dados como argumentos. As letras usadas como sufixo para especificar os tipos de dados so mostradas na seguinte tabela. Deve-se observar que todos os comandos OpenGL iniciam com o prefixo gl e que todas as constantes iniciam com o prefixo GL_. A sintaxe do comando glVertex*() a seguinte: void glVertex{234}{sifd}[v]{TYPE coords}; Este comando especifica um vrtice que descreve um objeto geomtrico. Suporta at 4 coordenadas (x, y, z, w) e no mnimo 2. O sufixo v opcional e usado para indicar que o argumento um vetor de dados. Se for usada uma verso que no explicita z ou w, por default z=0 e w=1. Sufixo b s i f d Tipo de dado Inteiro 8 bits Inteiro 16 bits Inteiro 32 bits Float 32 bits Float 64 bits Correspondncia com C signed char short int ou long float double Tipo OpenGL GLbyte GLshort GLint, GLsizei GLfloat, GLclampf GLdouble, GLclampd

ub us ui Exemplos:

Unsigned 8 bits Unsigned 16 bits Unsigned 32 bits

unsigned char unsigned short unsigned int ou long

GLubyte, GLboolean GLushort GLuint

GLdouble pos[] = {0.1, 10, 33.123}; glVertex3dv(pos); glVertex2d(10, 22.5); glVertex3d(0.1, 10, 33.123); glVertex2i(10, 22);

Este comando deve ser chamado dentro do par de comandos glBegin() e glEnd(). void glBegin(GLenum mode); Marca o incio de uma lista de vrtices que descrevem uma primitiva geomtrica. O parmetro mode pode ser uma das 10 primitivas geomtricas descritas anteriormente (GL_POINTS, GL_LINES, ...). void glEnd(); Marca o fim de uma lista de vrtices. Dentro do bloco glBegin() - glEnd() pode-se tambm especificar atributos dos vrtices, com cor, normal, textura, dentre outros. Os principais comandos so: glVertex*(), glColor*(), glIndex*(), glNormal*(), glTextCoord*() e glMaterial*().

glBegin(tipo_de_prim); //define atributos de vrtice: cor, normal, textura,... //define o vrtice glEnd(); glBegin(GL_TRIANGLE); glVertex3d(0.1, 10, 33.123); glVertex3d(0.1, 10, 33.123); glVertex3d(0.1, 10, 33.123); glEnd(); glBegin(GL_TRIANGLE); for(int i=0; i<30; i++) glVertex3dv(data[i]); glEnd();

Consideraes: Esta forma de especificao dos vrtices no impe uma estrutura de dados. Deve-se chamar uma funo para especificar cada vrtice Insuficiente para primitivas complexas No permite compartilhamento de vrtices.

5.1 Pontos e Linhas


Pode-se tambm especificar atributos s primitivas geomtricas, por meio dos comandos void glPointSize(GLfloat size): determina a largura em pixels do ponto. O tamanho deve ser maior que zero e o default 1. Os pixels a serem desenhados dependem se o antialiasing estiver habilitado. Se o antialiasing estiver desabilitado (default - glEnable(GL_POINT_SMOOTH), larguras fracionrias sero arredondadas para larguras inteiras e ser gerado um quadrado de pixels. Com o

antialiasing ativo, um grupo circular de pixels ser gerado, sendo os pixels na borda geralmente tendo intensidades mais fracas. void glLineWidth(GLfloat width): Determina a largura em pixels de uma linha. O tamanho deve ser maior que zero e o default 1. Pode-se tambm gerar linhas com antialiasing (glEnable(GL_LINE_SMOOTH)). void glLineStipple(GLint factor, GLushort pattern): Permite a gerao de linhas com padres configurveis. O argumento padro um conjunto de 16 bits 0s e 1s. O parmetro factor usado para esticar o padro gerado. Deve-se habilitar esta caracterstica com o comando glEnable(GL_LINE_STIPPLE).

Pattern
0x00FF 0x00FF 0x0C0F 0xAAAA

Factor
1 2 1 1

5.2 Polgonos
Polgonos podem ser desenhados de forma preenchida, apenas com as linhas e contorno (bordas do polgono) ou somente os vrtices. Um polgono tem dois lados (front e back), que podem ser renderizados diferentemente dependendo do lado que o observador estiver observando. Isso pode ser til para diferenciar partes que esto dentro ou fora de objetos. O comando glPoligonMode() usado para determinar a forma de desenho de polgonos. void glPolygonMode(GLenum face, GLenum mode); O parmetro face pode assumir GL_FRONT_AND_BACK, GL_FRONT, ou GL_BACK. mode pode ser GL_POINT, GL_LINE, ou GL_FILL para indicar se o polgono deve ser desenhado por pontos, linhas ou de forma preenchida (default).
glPolygonMode(GL_FRONT, GL_FILL); glPolygonMode(GL_BACK, GL_LINE);

Por converso, polgonos cujos vrtices aparecem em ordem anti-horrio na tela so chamados front-facing. Pode-se mudar esta conveno com o comando glFrontFace() caso os vrtices dos objetos forem definidos em ordem horria. Os argumentos podem ser GL_CCW (default) ou GL_CW. void glCullFace(GLenum mode); void glFrontFace(GLenum mode); Ao se construir um objeto fechado composto por polgonos opacos com uma orientao consistente, nenhum polgono back-facing ser visvel. Neste e em outros casos, pode-se otimizar a renderizao removendo-se as faces cuja face da frente no seja visvel. O comando glCullFace() diz ao OpenGL para descartar polgonos front- ou back-facing. Os argumentos so GL_FRONT, GL_BACK, ou GL_FRONT_AND_BACK. Deve-se habilitar o recurso de culling com o comando glEnable(GL_CULL_FACE).

10

5.3 Vetores Normais


O OpenGL permite a especificao de normais por faces (polgono) ou por vrtices. O comando glNormal3*() usado para a especificao de uma normal. O vetor normal utilizado para clculos de iluminao. void glNormal3{bsidf}(TYPE nx, TYPE ny, TYPE nz); void glNormal3{bsidf}v(const TYPE *v); Uma vez setado um valor de normal, este permanece o valor corrente da normal at que outro comando de normal seja chamado. No seguinte exemplo define-se uma normal para cada vrtice do polgono. Caso fosse definida somente a normal n0, todos os vrtices v0...v3 compartilhariam a mesma normal.
glBegin (GL_POLYGON); glNormal3fv(n0); glVertex3fv(v0); glNormal3fv(n1); glVertex3fv(v1); glNormal3fv(n2); glVertex3fv(v2); glNormal3fv(n3); glVertex3fv(v3); glEnd();

Deve-se observar que qualquer superfcie possui duas normais, apontando em direes opostas. Por conveno, a normal o vetor que aponta para fora do objeto sendo modelado. A norma dos vetores normais passados ao OpenGL irrelevante, porm deve-se observar que antes de aplicar processos de iluminao as normais devem ser normalizadas. o De preferncia, deve-se passar vetores normalizados. o Estes vetores permanecem normalizados exceto se forem aplicados transformaes de escala modelview. o Transformaes de translao e rotao no alteram as normais. o Em caso de transformaes no uniformes como escalas ou especificao de normais no normalizadas, pode-se requisitar que o OpenGL automaticamente as normalize aps as transformaes. Para isso, deve-se habilitar a normalizao com o comando glEnable(GL_NORMALIZE). Esse recurso esta desabilitado por default, visto que requer clculos adicionais que podem reduzir o desempenho da aplicao. As normais so sempre aplicadas sobre vrtices. Por isso, ao se usar strips (por exemplo GL_QUAD_STRIP), deve-se ter em mente que no se pode aplicar a normal por face, o que probe a gerao de objetos fechados como cubos, onde deve existir somente uma normal por face.

6 Modelos de Shading
Existem vrios modelos de iluminao (ou interpolao de cores) de polgonos: Constante: clculo de iluminao por polgono. Todo o polgono vai ter a mesma cor, o que em algumas aplicaes pode ser desejvel, como por exemplo observar a geometria do objeto. um algoritmo muito eficiente. Esta tcnica implementada no OpenGL e pode ser ativada com o comando glShadeModel(GL_FLAT). Gouraud: clculo de iluminao por vrtice. Faz interpolao de cor a partir da cor calculada para cada vrtice do tringulo. Apesar de rpido, a qualidade depende da resoluo da malha. Caso a reflexo especular mxima ocorre no centro de um tringulo grande, ela pode ser descartada complemente, devido a interpolao de cores entre vrtices. Para solucionar este problema, deve-se refinar a malha de polgonos. Esta tcnica implementada no OpenGL e pode ser ativada com o comando glShadeModel(GL_SMOOTH).

11

Phong: clculo de iluminao por pixel. Aplica-se uma interpolao de normais para cada pixel do tringulo. Tem melhor qualidade, a um custo computacional muito mais alto. Esta tcnica no implementada no OpenGL. As seguintes figuras ilustram a aplicao de dois modelos de shading: GL_FLAT (constante) e GL_SMOOTH (Gouraud).

As seguintes figuras ilustram a diferena entre o modelo flat e o modelo Phong Shading.

Flat shading Phong Shading [http://en.wikipedia.org/wiki/Phong_shading]


O algoritmo de Gouraud, como mostrado na seguinte figura, faz uma interpolao de cores, gerando resultados diferenciados em funo da posio dos tringulos. Esse efeito no ocorre com a tcnica Phong Shading.

Variao da reflexo especular em funo do posicionamento de tringulos. [http://en.wikipedia.org/wiki/Gouraud_shading] No seguinte exemplo ilustra-se um cdigo OpenGL para gerao do tringulo apresentado com variao contnua de cores.
glShadeModel(GL_SMOOTH); glBegin(GL_TRIANGLES); glColor3f(1.0,0.0,0.0); glVertex2f(-1.0,-1.0); glColor3f(0.0,1.0,0.0); glVertex2f(1.0,-1.0); glColor3f(0.0,0.0,1.0); glVertex2f(0.0,1.0); // default // red // green // blue

12

glEnd( );

Para se gerar o tringulo azul, basta especificar o modelo de shading como GL_FLAT. Observa-se no segundo exemplo que a especificao de cores por vrtice no tem efeito. Leva-se em considerao apenas a ltima cor especificada.
glShadeModel(GL_FLAT); glColor3f(0.0,0.0,1.0); // blue glBegin(GL_TRIANGLES); glVertex2f(-1.0,-1.0); glVertex2f(1.0,-1.0); glVertex2f(0.0,1.0); glEnd( ); glShadeModel(GL_FLAT); glBegin(GL_TRIANGLES); glColor3f(1.0,0.0,0.0); // red glVertex2f(-1.0,-1.0); glColor3f(0.0,1.0,0.0); // green glVertex2f(1.0,-1.0); glColor3f(0.0,0.0,1.0); // blue glVertex2f(0.0,1.0); glEnd( );

Para especificao de cores, deve-se utilizar o comando glColor*(). Este comando aceita 3 ou 4 argumentos (RGB e Alpha), em coordenadas inteiras ou flutuantes. Caso o parmetro Alpha no for especificado, ele automaticamente setado para 1. void void void void glColor3{b glColor4{b glColor3{b glColor4{b s s s s i i i i f f f f d d d d ub ub ub ub us us us us ui} (TYPE r, TYPE g, TYPE b); ui} (TYPE r, TYPE g, TYPE b, TYPE a); ui}v (const TYPE*v); ui}v (const TYPE*v);

As formas mais comuns de se utilizar este comando so com parmetros f e ub, com intervalos entre [0.0, 1.0] e [0, 255], respectivamente. Internamente ao OpenGL, todas as cores so tratadas como valores reais entre [0.0, 1.0].

7 Visualizao
O OpenGL oferece trs matrizes de transformao: projection, modelview e texture (GL_MODELVIEW, GL_PROJECTION, ou GL_TEXTURE). A matriz projection (GL_PROJECTION) usada para determinar as transformaes de recorte e projeo. A projeo pode ser: o projeo ortogrfica o Projeo em perspectiva A matriz modelview (GL_MODELVIEW) usada para indicar as transformaes aplicadas: o aos modelos da cena (transformaes de modelos) o posio da cmera (coordenadas de visualizao). Uma transformao de visualizao (cmera) muda a posio e orientao do viewpoint (ponto de visualizao). Como o nome sugere, esta matriz acumula transformaes geomtricas aplicadas a objetos da cena, bem como coordenadas de visualizao da cmera sinttica (no caso de uma visualizao 3D). Apenas uma matriz pode ser modificada de cada vez. A matriz default a modelview. Todas as matrizes tm dimenso 4x4. A visualizao das cenas composta por vrias transformaes: modelview, projection e viewport. As transformaes de viewing devem preceder transformaes de modelagem em um programa OpenGL. Devem ser definidas preferencialmente na callback onReshape(). Operaes de viewport e projeo podem ser especificadas em qualquer local do cdigo, desde que antes da imagem gerada ser exibida. A seqncia de operaes realizadas para visualizao mostrada na seguinte figura. Detalhes matemticos destas transformaes podem ser encontradas em [11].

13

Vrtices

Matriz Modelview

Matriz Projeo

Perspectiva

Transformao Viewport

Coordenadas Objetos

Coordenadas do olho

Coordenadas de recorte

Coordenadas dispositivo normalizadas

Coordenadas de janela

As coordenadas do olho so resultantes da aplicao de transformaes de modelagem e de cmera sinttica. As coordenadas de recorte so geradas a partir do volume de viso gerados pela matriz de projeo em perspectiva ou ortogrfica. As coordenada de janela so geradas pela transformao de viewport.

Tanto a matriz modelview como a matriz projection so na verdade pilhas de matrizes de transformao que permitem operaes de insero e remoo de matrizes de transformao. Cada matriz, como j mencionado, tem dimenso 4x4 (em coordenadas homogneas). Seguindo a filosofia de uma pilha, somente o elemento do topo pode ser modificado. Push Topo da pilha Pop

.
Base da pilha O recurso de pilha de matrizes de transformaes til para construo de modelos hierrquicos, no qual objetos complexos so construdos a partir de objetos simples. Ao se desenvolver um jogo, por exemplo, transformaes aplicadas ao cenrio devem tambm ser aplicadas a todos os elementos da cena. Transformaes aplicadas sobre personagens, devem levar em considerao a transformao do mundo bem como a transformao do personagem. O mesmo pode ser aplicado sobre o brao de um rob: transformaes aplicadas base tm influncia em todo o brao. Transformaes aplicadas s extremidades, devem tambm levar em considerao transformaes aplicadas em sees anteriores do brao. Existem diversos comandos para manipulao destas matrizes. Todos estes comandos operam sobre a pilha ativa, determinada pelo comando glMatrixMode(). void glMatrixMode(GLenum mode): Define a pilha de matrizes ativa. Tem como argumentos GL_MODELVIEW, GL_PROJECTION, ou GL_TEXTURE. void glPushMatrix(void): Insere no topo da pilha uma cpia da matriz que estava no topo at ento, ou seja, faz uma duplicao da matriz do topo. void glPopMatrix(void): Remove a matriz do topo da pilha, destruindo seu contedo. A matriz que estava uma posio abaixo torna-se o novo topo. void glLoadIdentity(void): Usado para inicializar a matriz topo da pilha ativa com a matriz identidade. void glLoadMatrix{fd}(const TYPE *m): Seta os 16 valores da matriz (4x4) corrente com a matriz especificada em m. Para o OpenGL a matriz m deve estar no formato coluna-linha, diferentemente da especificao da linguagem C. Deste modo, sugere-se declarar m como sendo m[16] ao invs de m[4][4].

14

void glMultMatrix{fd}(const TYPE *m): Multiplica a matriz corrente pela matriz passada em m. O valor resultante armazenado na prpria matriz. Toda as multiplicaes de matriz no OpenGL operam de forma que a matriz corrente C multiplicada pela matriz argumento M da seguinte forma CM, que no igual MC (a propriedade comutativa no se aplica multiplicao de matrizes).

7.1 Transformaes do Modelo


O OpenGL oferece trs comandos para transformaes de modelos geomtricos. Todas as transformaes so aplicadas em relao a origem do sistema de coordenadas. void glTranslate{fd}(TYPE x, TYPE y, TYPE z): Multiplica a matriz corrente por uma matriz que move (translada) um objeto por valores x, y, e z (ou move o sistema de coordenadas local pelo mesmo valor). void glRotate{fd}(TYPE angle, TYPE x, TYPE y, TYPE z): Multiplica a matriz corrente por uma matriz que rotaciona um objeto (ou o sistema de coordenadas local) em sentido anti-horrio ao redor de um raio que parte da origem e que passa pelo ponto (x, y, z). O ngulo de rotao especificado em graus. void glScale{fd}(TYPE x, TYPE y, TYPE z): Multiplica a matriz corrente por uma matriz que escala ou reflete um objeto em relao a cada eixo proporcional aos argumentos x, y, e z. Para se aplicar seqncias de transformaes a objetos deve-se observar a ordem em que as operaes so aplicadas. Como mencionado anteriormente, a aplicao de uma transformao matriz corrente ocorre no lado direito, ou seja, se a matriz corrente C, a multiplicao de uma matriz M resulta em CMv, onde v um vrtice do objeto. Caso for necessrio aplicar trs transformaes A, B e C nesta seqncia, deve-se definir a seguinte seqncia de transformaes:
glMatrixMode(GL_MODELVIEW); glLoadIdentity(); (Matriz Identidade I) glMultMatrixf(C); (Matriz C) glMultMatrixf(B); (Matriz CB) glMultMatrixf(A); (Matriz CBA) glBegin(); glVertex3fv(v); glEnd();

Deste modo, a matriz de transformao contm sucessivamente I, C, CB, CBA. O vrtice transformado CBAv. Deste modo, a transformao do vrtice C(B(Av)), ou seja , v inicialmente multiplicado por A, o resultado Av por B e na seqncia por C, ou seja, a multiplicao ocorre na ordem inversa da especificao. Na prtica, o n v multiplicado por uma matriz resultante de CBA. A especificao dos comandos de transformao do OpenGL segue um sistema de coordenadas global fixo, que exige uma ordem inversa para especificao. Outro sistema o sistema local mvel associado a cada objeto, que faz uso de uma ordem natural das transformaes. Neste segundo caso, o sistema de coordenadas fixo a cada objeto da cena. Se o objeto se mover, o sistema de coordenadas move tambm. Todas as operaes so relativas ao novo sistema de coordenadas. Nos seguintes exemplos ilustra-se os dois sistemas. Sistema local mvel glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRotatef(45,0,0,1); glTranslatef(10,0,0); Sistema global fixo (OpenGL) glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRotatef(45,0,0,1); glTranslatef(10,0,0);

15

No seguinte exemplo, o primeiro comando de translao tem efeito em toda a cena. Com o comando glPushMatrix(), pode-se associar transformaes especficas a cada elemento da cena. Aps desenhar o primeiro cubo, desempilha-se e volta-se ao estado global para pode ento aplicar a transformao ao cubo vermelho.
void render() { ... glMatrixMode(GL_MODELVIEW); glLoadIdentity( ); ... glTranslated(0.1, 0, 5); renderTable(); glPushMatrix(); glColor3f(0, 0, 1); glTranslated(-0.5, 0.15, 0.5); glutWireCube(0.2); glPopMatrix(); glPushMatrix(); glColor3f(1, 0, 0); glTranslated(0.5, 0.15, -0.5); glRotated(90, 0, 1, 0); glutWireCube(0.2); glPopMatrix(); ...

Origem do sistema de coordenadas global fixo

7.2 Transformaes da cmera


Como j mencionado, uma transformao de visualizao (cmera) muda a posio e orientao do viewpoint (ponto de visualizao). A cmera sinttica possui uma posio, direo de visualizao e um vetor up que indica a sua rotao em relao ao vetor direo de visualizao. A cmera default do OpenGL est posicionada na origem, apontada na direo do eixo z negativo, com o vetor up alinhado com o eixo y positivo. A transformao de viewing deve estar associada a matriz de modelview. Existem algumas formas de aplicar transformaes de viewing: Usar um ou mais comandos de transformaes de modelos, como glRotate*() e glTranslate*(); Usar o comando gluLookAt(). Supondo como exemplo que se tenha um objeto centrado na origem, na mesma posio que a cmera esta definida. Neste caso, mover a cmera para traz (z positivo) ou mover o objeto para frente (z negativo) tem o mesmo efeito. A mesma analogia pode ser feita em relao rotaes. void gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx, GLdouble centery,GLdouble centerz, GLdouble upx, GLdouble upy, GLdouble upz)

16

Define uma matriz de visualizao que multiplicada direita da matriz corrente. O vetor eye especifica onde a cmera est posicionada, center onde a cmera est olhando (coordenadas absolutas do sistema global fixo) e up a inclinao da cmera. O comando gluLookAt() deve ser chamado antes das operaes de transformaes dos modelos da cena, caso contrrio ele no ter efeito na visualizao da cena. As transformaes aplicadas por este comando mudam a matriz modelview de modo que a cena vista como se a cmera estivesse alinhada ao eixo z, apontada em direo ao z negativo. O comando glutLookAt() no est disponvel na API do OpenGL visto que um comando que faz uso de vrios comandos bsicos do OpenGL como glRotate*() e glTranslate*().

7.3 Projees
O OpenGL oferece comandos para definio de dois tipos de projeo: ortogrfica e perspectiva. Estas duas projees afetam a matriz projection, por isso deve-se torn-la ativa com o comando glMatrixMode(GL_PROJECTION). Um timo material sobre o assunto pode ser encontrado em http://www.songho.ca/opengl/gl_transform.html#projection.
Volume de viso

h fovy w Transformao de projeo

cmera

near

far

canonical view volume


Varia entre [-1, 1] em cada eixo

O objetivo da projeo a definio do volume de viso, que usado para determinar como um objeto ser projetado na tela e quais objetos ou parte de objetos sero removidos da imagem final. Com esta estratgia de recorte, objetos atrs da cmera so automaticamente eliminados, o que no ocorre quanto se utiliza um modelo de cmera sem recorte. Para aplicar projeo em perspectiva pode-se utilizar o comando glFrustum() ou o comando da API auxiliar gluPerspective(). A utilizao deste segundo comando mais intuitiva e por isso descrita neste tutorial. void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble near, GLdouble far); void glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far);

17

O comando gluPerspective() cria uma matriz para gerao do frustum (the portion of a solid normally a cone or pyramid which lies between two parallel planes cutting the solid [Wikipedia]) de viso em perspectiva e a multiplica pela matriz corrente. Para a demonstrao das matrizes de transformao, consulte http://www.songho.ca/opengl/gl_projectionmatrix.html. fovy o ngulo do campo de viso no plano x-z e deve estar no intervalo [0, 180]. Quanto maior for, maior a abertura da lente da cmera sinttica. aspect a razo de aspecto do frustum e dado por w/h. near e far so valores de distncia entre o viewpoint e os planos de recorte, ao longo do eixo z negativo. Outra forma de projeo a ortogrfica. Nos seguintes exemplos ilustra-se a utilizao de uma matriz de projeo ortogrfica para cenas 2D (sem a componente z). Nestes exemplos, utiliza-se uma viewport do tamanho da janela de desenho. Utiliza-se o comando gluOrtho2D() (ver comando glOrtho() para projees ortogrficas de cenas 3D) para especificao da matriz de projeo ortogrfica. A rea de recorte tem como parmetros as coordenadas do canto esquerdo inferior (left-bottom) e do canto direito superior (right-top). void gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top); void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far);
void onReshape(int w, int h) { ... glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, w, 0, h); (1) gluOrtho2D(w, 0, 0, h); (2) gluOrtho2D(0, w, h, 0); (3) gluOrtho2D(w, 0, h, 0); (4) gluOrtho2D(0, w*2, 0, h); (5) glMatrixMode(GL_MODELVIEW); }

Nestes exemplos, as coordenadas da figura variam entre [0, w] em largura e [0, h] em altura, ou seja, proporcionais s dimenses de especificao da rea de recorte. Toda informao gerada pela projeo ortogrfica deve ser exibido dentro da viewport, com transformaes sempre que necessrio. Para o exemplo 5, como a projeo gera um volume de viso 2x mais largo que a largura da janela, ao ser exibida na viewport esta informao tem que ser reescalada, resultando em uma deformao do objeto. Em muitos casos conveniente especificar a figura com coordenadas entre [0, 1] ou [-1, 1]. Neste caso, deve-se mudar a matriz de projeo para a escala apropriada.

18

gluOrtho2D( 0, 1, 0, 1); gluOrtho2D(-1, 1, -1, 1);

O comando gluOrtho2D() altera a matriz de projeo, por isso deve-se definir com o comando glMatrixMode(GL_PROJECTION) que a matriz corrente a matriz de projeo. Uma vez configurada a matriz de projeo, volta-se a habilitar a matriz de modelview (GL_MODELVIEW). Isso indica que as transformaes subseqentes iro afetar a modelview ao invs da matriz de projeo.

7.4 Viewport
Aps os clculos de projeo, como ltima etapa do processo aplica-se a transformao de viewport. A determinao da viewport pode ser dada de vrias maneiras, como mostrado no seguinte exemplo. Observe que a especificao da viewport deve ocorrer preferencialmente na callback onReshape(). O comando glViewport(x,y,width,height) usado para determinar a rea disponvel da janela para desenho. Os dois primeiros argumentos indicam a origem da janela e os outros dois a dimenso. Esse o motivo do porque utilizar este comando na callback de reshape() sempre que a janela mudar de tamanho, deve-se mudar o tamanho da viewport. Utilizando-se os parmetros w e h, mantm-se a proporcionalidade desejada. Este comando somente necessrio caso a viewport no for do tamanho da janela.
(largura, altura) void onReshape(int { glViewport(0, glViewport(w/2, glViewport(0, glViewport(w/2, glViewport(0, ?????????; ... } w, int h) 0, h/2, 0, h/2, 0, w, w, w/2, w/2, w, h ); h ); h/2); h/2); h/2); (1) (2) (3) (4) (5) (6)

Canto inferior (0,0)

Como pode ser observado nas figuras, caso o tamanho da viewport for maior que o tamanho da janela, haver um recorte dos objetos fora da janela. Se a viewport for menor que a janela, todos os objetos desenhados sero reescalados para serem exibidos dento da viewport. Pode-se tambm exibir duas ou mais viewports dentro de uma mesma janela (Figura 6). Neste caso, deve-se definir uma viewport, renderizar os objetos, redefinir outra viewport e desenhar os novos objetos.

8 Modelagem de Objetos
Para se criar cenrios em OpenGL pode-se importar modelos j prontos (por exemplo, do 3D Studio Max) ou criar seus prprios modelos, com o uso de primitivas bsicas que o OpenGL 19

oferece. Apesar da ltima ser um processo mais trabalhoso, fica desvinculado de arquivos de dados auxiliares. Ao se criar objetos modelados com as primitivas do OpenGL deve-se tomar cuidado em relao orientao das faces. Como ilustrado na seo de Primitivas Geomtricas, a ordem que os vrtices so definidos fundamental para se obter uma superfcie com os vrtices definidos em ordem horria ou anti-horria (counterclockwise padro do OpenGL) Caso os vrtices forem definidos em ordem errada, surgiro problemas na iluminao e na remoo de superfcies ocultas (glEnable(GL_CULL_FACE);).

9 Iluminao
O OpenGL permite a definio de fontes luminosas, modelos de iluminao e caractersticas dos materiais (o que tem influncia direta na reflexo da luz). A iluminao fundamental para dar a noo de profundidade. Sem iluminao, uma esfera e um disco possuem a mesma representao. Para se visualizar uma cena 3D sem o uso de iluminao, pode-se utilizar texturas ou fazer a visualizao em wireframe.

[http://en.wikipedia.org/wiki/Phong_reflection_model] O OpenGL oferece clculo da iluminao Ambiente, Difusa e Especular (Gouraud). Cada componente tratada e configurada separadamente para cada componente RGB, o que permite fazer operaes que no ocorrem no mundo real. A cor deve ser especificada para as fontes como para os materiais. Na fonte, especifica-se a cor que a conte ir emitir. Se R=G=B=1, a fonte ir emitir cor branca, e tem a intensidade mxima. Se os valores forem 0.5, a fonte ainda emitir branco, porm com apenas 50% da intensidade. Se somente R=1, a fonte emitir cor vermelha. No material especifica-se a taxa de reflexo de cada componente. Se R=1 e G=0.5, o material reflete toda luz vermelha incidente e apenas 50% da cor verde e no reflete a cor azul. Considerando-se que a fonte emite (LR, LG, LB), que o material reflete (MR, MG, MB), desconsiderando-se todos outros efeitos de reflexo, a luz que chega ao observador dada por (LR*MR, LG*MG, LB*MB). Caso existir mais de uma fonte, caso a somatria de intensidades LR1+LR2+..LRn for maior que 1, este valor truncando em 1 (funo clamp). Para ser aplicada a iluminao a uma cena necessita-se: 1. Definio dos vetores normais da superfcie 2. Ativao e definio da fonte de luz 3. Selecionar um modelo de iluminao 4. Definio de propriedades dos materiais dos objetos da cena. Para a ativao das fontes de luz (Passo 1), deve utilizar os seguintes comandos: glEnable(GL_LIGHTING); glEnable(GL_LIGHT0);

20

glEnable(GL_LIGHT7); O OpenGL permite a definio de at 8 fontes. Por default a fonte 0 tem cor branca e as demais a cor preto. Para mudar a cor, dentre outros parmetros da fonte (Passo 2), deve-se utilizar o comando glLightf*v().

void glLight{if}v(GLenum light, GLenum pname, TYPE *param); light: Especifica o ID da fonte que deve ser especificada. Pode assumir os seguintes valores: GL_LIGHT0, GL_LIGHT1, ... , ou GL_LIGHT7. pname: define a caracterstica a ser alterada da fonte light. Pode-se passar os seguintes argumentos: o GL_AMBIENT: intensidade RGBA ambiente da luz o GL_DIFFUSE: intensidade RGBA difusa da luz o GL_SPECULAR: intensidade RGBA especular da luz o GL_POSITION: posio (x, y, z, w) da luz. w deve ser 0. o GL_SPOT_DIRECTION: direo (x, y, z) do spotlight. o GL_SPOT_EXPONENT: expoente do spotlight. o GL_SPOT_CUTOFF: ngulo de corte (float). O default 180 (sem restrio) o GL_CONSTANT_ATTENUATION: fator de atenuao constante (float). o GL_LINEAR_ATTENUATION: fator de atenuao linear (float). o GL_QUADRATIC_ATTENUATION: fator de atenuao quadrtico (float). param: ponteiro para o conjunto de dados. Pode ter 1, 3 ou 4 componentes, dependendo do argumento pname.
GLfloat GLfloat GLfloat GLfloat light_0_position[] light_0_difuse[] light_0_specular[] light_0_ambient[] = = = = { { { { 1, 1, 1, 0 }; 0, 0, 1 }; //BLUE 1, 1, 1 }; //WHITE 0.2, 0.2, 0.2 }; light_0_position); light_0_difuse); light_0_specular); light_0_ambient);

glLightfv(GL_LIGHT0, glLightfv(GL_LIGHT0, glLightfv(GL_LIGHT0, glLightfv(GL_LIGHT0,

GL_POSITION, GL_DIFFUSE, GL_SPECULAR, GL_AMBIENT,

O OpenGL permite tambm a especificao de modelos de iluminao (Passo 3) com o comando glLightModel*(). O modelo usado para definir a posio do viewpoint, definir se a iluminao ser aplicada nos dois lados das faces (front- e back-facing) e para especificao da iluminao global ambiente. Para definir a iluminao global ambiente, que independe de fontes de iluminao, pode-se utilizar o seguinte comando:
GLfloat lmodel_ambient[] = { 0.2, 0.2, 0.2, 1.0 }; glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);

Neste caso, qualquer objeto da cena ter iluminao ambiente, independente da posio e configurao das fontes luminosas. Mesmo com nenhuma fonte habilitada, com este fator de iluminao ainda pode-se visualizar a cena. O prximo passo consiste na especificao dos materiais dos objetos da cena (Passo 4). Para isso existe o comando glMaterialfv().
void glMaterial{if}v(GLenum face, GLenum pname, TYPE *param);

face: indica em qual lado da face a propriedade ser aplicada. Pode assumir GL_FRONT, GL_BACK, ou GL_FRONT_AND_BACK.

21

pname: define a caracterstica a ser alterada no material. Pode-se passar os seguintes argumentos: o GL_AMBIENT: cor RGBA ambiente do material; o GL_DIFFUSE: cor RGBA difusa do material; o GL_AMBIENT_AND_DIFFUSE: cor ambiente e difusa do material; o GL_SPECULAR: cor RGBA especular do material o GL_SHININESS: expoente especular (float). o GL_EMISSION: cor RGBA emissiva do material. o GL_COLOR_INDEXES: ndice de cores. param: ponteiro para o conjunto de dados. Pode ter 1, 3 ou 4 componentes, dependendo do argumento pname.
GLfloat mat_specular[] = { 1, 1, 1, 1 }; GLfloat mat_shininess[] = { 10 }; glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);

A especificao de parmetros das fontes e materiais um trabalho que exige experimentos e prtica. No trivial encontrar uma combinao ideal de forma imediata. Deve-se observar que a iluminao do OpenGL no gera sombras. Algoritmos para sombra devem ser implementados separadamente. Se a iluminao realizada por vrtices, que estratgia pode ser utilizada para gerar um cubo, por exemplo, com uma reflexo mxima apenas no centro de uma face?

10 Referncias Bibliogrficas
[1] PHIGS. Disponvel em: http://en.wikipedia.org/wiki/PHIGS [2] PHIGS Standard. http://www.itl.nist.gov/iaui/vu/cugini/pvt/hy-top.html [3] GKS Standard. http://ngwww.ucar.edu/ngdoc/ng4.4/gks/intro.html [4] Lista comandos OpenGL, GLU e GLUT. Disponvel em: http://pyopengl.sourceforge.net/documentation/manual/index.xml [5] The OpenGL Utility Toolkit (GLUT) Programming Interface API Version 3. http://www.opengl.org/documentation/specs/glut/spec3/spec3.html [6] Woo, M.; Neider, J.; Davis, T.; Shreiner, D. OpenGL: Programming Guide. 5. ed. Massachusetts : Addison-Wesley, 2005. [7] Qt webpage. Disponvel em: http://www.trolltech.com/products/qt [8] GTK webpage. Disponvel em: http://www.gtk.org/ [9] wxWidget webpage. Disponvel em: http://www.wxwidgets.org/ [10] Fox Webpage. Disponvel em: http://www.fox-toolkit.org/ [11] http://www.cs.queensu.ca/~jstewart/454/notes/pipeline/ [12] Celes, W. Notas de Aula. PUC-Rio, 2006.

22

You might also like