Introdução a OpenGL Profª. Alessandra Martins Coelho março/ 2013
OpenGL OpenGL é uma API gráfica que permite a criação de imagens gráficas 2D e 3D, através da definição de objetos (2D/3D) por um conjunto de formas primitivas geométricas e rotinas para manipulação; consiste em cerca de 150 comandos distintos usados para especificar os objetos e operações necessárias para produzir aplicativos tridimensionais interativos.
OpenGL A API do OpenGL foi projetada para ser usada com C ou C++. Mesa implementação livre do OpenGL Jogl - para Java
OpenGL As especificações OpenGL não descrevem as interações entre OpenGL e o sistema de janelas utilizado. O OpenGL foi projetado para ser independente do SO e do sistema de janelas. Para ser completamente independente, o OpenGL não oferece rotinas de display ou interface (pois precisam de E/S). GLUT (OpenGL ToolKit), FDL
OpenGL como máquina de estados Todos os estados ou modos habilitados nas aplicações têm efeito enquanto os mesmos estiverem ligados ou forem modificados
O Pipeline do OpenGL A maior parte das implementações OpenGL tem uma ordem de operações a serem executadas. Uma série de estágios de processos chamam o pipeline de renderização do OpenGL.
Ambiente OpenGL para desenvolvimento As bibliotecas do OpenGL são distribuídas como parte dos sistemas operacionais da Microsoft, porém as mesmas podem ser baixadas no site oficial do OpenGL : http://www.opengl.org. Disponíveis também para MacOS, Unix Solaris e Linux.
Instalando o OpenGL e GLUT no DEV-C++ bibliotecas OpenGL http://www.opengl.org. O ambiente Windows já deve conter as DLLs necessárias para execução dos programas OpenGL. Pasta System ou System32 do Windows - opengl32.dll e glu32.dll. a pasta C:\Dev-C++\Include\GL contém os arquivos gl.h, glaux.h e glu.h pasta C:\Dev-C++\Lib contém os arquivos opengl32.def, glaux.def e glu32.def. Faça o download do arquivo glut-devc.zip e descompacte o mesmo; Mova o arquivo glut.h para a pasta GL do DevC++ (C:\Dev-C+ +\Include\GL); Mova os arquivos glut32.def e libglut.a para a pasta Lib do DevC++ (C:\Dev-C++\Lib); Mova o arquivo glut32.dll para a mesma pasta onde se encontram os arquivos opengl32.dll e glu32.dll (system)
Configure o compilador para utilização de OpenGL no menu Projeto, opções do Projeto, parâmetros, no campo linker as diretivas de ligação -lopengl32 lglut32 lglu32
Linux As bibliotecas necessárias para instalar: apt-get install freeglut3 freeglut3-dbg freeglut3-dev apt-get install build-essential Como compilar: gcc -lglut -lglu -lgl <nome do programa.c> -o <nome do programa.exe> Como Rodar:./nome do programa.exe
Estrutura Básica de Programas OpenGL declaração dos arquivos de header para o OpenGL; configurar e abrir a janela; inicializar os estados no OpenGL; registrar as funções de callback ; renderização; redimensionamento; entradas : teclado, mouse, etc.; entrar no loop de processamento de eventos.
Estrutura Básica de Programas OpenGL #include <GL/gl.h> #include <GL/glut.h> void main( int argc, char** argv ) { int mode = GLUT_DOUBLE GLUT_RGB; glutinitdisplaymode( mode ); glutinitwindowsize(400,350); glutinitwindowposition(10,10); glutcreatewindow( argv[0] ); init(); glutdisplayfunc( display ); glutreshapefunc( resize ); glutkeyboardfunc( key ); glutidlefunc( idle ); glutmainloop(); }
Estrutura Básica de Programas OpenGL #include <GL/gl.h> #include <GL/glut.h> void main( int argc, char** argv ) { int mode = GLUT_DOUBLE GLUT_RGB; glutinitdisplaymode( mode ); glutinitwindowsize(400,350); glutinitwindowposition(10,10); glutcreatewindow( argv[0] ); init(); glutdisplayfunc( display ); glutreshapefunc( resize ); glutkeyboardfunc( key ); glutidlefunc( idle ); glutmainloop(); } criar uma cena fora da tela para depois, rapidamente, colocá-la na janela de visualização DOUBLE ou SINGLE
Estrutura Básica de Programas OpenGL #include <GL/gl.h> #include <GL/glut.h> void main( int argc, char** argv ) { int mode = GLUT_DOUBLE GLUT_RGB; glutinitdisplaymode( mode ); glutinitwindowsize(400,350); glutinitwindowposition(10,10); glutcreatewindow( argv[0] ); init(); glutdisplayfunc( display ); glutreshapefunc( resize ); glutkeyboardfunc( key ); glutidlefunc( idle ); glutmainloop(); } as cores são especificadas através do fornecimento de intensidades dos componentes red, green e blue separadas RGB ou RGBA
Estrutura Básica de Programas OpenGL #include <GL/gl.h> #include <GL/glut.h> void main( int argc, char** argv ) { int mode = GLUT_DOUBLE GLUT_RGB; } glutinitdisplaymode( mode ); glutinitwindowsize(400,350); glutinitwindowposition(10,10); glutcreatewindow( argv[0] ); init(); glutdisplayfunc( display ); glutreshapefunc( resize ); glutkeyboardfunc( key ); glutidlefunc( idle ); glutmainloop(); Tamanho da janela a ser criada
Estrutura Básica de Programas OpenGL #include <GL/gl.h> #include <GL/glut.h> void main( int argc, char** argv ) { int mode = GLUT_DOUBLE GLUT_RGB; glutinitdisplaymode( mode ); glutinitwindowsize(400,350); Posição da janela na tela glutinitwindowposition(10,10); do computador glutcreatewindow( argv[0] ); init(); glutdisplayfunc( display ); glutreshapefunc( resize ); glutkeyboardfunc( key ); glutidlefunc( idle ); glutmainloop(); }
Estrutura Básica de Programas OpenGL #include <GL/gl.h> #include <GL/glut.h> void main( int argc, char** argv ) { int mode = GLUT_DOUBLE GLUT_RGB; glutinitdisplaymode(mod); } glutinitwindowsize(400,350); glutinitwindowposition(10,10); glutcreatewindow(... ); init(); glutdisplayfunc( display ); glutreshapefunc( resize ); glutkeyboardfunc( key ); glutidlefunc( idle ); glutmainloop(); Neste momento serão inicializados quaisquer estados OpenGL, que serão executados na execução do programa
Estrutura Básica de Programas OpenGL #include <GL/gl.h> #include <GL/glut.h> void main( int argc, char** argv ) { int mode = GLUT_DOUBLE GLUT_RGB; } glutinitdisplaymode(mod); glutinitwindowsize(400,350); glutinitwindowposition(10,10); glutcreatewindow(... ); init(); glutdisplayfunc( display ); glutreshapefunc( resize ); glutkeyboardfunc( key ); glutidlefunc( idle ); glutmainloop(); ações de callback qqr evento ocorrendo no sistema: -redimensionamento de janela; - entradas de usuários através de teclado, mouse, ou outro dispositivo de entrada; - ocorrência da animações.
diferentes tipos de ações de callback glutdisplayfunc() chamada quando um pixel na janela necessita ser atualizado. glutreshapefunc() chamado quando a janela é redimensionada. glutkeyboardfunc() chamada quando uma tecla do teclado é pressionada. glutmousefunc() chamada quando o usuário pressiona um botão do mouse. glutmotionfunc() - chamada quando o usuário movimenta o mouse enquanto mantém um botão do mesmo pressionado. glutpassivemousefunc() chamado quando o mouse é movimentado, independente do estado dos botões. glutidlefunc() uma função de callback chamada quando nada está acontecendo. Muito útil para animações.
Estrutura Básica de Programas OpenGL #include <GL/gl.h> #include <GL/glut.h> void main( int argc, char** argv ) { int mode = GLUT_DOUBLE GLUT_RGB; glutinitdisplaymode( mode ); glutinitwindowsize(400,350); glutinitwindowposition(10,10); glutcreatewindow( argv[0] ); init(); } glutdisplayfunc( display ); glutreshapefunc( resize ); glutkeyboardfunc( key ); glutidlefunc( idle ); glutmainloop(); entrar em um processo de loop, o qual interpreta os eventos e chamadas das rotinas especificadas como callback
Modelo int main(int argc, char **argv) { glutinit(&argc, argv); glutinitdisplaymode(glut_single GLUT_RGB); glutinitwindowsize(500, 500); glutinitwindowposition(100, 100); glutcreatewindow("introdução a OPENGL - Computação Gráfica - março/2013"); init(); glutdisplayfunc(desenha); glutreshapefunc(resize); glutkeyboardfunc(keyinput); glutmainloop(); return 0; }
Modelo void desenha(void) { glclear(gl_color_buffer_bit); glcolor3f (1.0, 0.0, 0.0);... glflush(); }
Modelo void init(void) { glclearcolor(0.0, 0.0, 0.0, 0.0); }
Modelo void resize(int w, int h) { glviewport(0, 0, (GLsizei)w, (GLsizei)h); // Set viewport size to be entire OpenGL window. glmatrixmode(gl_projection); // Set matrix mode to projection. glloadidentity(); // Clear current projection matrix to identity. // Specify the orthographic (or perpendicular) projection, // i.e., define the viewing box. glortho(0.0, 100.0, 0.0, 100.0, -1.0, 1.0); glmatrixmode(gl_modelview); // Set matrix mode to modelview. } glloadidentity();
Viewport: Definindo a área de desenho O viewport corresponde a uma região na janela realmente criada, onde o nosso desenho é exibido. Sempre que a janela muda de tamanho/forma, não é necessário mudar o desenho, apenas o viewport. Você também pode usar o viewport para aumentar ou diminuir o tamanho da imagem. Por padrão, o viewport do OpenGL ocupa toda a janela. glviewport( x, y, GLsizei width, GLsizei height)
Modelo // uso do teclado void keyinput(unsigned char key, int x, int y) { switch(key) { case 27: // Press escape to exit. exit(0); break; default: break; } }
Sintaxe de Comandos do OpenGL Todos os comandos utilizam-se do prefixo gl em letras minúsculas. Similarmente, OpenGL define constantes com as iniciais GL_, em letras maiúsculas, e usa um underscore para separar as palavras Ex: glcolor3f(); GL_COLOR_BUFFER_BIT
Glvertex3fv(v) Nº de Componentes 2 (x,y) 3 (x,y,z) 4 (x,y,z,w) Tipo de dados b byte ub unsigned byte s short us unsigned short i int ui unsigned int f float d double Vetor Omite v para a forma escalar
Primitivas glbegin(primitiva); glvertex3f(*,*,*);// v 0 glvertex3f(*,*,*);//v 1... glvertex3f(*,*,*);//v n-1 glend();
GL_POINTS Desenha apenas pontos no plano. v 0, v 1,..., v n-1
GL_POINTS glcolor3f (1.0, 0.0, 0.0); glpointsize(15); glbegin(gl_points); glvertex2f(25,25); glvertex2f(25,75); glvertex2f(75,25); glvertex2f(75,75); glend();
GL_POINTS const float distancia = 5.0f; float y=50, pos = -1 + distancia; int i; for (i = 1; i <= 20; i ++) { glpointsize(i); glbegin(gl_points); glvertex3f(pos, y, 0); glend(); pos += distancia; }
GL_LINES Desenha linhas independentes entre dois pontos v 0 v 1, v 2 v 3,..., v n-2 v n-1
gllinewidth(5.0); glbegin(gl_lines); glcolor3f(1.0, 0.0, 0.0);// vermelho glvertex3f(20.0, 20.0, 0.0); glcolor3f(0.0, 1.0, 0.0);// verde glvertex3f(80, 20.0, 0.0); glend(); GL_LINES
GL_POINTS você pode dizer quais os valores de cor devem estar no ponto médio (50,0, 20,0, 0,0) do segmento desenhado? verificar a sua resposta desenhando um ponto com os valores de cor um pouco acima do ponto médio.
GL_LINE_STRIP Liga todos os pontos (não fecha o circuito) v 0 v 1, v 2 v 3,..., v n-2 v n-1
GL_LINE_LOOP Liga todos os pontos (fecha o circuito) v 0 v 1, v 2 v 3,..., v n-2 v n-1, v n-1 v 0
GL_TRIANGLES A cada três vértices forma um triângulo v 0 v 1 v 2, v 3 v 4 v 5,..., v n-3 v n-2 v n-1
GL_TRIANGLES glbegin(gl_triangles); glvertex2f(10,90); glvertex2f(10,10); glvertex2f(35,75); glvertex2f(30,20); glvertex2f(90,90); glvertex2f(80,40); glend();
GL_TRIANGLE_ STRIP - Liga uma série de triângulos, formando uma tira com os mesmos. v 0 v 1 v 2, v 1 v 3 v 2, v 2 v 3 v 4,...,v n-3 v n-2 v n-1 (para n ímpar) v 0 v 1 v 2, v 1 v 3 v 2, v 2 v 3 v 4,..., v n-3 v n-1 v n-2 (para n par)
GL_TRIANGLE_STRIP glpolygonmode(gl_front_and_back, GL_LINE); glbegin(gl_triangle_strip); glvertex3f(10,90, 0); glvertex3f(10,10, 0); glvertex3f(35,75, 0); glvertex3f(30,20, 0); glvertex3f(90,90, 0); glvertex3f(80,40, 0); glend();
Exercício 1 Usando GL_TRIANGLE_STRIP reproduza as figuras abaixo:
GL_TRIANGLE_FAN A palavra "fan" significa leque em português. Ou seja, cria-se um leque no plano. v 0 v 1 v 2, v 0 v 2 v 3, v 0 v 3 v 4,..., v 0 v n-2 v n-1
GL_TRIANGLE_FAN
GL_QUADS A cada quatro vértices definidos, é desenhado um quadrado na tela. V 0 v 1 v 3 v 2,v 4 v 5 v 6 v 7,..
GL_QUADS glpolygonmode(gl_front_and _BACK, GL_LINE); glbegin(gl_quads); glcolor3f (0.0, 0.0, 1.0); glvertex3f(10,90,0); glvertex3f(10,10,0); glvertex3f(40,20,0); glvertex3f(35,75,0); glcolor3f (0.0, 0.7, 1.0); glvertex3f(15,80,0); glvertex3f(20,10,0); glvertex3f(90,20,0); glvertex3f(90,75,0); glend();