Programação Gráfica 2D com OpenGL (Aulas 22, 24 e 25)



Documentos relacionados
Computação Gráfica - 04

Desenho de uma matriz de retângulos Serve de base para o exercício das cores

Introdução à Programação em OpenGL. Prof. Márcio Bueno

OpenGL, GLU e GLUT. GLUT (OpenGL Utility Toolkit) OpenGL. Linguagem. OpenGL. Esqueleto de um programa em PyOpenGL

Introdução a Prática em OpenGL

Computação Gráfica OpenGl 01

Introdução a OpenGL. Profª. Alessandra Martins Coelho

Computação Gráfica. Engenharia de Computação. CEFET/RJ campus Petrópolis. Prof. Luis Retondaro. Aula 2. Introdução a OpenGL

INTRODUÇÃO A OPENGL. Computação Gráfica

Introdução a OpenGL. Renato Rodrigues Oliveira da Silva Danilo Medeiros Eler

Introdução à Engenharia ENG1000

LAB. 1. Introdução à OpenGL

Sobre o Visual C

n À primeira vista: basta desenhar n Uma subrotina para desenhar cada tipo de objeto n Mas... n Como fazer interação? n Como estruturar a cena?

Programação 2009/2010 MEEC - MEAer Laboratório 5 Semana de 26 de outubro de 2009

IDES E PROGRAMAÇÃO. Prof. Dr. Cláudio Fabiano Motta Toledo PAE: Maurício A Dias

Cap. 4: Janelas, Visores & Recorte Gráfico

Imagem ou Desenhos e Gráficos vetorial ou raster?

Imagem e Gráficos. vetorial ou raster?

Fundamentos de Computação Gráfica

OpenGL. Introdução ao OpenGL. Sistemas de Coordenadas. OpenGL 29/04/2010. Profa. M. Cristina Profa. Rosane. Application Programming Interface (API)

Tutorial. Georreferenciamento de Imagens. versão /08/2008. Autores: Rafael Bellucci Moretti, Vitor Pires Vencovsky

Linguagem C Princípios Básicos (parte 1)

Computação Gráfica. Licenciatura em Engenharia Informática e de Computadores Taguspark / Alameda. Primeiro Teste 17 de Março de 2012

Utilizando o compilador CCS integrado ao MPLAB X

OpenGL. O que é OpenGL. O Pipeline do OpenGL. Listas de Exposição

Sistemas de Interfaces com o Usuário e OpenGL (com IUP ou GLUT)

Introdução ao OpenGL. Professora: Maria Cristina Ferreira de Oliveira. Erick Gómez Nieto Agosto, 2011 Introdução ao OpenGL

Introdução ao OpenGL e à Programação Baseada em Eventos

Processamento Digital de Imagens

Selecione a opção "Novo" -> "Atalho"

1. Crie um novo projeto Scratch. Apague o gato clicando com o botão direito e em apagar.

Tutorial para configurar as bibliotecas TerraView e Qt 3 no Visual Studio 2005

Programação Gráfica Cap 2

Guia para configurar o IDE Netbeans para desenvolver projectos em C/C++ com OpenMP:

Conceitos importantes da Computação Gráfica [3]

FCG2006 Prova sobre OpenGL e Rastreamento de Raios

Programação 2010/2011 MEEC

INF01046 Fundamentos de Processamento de Imagens. Prof. Manuel M. Oliveira

CG 2013/2014 Primeiro Teste LEIC Alameda/Taguspark

DISTRIBUINDO SUA APLICAÇÃO

INF01046 Fundamentos de Processamento de Imagens Semestre Turma A. Prof. Manuel M. Oliveira

Computação Gráfica - OpenGl 02

INTRODUÇÃO À LINGUAGEM C

Computação Gráfica II

COMPUTAÇÃO E PROGRAMAÇÃO

No Windows há basicamente dois tipos de programas de usuário:

Computação Gráfica - 06

Disciplina: INF Programação I. 1 a aula prática Introdução ao ambiente do Microsoft Visual Studio 2010

Transformações Geométricas

Anhanguera Educacional S.A. Centro Universitário Ibero-Americano

OpenGL. Computação Gráfica ISEL/DEETC/SP Computação Gráfica

INF1007: Programação 2 9 Tipos Abstratos de Dados. (c) Dept. Informática - PUC-Rio 1

Algoritmos e Estruturas de Dados I (DCC/003) Introdução à Programação de Computadores. Aula - Tópico 1

FUNDAMENTOS E APLICAÇÕES. Luis Valente

Usando o e a Internet

O Primeiro Programa em Visual Studio.net

GraphicsLib Biblioteca Gráfica 2D. Documentação

Corel Draw. Editoração Gráfica. Professor: Jarbas Araújo CENTRO EDUCACIONAL RADIER.

Uso do Easy Interactive Tools

Antes da aula. Para mudar o idioma, no canto superior esquerdo da tela, clique no botão em forma de engrenagem. Escolha Language.

1 Como compilar seu código? 2 Comandos de terminal:

Computação Gráfica. 5385: Licenciatura em Engenharia Informática. Cap. 3 Janelas e Visores. Janelas e Visores

Curso de C. Introdução by Arnaldo V. Moura e Daniel F. Ferber 3/10/ :43 AM

DISCIPLINA SIG EXERCÍCIO 1: MUDANÇA DE SISTEMA DE COORDENADAS (GEOGRÁFICAS LAT/LONG PARA UTM CÓRREGO ALEGRE)

ALTERA Quartus II. Manual

Guia prático do. Passo a passo

Estrutura de Programas e Tipos de Dados Simples

Introdução à OpenGL. SCC0250/ Computação Gráfica

INTRODUÇÃO AO USO DO DEV C++ Disciplina: Introdução à Ciência da Computação Prof. Modesto Antonio Chaves Universidade estadual do Sudoeste da Bahia

Trabalhando com MDI e Menus

NOTA: Neste tutorial foi utilizado o Visual Studio 2010 para criar o Projeto Web no qual iremos realizar os passos abaixo.

Faculdade de Computação

Aula 04 Tipos de arquivos e Fireworks

Guia e Utilização do Visual Studio.NET 2003

Transcrição:

MC102 Introdução à Programação de Computadores Programação Gráfica 2D com OpenGL (Aulas 22, 24 e 25) Felipe P.G. Bergo 1 Introdução OpenGL é uma biblioteca de funções utilizada para programar gráficos. O objetivo do OpenGL é uniformizar os comandos e primitivas geométricas usados para fazer desenhos, de forma que os fabricantes de hardware possam projetar processadores de vídeo (GPUs Graphical Processor Unit) otimizados para as primitivas de desenho usadas pelos programadores. Hoje a programação de gráficos é dominada por duas bibliotecas: OpenGL (mais antiga, compatível com vários sistemas operacionais e ambientes de programação) e DirectX (proprietária da Microsoft, usada apenas no Windows e no videogame XBox, da própria Microsoft). OpenGL não tem funções para abrir uma janela, ajustar o tamanho da janela ou obter toques no teclado, pois isto ainda é dependente do sistema operacional. Uma tentativa de deixar o OpenGL totalmente independente do sistema é a biblioteca GLUT, que define funções simples para realizar estas operações de forma compatível com todos os sistemas. As duas principais referências para OpenGL são os livros vermelho (Programming Guide) e azul (Reference Guide). Ambos os livros estão disponíveis online no site do OpenGL (http://www. opengl.org), na seção de documentação (Documentation). 2 Inicialização da GLUT e OpenGL O programa abaixo abre uma janela de 640 por 480 pixels. #include <GL/glut.h> int main(int argc, char **argv) { glutinit(&argc,argv); glutinitdisplaymode(glut_rgba GLUT_DOUBLE); glutcreatewindow("gl Exemplo 1"); glutreshapewindow(640,480); 1

glviewport(0.0,0.0,640.0,480.0); glmatrixmode(gl_projection); glloadidentity(); gluortho2d(0.0,640.0,480.0,0.0); glmatrixmode(gl_modelview); glloadidentity(); glutmainloop(); return 0; } O comando include pode variar entre ambientes de programação. Na seção final deste documento há explicações de como compilar programas OpenGL em vários ambientes. A primeira chamada, glutinit, inicializa a GLUT, avisando que nosso programa utilizará a biblioteca. Os parâmetros de linha de comando argc e argv precisam ser passados para glutinit (ponteiro para argc e o próprio argv). A segunda chamada, glutinitdisplaymode, ajusta o modo de exibição, que será com cor RGBA (RGB mais um canal de transparência, que é a forma mais eficiente pois já é implementada no hardware da maioria das placas de vídeo) e usando double-buffering. Double-buffering é uma técnica de atualização de tela na qual sempre temos duas telas no OpenGL: a tela que está sendo exibida e a tela que está sendo desenhada. Quando terminamos de desenhar, faremos uma operação de Swap (troca), exibindo a tela que era de desenho e usando a outra tela para desenhar. Esta técnica evita que os passos do desenho sejam vistos pelo usuário antes de terminar cada quadro. As chamadas glutcreatewindow e glutreshapewindow criam uma janela e a redimensiona para o tamanho dado. Em vez de glutreshapewindow, poderíamos chamar glutfullscreen(); para usar a tela toda do computador (como a maioria dos jogos). As seis chamadas seguintes estabelecem o sistema de coordenadas de desenho e sua relação com a janela ou tela do computador. Neste curso usaremos OpenGL apenas para desenhos 2D simples, e estas chamadas estabelecem um sistema cartesiano ortogonal com origem no canto superior esquerdo da janela (ou tela), indo de 0 a 640 (eixo X) e 0 a 480 (eixo Y). Para maiores informações sobre transformações de vista, veja o capítulo 3 do livro vermelho. A última chamada, glutmainloop, não retorna: ela executa o loop de eventos da GLUT, que espera eventos (a janela ser redimensionada, precisar ser repintada, algum temporizador ser chamado, uma tecla ser apertada, o mouse ser movido, etc.) e executa ações baseadas nos eventos. Para que nosso programa faça algo de útil devemos registrar tratadores de eventos antes de chamar glutmainloop. O principal tratador é o evento display, que é o evento que desenhará o conteúdo da janela. Para registrar o evento de display, usamos a função glutdisplayfunc: 2

glutdisplayfunc(display); Onde display (o nome pode ser qualquer um) deve ser uma função previamente declarada, sem parâmetros e com retorno void, que será chamada para desenhar a tela sempre que necessário. 3 Primitivas de Desenho A função que trata o evento display deve limpar a tela de desenho com a chamada glclear(gl_color_buffer_bit); desenhar o conteúdo da janela ou tela o mais rápido possível (sem realizar operações demoradas, como acesso a arquivos) e então chamar glutswapbuffers(); para trocar a tela exibida com a tela de desenho. Se, em algum momento o seu programa precisar forçar a tela a ser redesenhada, você não deve chamar a função de display diretamente. Em vez disso, chame glutpostredisplay();, que fará o laço de eventos da GLUT repintar a tela assim que possível. Chamar esta função de dentro da função de display pode causar um loop infinito, cuidado. 3.1 Primitivas Vetoriais A forma mais simples de desenhar com OpenGL é com primitivas vetoriais. Estas primitivas traçam algum tipo de desenho a partir de um conjunto de vértices. No nosso caso, os vértices terão coordenadas de duas dimensões, e serão criados com as funções void glvertex2i(int x,int y); void glvertex2f(float x,float y); A única diferença entre as duas é a especificação das coordenadas como inteiros ou como valores de ponto flutuante. Cada vértice tem uma cor associada. Ao ser criado, o vértice assume a cor atual. A cor atual pode ser modificada com as chamadas void glcolor3f(float r,float g,float b); void glcolor3ub(unsigned byte r, unsigned byte g, unsigned byte b); 3

A versão 3f usa valores entre 0.0 e 1.0 para as componentes R (Red), G (Green) e B (Blue) da cor. A versão 3ub usa valores entre 0 e 255. O Capítulo 5 do livro vermelho tem uma tabela com os intervalos de valores para outras versões de glcolor. As primitivas de desenho são delimitadas por comandos glbegin e glend: glcolor3f(1.0,0.0,0.0); glbegin(gl_points); glvertex2i(10,10); glvertex2i(20,20); glend(); A primitiva GL POINTS apenas pinta os pontos de cada vértice isoladamente. OpenGL oferece 10 primitivas de desenho (Fig. 1). Figura 1: Primitivas de desenho geométrico do OpenGL. Caso os diferentes vértices de uma figura tenha cores diferentes, o OpenGL realizará uma interpolação de cores no seu interior. A Fig. 2 mostra o resultado gerado por glbegin(gl_triangles); glcolor3f(1.0,0.0,0.0); glvertex2i(10,200); glcolor3f(0.0,1.0,0.0); glvertex2i(500,20); 4

glcolor3f(0.0,0.0,1.0); glvertex2i(400,400); glend(); Figura 2: Triângulo com vértices de cores diferentes (vermelho, verde e azul). 4 Tratadores de Eventos Alguns outros eventos que vamos querer tratar via GLUT: teclas normais do teclado (glutkeyboardfunc), teclas especiais do teclado (glutspecialfunc), botões do mouse (glutmousefunc) e temporizações (gluttimerfunc). Os protótipos abaixo indicam os tipos de retorno e dos parâmetros da função a ser passada. A sintaxe para ponteiros de funções em protótipos é estranha mesmo. void glutmousefunc(void (*func)(int button, int state, int x, int y)); void glutkeyboardfunc(void (*func)(unsigned char key, int x, int y)); void glutspecialfunc(void (*func)(int key, int x, int y)); void gluttimerfunc(unsigned int msecs, void (*func)(int value), value); Na glutmousefunc, a função passada deve receber 4 parâmetros: button, state, x, e y.button terá um dos valores GLUT LEFT BUTTON, GLUT MIDDLE BUTTON ou GLUT RIGHT BUTTON, de acordo com o botão acionado. state será ou GLUT UP ou GLUT DOWN, indicando se o botão está sendo pressionado ou solto. A função será chamada em ambos os casos (quando o botão é apertado e quando ele é solto). Os parâmetros x e y contêm as coordenadas da janela em que o evento ocorreu. Na glutkeyboardfunc, a função recebe o caractere gerado pela tecla pressionada. Os parâmetros x e y recebem a posição do mouse na janela no momento do pressionamento da tecla. A função registrada com glutspecialfunc é semelhante, e recebe eventos de teclas não-imprimíveis, como 5

teclas de função e setas de direção. Uma lista das constantes de teclas está listada na documentação da GLUT (http://www.opengl.org/resources/libraries/glut/spec3/spec3.html), mas são constantes do tipo GLUT KEY F1, GLUT KEY LEFT, etc. Na gluttimerfunc, a função passada será chamada após msecs milissegundos. Se a própria função se rearmar (chamando gluttimerfunc para si mesma), isto fará com que a função seja chamada periodicamente. Isto é a forma ideal de fazer animações e verificações periódicas. Caso a função temporizada precise forçar o redesenho da tela, deve fazê-lo com glutpostredisplay() (e nunca chamando a função de display diretamente). Na maioria dos computadores, dificilmente será possível usar tempos abaixo de 50 milissegundos. 5 Listas OpenGL permite que gravemos listas de comandos muito utilizados na placa de vídeo, evitando ter que transferir uma grande quantidade de dados toda vez que os comandos forem repetidos. Para isso usamos Listas. Cada lista é identificada por um número inteiro. Cada lista deve ser declarada entre um par de chamadas glnewlist e glendlist. Uma vez declarada, uma lista pode ser executada com glcalllist. Um conjunto de listas pode ser apagado da placa de vídeo com gldelelelists. Exemplo de definição de lista: glnewlist(1,gl_compile); // lista #1 glcolor3f(1.0,0.0,0.0); glbegin(gl_triangles); glvertex2i(0,0); glvertex2i(10,0); glvertex2i(0,10); glend(); glendlist(); Para chamar a lista criada: glpushmatrix(); gltranslatef(20.0,40.0,0.0); glcalllist(1); glpopmatrix(); No exemplo acima chamamos a lista 1 com uma matriz de translação que adiciona 20 às coordenadas X e 40 às coordenadas Y dos vértices da lista. As funções glpushmatrix e glpopmatrix salvam e restauram o sistema de coordenadas para que a translação não se aplique a outras chamadas. Um grupo de listas com identificadores adjacentes pode ser deletado como no exemplo abaixo: gldeletelists(1,10); // apaga listas de 1 a 10 gldeletelists(400,10); // apaga listas de 400 a 409 6

O primeiro parâmetro é a primeira lista ser apagada, e o segundo é o número de listas. 6 Texto Para escrever texto, o ideal é definirmos uma fonte de bitmaps, a serem carimbados na tela para compor texto. No OpenGL, um bitmap é um padrão de bits onde cada pixel ou é pintado (com a cor atual) ou não. O comando que desenha bitmaps é glbitmap. Seu protótipo é void glbitmap(int largura, int altura, float xorig, float yorig, float xmove, float ymove, void *dados); Esta função desenha um bitmap de largura altura pixels com o canto inferior esquerdo na atual posição raster e move a posição raster por (xmove, ymove). O desenho do bitmap é definido pela memória apontada por dados. A Fig. 3 tem um exemplo de uma letra S. O exemplo P4 disponível na página do curso contem uma fonte inteira. Figura 3: Definição de bitmap. A posição raster pode ser modificada com glrasterpos2i. Maiores detalhes podem ser consultados no capítulo 8 do livro vermelho. 7 Imagens De forma semelhante a bitmaps, podemos carimbar imagens coloridas com a função gldraw- Pixels: gldrawpixels(int largura, int altura, GLenum formato, GLenum tipo, void *dados); 7

Largura e altura definem o tamanho da imagem. O formato que nos interessa é GL RGB, onde nossos dados serão compostos de sequências de valores R,G,B para cada pixel. No campo tipo podemos especificar GL UNSIGNED BYTE para usar valores entre 0 e 255 para cada componente (É possível usar valores de ponto flutuante de 32 bits com GL FLOAT, por exemplo, mas isto é incomum. O capítulo 8 do livro vermelho tem uma tabela com todos os tipos permitidos). Com GL RGB e GL UNSIGNED BYTE, os dados devem apontar para uma imagem definida tal como no exercício com imagens P6 (R,G,B,R,G,B,etc.), exceto que OpenGL armazena imagens a partir da linha inferior (canto inferior esquerdo). gldrawpixels desenha a imagem com o canto inferior esquerdo na atual posição raster. 8 Compilando com OpenGL 8.1 Linux No Linux, caso OpenGL e glut estejam devidamente instalados, basta incluir a GLUT com #include <GL/glut.h> e compilar os programas com gcc programa.c -o programa -lglut Em alguns Linux pode ser necessário adicionar -lglu -lgl. 8.2 Windows: GLUT O Windows já inclui OpenGL, mas não a GLUT. O primeiro passo no Windows é baixar a GLUT de http://www.xmission.com/~nate/glut.html (arquivo glut-3.7.6-bin.zip) e descompactá-lo em um diretório qualquer. Figura 4: Arquivos da GLUT para Windows. 8

8.3 Windows: Microsoft Visual Studio Configuração inicial: selecione Tools, Options. Selecione Projects, VC++ Directories. Exibindo os diretórios para Include Files, adicione o diretório que contem o arquivo glut.h. Exibindo os diretórios para Library Files, adicione o diretório que contem o arquivo glut32.lib. Copie o arquivo glut32.dll para C:\Windows\System32 (ou terá que copiá-lo para o diretório do seu.exe toda vez que fizer um projeto). Criando um projeto OpenGL:File, New, Project. Em Visual C++ Projects escolha Win32 Project, escolha o nome e o diretório do seu projeto e clique Ok. Clique em Application Settings e escolha Console Application e Empty Project. Expanda Source Files no lado esquerdo da janela, abra o menu com o botão direito e escolha Add Existing Item para adicionar um arquivo C já existente, ou Add Item para adicionar um arquivo C vazio. Seus programas devem ter os includes abaixo: #include <windows.h> #include <glut.h> Há algumas pequenas diferenças no Windows. O math.h por exemplo não tem a definição de pi (M PI). Para compilar, Build, Build Solution (ou F7 no teclado). Procure o executável gerado (estará dentro de um diretório Debug no diretório do seu projeto, que foi escolhido na tela de criação de novo projeto). Figura 5: Telas do Visual Studio. 9

8.4 Windows: Dev C++ Configuração Inicial: Selecione Tools, Compiler Options. Na aba Directories, adicione o diretório que contem o arquivo glut32.lib aos diretórios de Libraries, e adicione o diretório que contem o arquivo glut.h aos diretórios de C Includes. Clique Ok. Criando um novo projeto: File, New Project. Escolha Basic, Console Application. Dê um nome ao projeto e clique Ok. Escreva seu programa C ou adicione um já existente ao projeto. Abra Project, Project Options. Selecione a aba Parameters. No campo do Linker, escreva em uma mesma linha: -lopengl32 -lglu32 -lglut32 Nos seus programas, escreva a linha #define GLUT_DISABLE_ATEXIT_HACK antes de todos os #include, e inclua #include <windows.h> #include <glut.h> Figura 6: Tela de configuração do Dev C++. 10