OpenGL Tomás Antônio C. Badan 1 Introdução ao OpenGL Projetada para ter um processamento eficiente em aplicações em 3 dimensões Pode lidar com cenas em 2 dimensões, como um caso especial (coordenada z = 0) É altamente portável e muito rápida É independente de qualquer linguagem de programação É definido uma language binding para as linguagens mais usuais C, C++, java, python, etc • Usaremos a linguagem C 2 Introdução ao OpenGL (2) Fornece um conjunto básico de: primitivas gráficas, atributos, transformações geométricas, transformações de visualização, etc Projetada para ser independente do hardware Operações de E/S não são definidas Deixadas para bibliotecas auxiliares Mouse, teclado, gerência de janelas, etc 3 Introdução ao OpenGL (3) Proposto e criado pela SGI Objetivo é vender hardware Mais programas disponíveis mais hardware vendido Proposto como um padrão aberto Criado o OpenGL Architecture Review Board (ARB) Originalmente composto por SGI, Digital Equipament Corporation, IBM, Intel e Microsoft 4 Introdução ao OpenGL (4) 2006 → SGI transfere controle da ARB para o grupo Khronos (www.khronos.org) Pode ser implementada sob 2 perspectiva Hardware → muito mais eficiente Software → bem mais lenta mas permite rodar programas em ambiente que não possui implementação em hardware nativo 5 A Guerra das APIs OpenGL → mais fácil de programar do que Direct3D (antes de 1998) Grande atrativo para desenvolvimento de games em plataformas de baixo custo Microsoft proveu um driver kit que facilitou o desenvolvimento do OpenGL no Windows98 Cortou anos de esforços no desenvolvimento de um driver robusto Microsoft desencorajou vendedores de usar um modelo de desenvolvimento mais robusto 6 A Guerra das APIs (2) Antes do lançamentos do window98 Microsoft não iria estender a licença de seu driver kit para o OpenGL Proibiu qualquer vendedor de hardware de liberar seus drivers. OpenGL fadada ao esquecimento 7 Futuro do OpenGL Vendedores de hardware continuaram a suportar o OpenGL com novos drivers Aplicações especificas pudessem rodar em versões domésticas do Windows DirectX era para jogos OpenGL é mais fácil de programar do que DirectX Programadores voltaram a utilizá-la intensamente São quem decide o futuro da indústria Hoje, largamente suportada em hardwares8 Implementação Genérica Exemplos: OpenGL nativo no windows → Baixa performance Implementação típica no windows Mesa3d → não oficial do OpenGL → solução aberta Rasterizar → processo de transformar informações geométricas em pontos no monitor 9 Implementação em Hardware Aplicação típica no Windows 10 Pipeline do OpenGL 11 Sintaxe das Funções OpenGL Conhecida como OpenGL basic library ou OpenGL core library São todas prefixadas com “gl” Funções: glBegin, glClear, etc Constantes: GL_2D, GL_RGB, etc Tipos: GLbyte, GLfloat, GLboolean, etc 12 Tipos de Dados do OpenGL Suffix Data Type b s i f 8-bit integer 16-bit integer 32-bit integer 32-bit floating-point Typical Corresponding CLanguage Type signed char short int or long float d 64-bit floating-point double ub 8-bit unsigned integer unsigned char us 16-bit unsigned integer 32-bit unsigned integer unsigned short GLbyte GLshort GLint, GLsizei GLfloat, GLclampf GLdouble, GLclampd GLubyte, GLboolean GLushort unsigned int or unsigned long GLuint, GLenum, GLbitfield ui OpenGL Type Definition 13 Formato das Instruções 14 Bibliotecas Relacionadas GLU (OpenGL Utility) Inicializa algumas matrizes de visualização e projeção Descreve objetos complexos com aproximações de linhas e polígonos Mostra curvas quadráticas e B-spline por aproximação linear Processa operações de renderização de superfícies, dentre outras Funções são prefixadas por “glu” Toda distribuição OpenGL vem com essa biblioteca 15 Bibliotecas Relacionadas (2) GLUT (OpenGL Utility Toolkit) Processa informações que são dependentes do sistema de gerenciamento de janelas em uso (windows, X, etc) Processa E/S (mouse, teclado, etc) Permite a criação simples de menus do tipo cascata Suporta fontes do tipo bitmap e vetoriais Etc Processamentos dirigido por eventos de Callback Rotinas para temporização e processamento “idle'' Funções para descrever objetos 3D, representados por sólidos ou wireframes Funções são prefixadas por “glut” Implementação atual → freeglut 16 Coordenadas Cartesianas 17 GLUT ANSI C binding para a maioria dos parâmetros das rotinas (int, char*) Para as rotinas em OpenGL: tipos dos OpenGL (GLfloat) Sistema de coordenadas é da tela Expressa em pixels 18 GLUT – Programa Esqueleto #include <GL/glut.h> #include <stdlib.h> #include <stdio.h> // algumas variáveis globais GLint width = 640, height = 480; // prototype das funções void init(void); void desenha(void); void redimensiona(int width, int height); void teclado(unsigned char key, int x, int y); int main(int argc, char *argv[]) { // inicialização do sistema de janelas glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); glutInitWindowPosition(1, 1); glutInitWindowSize(width, height); void init(void) { // inicializações pertinentes à aplicação glClearColor(1.0, 1.0, 1.0, 0.0); // fundo branco redimensiona(width, height); glMatrixMode(GL_MODELVIEW); glColor3i(0, 0, 0); // cor atual: preto } void desenha(void) { // desenha o quadro principal glClear(GL_COLOR_BUFFER_BIT); glGlRectf(-25.0, 25.0, 25.0, -25.0); glFlush(); // força a execução dos comandos } void redimensiona(int w, int h) { width = w; height = h; glutCreateWindow("Titulo da janela"); init(); glViewport(0, 0, w, h); // inicializa o sistema de visualização glMatrixMode(GL_PROJECTION); glLoadIdentity(); // limpa a matriz atual gluOrtho2D(0.0, (GLdouble) width, 0.0, (GLdouble) height); // Registra os callbacks glutDisplayFunc(desenha); glutReshapeFunc(redimensiona); glutKeyboardFunc(teclado); // entra no loop principal e aguarda eventos glutMainLoop(); } glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } 19 GLUT – Programa Esqueleto (2) void teclado(unsigned char key, int x, int y) { static GLboolean fullScreen = 0; switch (key) { default : glWindowPos2i(x, height - y); glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, key); break ; case 'f': case 'F': if ( !fullScreen) { glutFullScreen(); fullScreen = 1; } else { glutReshapeWindow(width, height); fullScreen = 0; } break ; case 'q': case 'Q': case 27: // escape exit(EXIT_SUCCESS); case 13: // return desenha(); break ; } } 20 Cabeçalho Note a inclusão da linha #include <GL/glut.h> Inclui nos programas os cabeçalhos #include <GL/gl.h> #include <GL/glu.h> Inclui também algumas funções que são dependentes do SO em uso 21 GLUT – Funções de Inicialização void glutInit(int *argcp, char **argv); Primeira rotina a ser chamada void glutInitWindowSize(int width, int height); Se X ou Y for negativo: posição é deixada para o sistema de janelas escolher Valores são sugestões para o sistema de janela Valor default: 300x300 pixels. Valores devem ser maiores do que zero void glutInitWindowPosition(int x, int y); Somente funções que são prefixadas com glutInit podem ser chamadas antes Não precisam ser necessariamente obedecidos void glutInitDisplayMode(unsigned int mode); GLUT_RGBA GLUT_RGB Equivalente a GLUT_RGBA. GLUT_SINGLE ← Buffer simples GLUT_DOUBLE ← Usado para realizar animação etc 22 GLUT – Iniciando Processamento de Eventos void glutMainLoop(void); Nunca retorna Processa todas as requisições anteriores e entra em modo de loop Aguarda por eventos Processamento via callback Chama as funções que foram anteriormente registradas 23 GLUT – Gerência de Janelas Criação e destruição: void glutSwapBuffers(void); Força a janela corrente a ser redesenhada void glutReshapeWindow(int width, int height); Somente se estiver habilitado void glutPostRedisplay(void); int glutCreateWindow(char *name); void glutDestroyWindow(int win); Requer uma mudança de dimensões void glutFullScreen(void); Não funciona 24 GLUT – Registro de Callbacks void glutDisplayFunc(void (*func)(void)); void glutReshapeFunc(void (*func)(int width, int height)); func: chamada para desenhar os objetos Mudança de dimensões da janela void glutKeyboardFunc(void (*func) (unsigned char key, int x, int y)); key: valor ASCII da tecla x e y: posição do ponteiro do mouse 25 GLUT – Registro de Callbacks (2) void glutMouseFunc(void (*func)(int button, int state, int x, int y)); void glutIdleFunc(void (*func)(void)); Captura botões do mouse É chamada quando não se tem mais nenhuma outra callback para ser chamada etc 26 GLUT - Fontes void glutBitmapCharacter(void *font, int character); Fonte em formato de bitmap void glutStrokeCharacter(void *font, int character); Fonte em formato vetorial 27 GLUT – Programa Esqueleto #include <GL/glut.h> #include <stdlib.h> #include <stdio.h> // algumas variáveis globais GLint width = 640, height = 480; // prototype das funções void init(void); void desenha(void); void redimensiona(int width, int height); void teclado(unsigned char key, int x, int y); int main(int argc, char *argv[]) { // inicialização do sistema de janelas glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); glutInitWindowPosition(1, 1); glutInitWindowSize(width, height); void init(void) { // inicializações pertinentes à aplicação glClearColor(1.0, 1.0, 1.0, 0.0); // fundo branco redimensiona(width, height); glMatrixMode(GL_MODELVIEW); glColor3i(0, 0, 0); // cor atual: preto } void desenha(void) { // desenha o quadro principal glClear(GL_COLOR_BUFFER_BIT); glGlRectf(-25.0, 25.0, 25.0, -25.0); glFlush(); // força a execução dos comandos } void redimensiona(int w, int h) { width = w; height = h; glutCreateWindow("Titulo da janela"); init(); glViewport(0, 0, w, h); // inicializa o sistema de visualização glMatrixMode(GL_PROJECTION); glLoadIdentity(); // limpa a matriz atual gluOrtho2D(0.0, (GLdouble) width, 0.0, (GLdouble) height); // Registra os callbacks glutDisplayFunc(desenha); glutReshapeFunc(redimensiona); glutKeyboardFunc(teclado); // entra no loop principal e aguarda eventos glutMainLoop(); } glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } 28 Programa Esqueleto (2) void teclado(unsigned char key, int x, int y) { static GLboolean fullScreen = 0; switch (key) { default : glWindowPos2i(x, height - y); glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, key); break ; case 'f': case 'F': if ( !fullScreen) { glutFullScreen(); fullScreen = 1; } else { glutReshapeWindow(width, height); fullScreen = 0; } break ; case 'q': case 'Q': case 27: // escape exit(EXIT_SUCCESS); case 13: // return desenha(); break ; } } 29 GLU – Funções void gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top); Define a matriz de projeção ortográfica 2D void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar); Define a matriz de projeção em perspectiva 30 GLU – Funções (2) void gluLookAt(GLdouble eyeX,GLdouble eyeY, GLdouble eyeZ, GLdouble centerX, GLdouble centerY, GLdouble centerZ, GLdouble upX, GLdouble upY, GLdouble upZ); eye*: posição dos olhos center*: para onde está olhando up*: lado de cima da câmera 31 Comentários glViewport → Define como o volume de visualização será mapeado para a janela do sistema de janelas 32 Comentários (2) Preservar a relação de aspecto Na função redimensiona: aspect = w/h; if ( w <= h ) glOrtho(-100, 100, -100/aspect, 100/aspect, 1, -1); else glOrtho(-100*aspect, 100*aspect, -100, 100, 1, -1); 33 Comentários (3) Para usar o buffer duplo: Trocar GLUT_SINGLE por GLUT_DOUBLE Faz com que todo o desenho seja realizado no buffer offscreen Chamar glutSwapBuffers() Faz a troca entre o buffer ativo e o buffer offscreen Internamente chama a função glFlush() 34 Máquina de Estado do OpenGL Várias variáveis definem como uma cena deve ser desenhada/renderizada Objeto brilha? Que tipo de luz está em uso? Tem textura a ser aplicada? Qual a perspectiva? Etc. Todas essas variáveis define um estado Uma vez definido, ele permanece até que seja alterado 35 Máquina de Estado do OpenGL (2) Vários estados são apenas on / off void glEnable(GLenum capability); void glDisable(GLenum capability); Outros uma vez fixados só mudam quando forem alterados explicitamente glColor, glShadeModel(x), glMatrixModel(..) Etc. 36 Máquina de Estado do OpenGL (3) Salvando e recuperando estados void glPushAttrib(GLbitfield mask); void glPopAttrib(GLbitfield mask); 37 OpenGL Projetado sob o paradigma Cliente/Servidor Servidor pode estar na mesma máquina ou em máquinas diferentes Cliente é o programa que faz as requisições ao Servidor Empacota várias requisições antes de enviá-las Se estiver com o buffer cheio, são enviadas glFlush() força o esvaziamento do buffer (assíncrono) glFinish() força o esvaziamento do buffer (síncrono) 38 Bibliografia Adicional http://www.opengl.org/sdk/docs/man/ • http://www.opengl.org/resources/libraries/glut/ http://www.opengl.org/resources/code/sampl es/glut_examples/examples/examples.html 39