Sumário ao OpenGL Exemplos Leandro Tonietto Processamento Gráfico / Computação Gráfica Jogos Digitais ltonietto@unisinos.br http://www.inf.unisinos.br/~ltonietto Mar-2008 Alguns slides são provenientes da apresentação do professor Christian Hofsetz O que é OpenGL? [1] Open Graphics Library Interface de software para hardware gráfico. É uma biblioteca de modelagem e gráficos 3D, altamente portável e muito rápida. Independente de SO e de hardware. Muito mais rápido do que implementação puramente em software, como: motores de gráficos ou software de ray-tracing. Inicio: Biblioteca gráfica desenvolvida para rodar aplicações gráficas sobre o hardware proprietário da Silicon Graphis Inc. (SGI). Primeira versão foi o IRIS GL, biblioteca gráfica das estações IRIS Graphics da SGI. Hardware que provia transformações de matrizes com altíssima performance. OpenGL surge da decisão de portar a IRIS GL para um padrão aberto, para suportar outros fabricantes de dispositivos gráficos, outras plataformas de hardware e outros sistemas operacionais. OpenGL ARB: API aberta não pode ser de propriedade de uma empresa apenas. Surge então o OpenGL Architecture Review Board (ARB) Consórcio, originalmente, formado por SGI, Digital Equipament Corporation, IBM, Intel e Microsoft. Outras empresas fazem parte do consórcio, como: SUN, nvidia, ATI,... 01/07/1992 sai a primeira versão da especificação da OpenGL. A partir de 2006 SGI transfere o controle sobre o padrão OpenGL para o grupo de trabalho The Khronos Group (www.khronos.org). Atualmente, este grupo promove o OpenGL e outros padrões como o OpenGL ES (para dispositivos móveis). OpenGL está na versão 2.0. Software x hardware: SW tem muito menos performance que HW e alguns efeitos especiais podem ser proibitivos nas aplicações gráficas. SW pode executar em qualquer plataforma sem que o usuário necessite de hardware especial, no caso hardware gráfico. HW tem performance, porém maior custo. OpenGL interage com o hardware. Uma aplicação gráfica que use a OpenGL necessitará que o dispositivo gráfico (placa-devídeo) e o driver gráfico implementem a especificação da OpenGL. 1
Como funciona a OpenGL API Procedural. Programador invoca comandos OpenGL para compor uma cena. De forma mais básica, os objetos são desenhados com primitivas gráficas: pontos, linhas e polígonos em 3D. Permite visualização de objetos em qualquer ponto de um espaço 3D. OpenGL suporta também iluminação e sombra, mapeamento de textura, blending, transparência, animação e diversos outros efeitos especiais. Faz a conversão das primitivas para imagem rasterização. Não possui funcionalidades para gerenciamento de janela, interação com o usuário ou acesso a arquivos (I/O). É necessário utilizar alguma biblioteca adicional (GLUT) Também não existe nenhum formato de arquivo associado ao OpenGL para modelos ou ambientes virtuais. O programador deve fazer a carga e interpretação dos formatos de arquivos comuns e converter para primitivas gráficas. Como funciona a OpenGL OpenGL em software x em hardware Implementação Microsoft Processamento passa por GDI Mais lenta Limitação de funcionalidades X Implementação no driver do HW Comunicação direta com dispositivo Mais lento Como funciona a OpenGL Pipeline OpenGL Aplicação executa chamadas as funções da API da OpenGL. Comandos e dados (vértices, textura e etc) são armazenados no command buffer. Quando do flush os vértices passam pelo processamento matemático (transformações geométricas e de iluminação) Depois é feita a rasterização para cria uma imagem colorida a partir da geometria, cor e dados de textura. A imagem é colocada num framebuffer, que é a memória do dispositivo gráfico. Bibliotecas OpenGL Microsoft Windows opengl32.dll OpenGL utility library (GLU) glu32.dll Conjunto de funções utilitárias para tarefas comuns e complexas, algumas matrizes especiais para cálculo e suporte para curvas e superfícies. Headers: gl.h header de prototipação das funções OpenGL glu.h header de prototipação das funçoes GLU Exemplo de #include para um programa OpengGL: #include <windows.h> // não vem no VisualC++ Express #include <gl/gl.h> #include <glu/glu.h> #include glee.h // extensões da OpenGL #include glut.h // freeglut Tipos de dados para se usar com a API OpenGL Convenção de nomes glvertex3f(0.0f, 0.0f, 0.0f); glvertex3i(0, 0, 0); glvertex3v(vertex[0]); 2
Convenção de nomes Começam com gl... Próximas palavras começa com a primeira letra maiúscula. glbegin() Constantes começam com GL_ e são sempre em maiúsculas. GL_COLOR_BUFFER_BIT Lembre-se: OpenGL é máquina de estados, desenha primitivas e o estado das variáveis altera o resultado da síntese da imagem. Um objeto é desenhado com a cor que está definida, com iluminação que está definida, com as transformações previamente definidas e etc. Portanto, um vez definida um propriedade, ela ficará residente até tenha o seu estado limpo ou alterado com outro valor. Por exemplo, quando uma cor é definida ela será usada em qualquer processo de colorização até que ocorra um novo comando de cor. OpenGL faz interação com usuário, portanto, não gerencia entrada e saída de dados. É necessário o uso de alguma biblioteca para gerenciamento de GUI. Padrão GLUT. Como uma máquina de estados, os comandos também podem ter seu estado definido/alterado apenas como ligado ou desligado. glenable() e gldisable() É o caso da iluminação: glenable(gl_lighting) CUIDADO: a troca frequente de estados afeta a performance. O melhor é setar os estados uma vez só, quando possível. Desenho de primitivas: Basicamente, é a definição dos vértices das primitivas e das propriedades de cor, normais, texturas e etc. Tudo definido entre glbegin(<primitiva>) e glend() Exemplo: glbegin(gl_triangles); glcolor3f(0.0, 0.0, 1.0); glvertex3f(0.0, 0.0, 0.0); glvertex3f(1.0, 0.0, 0.0); glvertex3f(0.5, 0.5, 0.0); glend(); Outros comandos utilizados dentro do bloco: glcolor*(), glnormal*(), glmaterial*() Primitivas: Primitivas: Primitiva / Constante GL_POINTS GL_LINES GL_LINE_STRIP GL_LINE_LOOP GL_TRIANGLES GL_TRIANGLE_STRIP GL_TRIANGLE_FAN GL_QUADS GL_QUAD_STRIP GL_POLYGON Descrição Pontos individuais Par de vértices = 1 linha Pontos conectados por linhas = strip + 1 linha para fechar 3 pontos = 1 triângulo Série de triângulos conectados Todos tri compartilham ponto zero 4 pontos = 1 quadrilátero Série de quads. conectados Todos pontos = 1 polígono 3
Primitivas. Exemplos: Tipos de polígonos: glbegin(gl_polygon); // ou glbegin(gl_points); glvertex2f(0.0, 0.0); glvertex2f(0.0, 3.0); glvertex2f(4.0, 3.0); glvertex2f(6.0, 1.5); glvertex2f(4.0, 0.0); glend(); Válidos Inválidos Objetos curvos são aproximados por retas: Exemplo. Desenhando um círculo: #define PI 3.1415926535898 GLfloat circle_points = 100; glbegin(gl_line_loop); for (i = 0; i < circle_points; i++) { angle = 2*PI*i/circle_points; glvertex2f(cos(angle), sin(angle)); } glend(); Tratamento de erros em OpenGL: Quando fazemos algo inválido em OpenGL ou GLU o programa não pára; apenas não faz o que a gente espera. Isso dificulta a depuração! Quando um erro ocorre um flag é setado com um código de erro. Para acessar esse código deve-se usar glgeterror(); Por outro lado cada chamada OpenGL a mais afetam a performance Em alguns casos quando queremos renderização em tempo real temos que eliminar o maior número possível dessas chamadas! Lembre-se: todos os comandos são bufferizados e processados. Matrizes: Três tipos de matrizes: GL_MODELVIEW: A matriz modelview controla as transformações dos vértices dos objetos da cena GL_PROJECTION A matriz de projeção controla como a cena 3-D é projetada em 2-D GL_TEXTURE A matriz de texturas (geralmente pouco conhecida e utilizada) transforma as coordenadas das textura para obter efeitos como projetar e deslocar texturas 4
Matrizes de projeção: glfrustum(left,right,bottom,top,near,far) glortho(left,right,bottom,top,near,far) gluperspective(fovy,aspect,znear,zfar) gluortho2d(left,right,bottom,top) glulookat(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz) Coordenadas de Tela glviewport(x, y, width, height) Transformações: Modelagem gltranslate{fd}(x, y, z) glrotate{fd) (angle, x, y, z ) glscale{fd}(x,y,z) Propriedades Materiais glmaterial*() ambiente, difuso, especular Fontes de Luz gllight*() cor, posição, atenuação, etc Exemplo: // Estabelece o modo de projeção glmatrixmode(gl_projection); // limpa matrizes glloadidentity(); // especifica o Frustum glfrustum(-1, 1, -1, 1, 0.0, 40.0); // habilita estado de modelagem glmatrixmode(gl_modelview); // cria matriz de transformação glpushmatrix(); // define uma transformação de rotação em X,Y,Z glrotatef(45.0, 1.0, 1.0, 1.0); render(); // invoca um método do programa glpopmatrix(); Dicas: Lembre-se que a origem do OpenGL é no canto esquerdo (e é baseado em um sistema de coordenadas left-hand ) Lembre-se de (1) ativar o modo de preenchimento desejado (por ex.: glenable(gl_depth_test);) e de (2) Limpar os respectivos buffers! (por ex.: glclear(gl_color_buffer_bit GL_DEPTH_BUFFER_BIT);) Evitar mudanças constantes de estado Maior freqüência de erros: posicionamento de câmera. Atente-se para olhar de um ponto e para um ponto que seja coerente com os objetos renderizados. Dicas: Ao manipular as matrizes OpenGL lembre-se de verificar se o tipo de matriz correto está ativado. Por exemplo: glmatrixmode(gl_projection); glloadidentity(); glfrustum(-1, 1, -1, 1, 0.0, 40.0); /* glmatrixmode(gl_modelview); */ glpushmatrix(); glrotatef(45.0, 1.0, 1.0, 1.0); render(); glpopmatrix(); Alguns métodos normalmente presentes em programas OpenGL: init() inicializiação de variáveis e de estados permanentes. display() é que a coisa acontece!! Desenho das primitivas e definição dos estados relacionados a elas, como cor, textura e outros aspectos. update() alterações a serem realizadas quando do redimensionamento da janela. getinputs() processamento de entradas como teclado e mouse. 5
Exemplos de código para o método init(): void init(){ glmatrixmode(gl_projection); glloadidentity(); gluperspective(50.0, 1.0, -10.0, 7.0); glenable(gl_lighting); const float specularcolor[] = {1.0f, 0.0f, 1.0f, 0.5f}; gllightfv(gl_light0, GL_SPECULAR, specularcolor); } Exemplos de método update(): Exemplos de método display(): Exemplos de método getinputs(): Fake or Real? OpenGL Bibliografias www.opengl.org www.khronos.org OpenGL Programming Guide (Woo, Neider, Davis - Addison-Wesley ) OpenGL Programming for the X Window System OpenGL Game Programming (Astle, Hawkins, LaMothe) 6
Referências bibliográficas WRIGHT Jr., Richard S.; LIPCHAK, Benjamin; HAEMEL, Nicholas. OpenGL Superbible: Comprehensive Tutorial and Reference. 4ed.: Addison-Wesley. 2007. Slides do prof. Dr. Christian Hofsetz. 7