• Olá Visitante, se gosta do forum e pretende contribuir com um donativo para auxiliar nos encargos financeiros inerentes ao alojamento desta plataforma, pode encontrar mais informações sobre os várias formas disponíveis para o fazer no seguinte tópico: leia mais... O seu contributo é importante! Obrigado.

Introdução à OpenGL

helldanger1

GForum VIP
Entrou
Ago 1, 2007
Mensagens
29,631
Gostos Recebidos
1
Por:professora Isabel Harb Manssour


01. Introdução

OpenGL é definida como "um programa de interface para hardware gráfico". Na verdade, OpenGL é uma biblioteca de rotinas gráficas e de modelagem, bi (2D) e tridimensional (3D), extremamente portável e rápida. Usando OpenGL é possível criar gráficos 3D com uma qualidade visual próxima de um ray tracer. Entretanto, a maior vantagem na sua utilização é a rapidez, uma vez que usa algoritmos cuidadosamente desenvolvidos e otimizados pela Silicon Graphics, Inc., líder mundial em Computação Gráfica e Animação.

OpenGL não é uma linguagem de programação, é uma poderosa e sofisticada API (Application Programming Interface) para criação de aplicações gráficas 2D e 3D. Seu funcionamento é semelhante ao de uma biblioteca C, uma vez que fornece uma série de funcionalidades. Normalmente se diz que um programa é baseado em OpenGL ou é uma aplicação OpenGL, o que significa que ele é escrito em alguma linguagem de programação que faz chamadas a uma ou mais bibliotecas OpenGL.

As aplicações OpenGL variam de ferramentas CAD a programas de modelagem usados para criar personagens para o cinema, tal como um dinossauro. Além do desenho de primitivas gráficas, tais como linhas e polígonos, OpenGL dá suporte a iluminação, colorização, mapeamento de textura, transparência, animação, entre muitos outros efeitos especiais. Atualmente, OpenGL é reconhecida e aceita como um padrão API para desenvolvimento de aplicações gráficas 3D em tempo real.
 

helldanger1

GForum VIP
Entrou
Ago 1, 2007
Mensagens
29,631
Gostos Recebidos
1
Ao invés de descrever a cena e como ela deve parecer, quando se está utilizando OpenGL é preciso apenas determinar os passos necessários para alcançar a aparência ou efeito desejado. Estes passos envolvem chamadas a esta API portável que inclui aproximadamente 250 comandos e funções (200 comandos do core OpenGL e 50 da GLU - OpenGL Utility Library). Por ser portável, OpenGL não possui funções para gerenciamento de janelas, interação com o usuário ou arquivos de entrada/saída. Cada ambiente, como por exemplo o Microsoft Windows, possui suas próprias funções para estes propósitos. Não existe um formato de arquivo OpenGL para modelos ou ambientes virtuais. OpenGL fornece um pequeno conjunto de primitivas gráficas para construção de modelos, tais como pontos, linhas e polígonos. A biblioteca GLU (que faz parte da implementação OpenGL) é que fornece várias funções para modelagem, tais como superfícies quádricas, e curvas e superfícies NURBS (Non Uniform Rational B-Splines) [Woo 1999, Wright 2000].
 

helldanger1

GForum VIP
Entrou
Ago 1, 2007
Mensagens
29,631
Gostos Recebidos
1
A palavra pipeline é usada para descrever um processo que pode ter dois ou mais passos distintos. A figura 2.1 mostra uma versão simplificada do pipeline OpenGL. Como uma aplicação faz chamadas às funções API OpenGL, os comandos são colocados em um buffer de comandos. Este buffer é preenchido com comandos, vértices, dados de textura, etc. Quando este buffer é "esvaziado", os comandos e dados são passados para o próximo estágio.

pipeline.jpg



Após a etapa de aplicação das transformações geométricas e da iluminação, é feita a rasterização, isto é, é gerada a imagem a partir dos dados geométricos, de cor e textura. A imagem final, então, é colocada no frame buffer, que é a memória do dispositivo gráfico. Isto significa que a imagem é exibida no monitor [Wright 2000].
 

helldanger1

GForum VIP
Entrou
Ago 1, 2007
Mensagens
29,631
Gostos Recebidos
1
02. Utilização

Como uma API, OpenGL segue a convenção de chamada da linguagem C. Isto significa que programas escritos em C podem facilmente chamar funções desta API, tanto porque estas foram escritas em C, como porque é fornecido um conjunto de funções C intermediárias que chamam funções escritas em assembler ou outra linguagem [Wright 2000].

Apesar de OpenGL ser uma biblioteca de programação "padrão", existem muitas implementações desta biblioteca, por exemplo, para Windows e para Linux. A implementação utilizada no ambiente Linux é a biblioteca Mesa. Também existem implementações para os compiladores Visual C++, Borland C++, Dev-C++, Delphi e Visual Basic. Para obter as bibliotecas e a documentação de cada implementação acesse _http://www.opengl.org/.
 

helldanger1

GForum VIP
Entrou
Ago 1, 2007
Mensagens
29,631
Gostos Recebidos
1
No caso da implementação da Microsoft, o sistema operacional fornece os arquivos opengl32.dll e glu32.dll, necessários para execução de programas OpenGL. Além disso, são fornecidas com suas ferramentas de programação, como por exemplo com o Microsoft Visual C++, as bibliotecas opengl32.lib (OpenGL) e glu32.lib (GLU - biblioteca de utilitários OpenGL). Assim, para criar programas com ferramentas Microsoft que usem OpenGL, tal como o MS Visual C++ 6.0, é necessário adicionar estas duas bibliotecas à lista de bibliotecas importadas. Protótipos para todas as funções, tipos e macros OpenGL estão (por convenção) no header gl.h. Os protótipos da biblioteca de funções utilitárias estão em um arquivo diferente, glu.h. Estes arquivos normalmente estão localizados em uma pasta especial no path do include. O código abaixo mostra as inclusões típicas para um programa Windows que usa OpenGL [Wright 2000]:
#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
 

helldanger1

GForum VIP
Entrou
Ago 1, 2007
Mensagens
29,631
Gostos Recebidos
1
Considerando o compilador MS Visual C++ 6.0, para utilizar a GLUT (veja a explicação no capítulo 05) é necessário fazer o download desta biblioteca (clique aqui para fazer agora o download da GLUT para o MS Visual C++ 6.0), descompactar o arquivo e copiar: os arquivos glut.dll e glut32.dll para a pasta System do Windows (ou para a pasta System32 do Windows NT ou Windows 2000); os arquivos glut.lib e glut32.lib para a mesma pasta do ambiente de programação onde estão as outras bibliotecas (opengl32.lib e glu32.lib); e o arquivo glut.h para a mesma pasta do ambiente de programação onde estão os arquivos gl.h e glu.h [Wright 2000]. Estes arquivos normalmente estão compactados em um único arquivo que pode ser obtido em _http://www.opengl.org/developers/documentation/glut/index.html.

Também é necessário criar um projeto no MS Visual C++ 6.0 da seguinte maneira:
no menu File selecione a opção New;
na janela aberta, selecione a opção Win32ConsoleApplication e coloque o nome do projeto e o local onde ele será gravado;
depois, inicialmente, pode ser selecionada a opção An empty project;
no menu Project selecione a opção Settings;
na janela aberta, selecione a guia Link e acrescente na caixa de texto Object/library modules a(s) biblioteca(s) que devem ser linkadas com o programa, que são opengl32.lib e glu32.lib, ou também a glut32.lib;
no final, adicione o arquivo fonte (.cpp) ao projeto, selecionando a opção Add to Project/Files do menu Project.
 

helldanger1

GForum VIP
Entrou
Ago 1, 2007
Mensagens
29,631
Gostos Recebidos
1
Resumindo, para utilizar OpenGL e GLUT com ferramentas Microsoft, no caso o MS Visual C++ 6.0, é necessário:
Fazer o download e instalar a biblioteca GLUT;
Criar um projeto para linkar as bibliotecas necessárias com o programa;
Incluir os headers adequados (<gl/gl.h> e <gl/glu.h>, ou <gl/glut.h>).


A implementação da OpenGL utilizada no ambiente Linux, a biblioteca Mesa, não é uma implementação "oficial", é um projeto de software livre. A distribuição desta biblioteca, cuja versão 5.0 possui suporte para o conjunto de instruções da OpenGL 1.4, inclui makefiles e instruções para a sua correta utilização.

Neste capítulo estão descritos os passos necessários para a utilização de OpenGL com o MS Visual C++ 6.0. Para verificar as instruções de como utilizar OpenGL com outros compiladores, clique em um dos links abaixo.
 

helldanger1

GForum VIP
Entrou
Ago 1, 2007
Mensagens
29,631
Gostos Recebidos
1
para verificar as instruções sobre a utilização de OpenGL com o Dev-C++, que é free.



Utilização do Dev-C++ com OpenGL

O Dev-C++ é um ambiente de desenvolvimento integrado (IDE - Integrated Development Environment) para a linguagem de programação C/C++. O compilador Dev-C++, que dá suporte a compiladores baseados no GCC (GNU Compiler Collection), pode ser obtido em _http://www.bloodshed.net/devcpp.html. Entretanto, para facilitar, os arquivos também estão disponíveis aqui. Para instalar o Dev-C++ 4.01 siga as instruções a seguir.
Faça o download dos arquivos devcpp4.zip e devcpp401.zip;
Descompacte o arquivo devcpp4.zip em um diretório temporário (por exemplo, c:\Temp);
Execute o Setup.exe (opção Typical, instala no diretório C:\Dev-C++);
Descompacte o arquivo devcpp401.zip também em um diretório temporário;
Mova o arquivo DevCpp.exe para o diretório onde o Dev-C++ foi instalado (por exemplo, C:\Dev-C++) sobrepondo-o à versão instalada anteriormente (este novo executável corrige algumas falhas da versão anterior).

O ambiente Windows já deve conter as DLLs necessárias para execução dos programas OpenGL. Neste caso, os arquivos opengl32.dll e glu32.dll devem estar na pasta System (Windows98) ou System32 (Windows NT ou Windows 2000). Como o Dev-C++ dá suporte para programação com OpenGL, a pasta C:\Dev-C++\Include\GL contém os arquivos gl.h, glaux.h e glu.h, e a pasta C:\Dev-C++\Lib contém os arquivos opengl32.def, glaux.def e glu32.def. Neste caso, falta instalar apenas a biblioteca GLUT, o que pode ser feito seguindo os passos descritos a seguir.
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;



 

helldanger1

GForum VIP
Entrou
Ago 1, 2007
Mensagens
29,631
Gostos Recebidos
1
Para utilizar OpenGL com o Borland C++ (versão free), é necessário fazer o download do compilador e da biblioteca GLUT adequada. .



Um tutorial que explica como utilizar OpenGL com Delphi está disponível em Biblioteca Gráfica OpenGl. O download do componente também pode ser feito neste endereço.



para acessar alguns links com instruções de como usar OpenGL com Java.

* OpenGL e Java

_http://www.jausoft.com/gl4java/ - Jausoft GL4Java Home-Page

_http://sourceforge.net/projects/gl4java - SourceForge: Project Info - OpenGL[tm] for Java[tm]

_http://www.codeproject.com/java/opengl.asp - The Code Project - Embed OpenGL inside Java AWT Canvas - Java Programming

_http://www.palevich.com/3dfx/JavaOpenGL.html - JavaOpenGL Manual

_http://www.palevich.com/3dfx/JavaMesa.html - JavaMesa Manual

_http://www.javaworld.com/javaworld/jw-05-1999/jw-05-media.html - 3D graphics programming in Java, Part 3: OpenGL - JavaWorld May 1999

_http://arcana.symbolstone.org/products/magician/ - Magician: OpenGL for Java



* OpenGL e Visual Basic

_http://is6.pacific.net.hk/~edx/ - Programming OpenGL with Visual Basic

_http://inetarena.com/~rmyers/opengl/etc.html - OpenGL And Visual Basic: Links & Other Stuff



 

helldanger1

GForum VIP
Entrou
Ago 1, 2007
Mensagens
29,631
Gostos Recebidos
1
03. Tipos de Dados

Para tornar o código portável, foram definidos tipos de dados próprios para OpenGL. Estes tipos de dados são mapeados dos tipos de dados C comuns, que também podem ser utilizados. Como os vários compiladores e ambientes possuem regras diferentes para determinar o tamanho das variáveis C, usando os tipos OpenGL é possível “isolar” o código das aplicações destas alterações.

Na tabela 3.1, definida tanto por [Woo 1999], como por [Wright 2000], são apresentados os tipos de dados OpenGL, os tipos de dados C correspondentes e o sufixo apropriado. Estes sufixos são usados para especificar os tipos de dados para as implementações ISO C de OpenGL. Pode-se observar que todos os tipos começam "GL", e a maioria é seguido pelo tipo de dado C correspondente.
Tipo de dado OpenGL-Representação interna-Tipo de dado C -Sufixo
----------------------------------------------equivalente
GLbyte---------------- 8-bit integer----------- signed char---- b
GLshort---------------- 16-bit integer---------- short---------- s
GLint, GLsizei----------- 32-bit integer---------- int ou long------ i
GLfloat, GLclampf--------32-bit floating-point----- float------ f
GLdouble, GLclampd------64-bit floating-point------ double---- d
GLubyte, GLboolean----- 8-bit unsigned integer--------unsigned char---- ub
GLushort--------------- 16-bit unsigned integer--------- unsigned short--------------------------------------------------------------------- us
GLuint, GLenum, GLbitfield------- 32-bit unsigned integer-----unsigned long ou unsigned int------------------------------------------------------------------- ui


Tabela 3.1 - Tipos de dados OpenGL
 

helldanger1

GForum VIP
Entrou
Ago 1, 2007
Mensagens
29,631
Gostos Recebidos
1
04. Convenções para os Nomes das Funções

Todos os nomes das funções OpenGL seguem uma convenção que indica de qual biblioteca a função faz parte e, freqüentemente, quantos e que tipos de argumentos a função tem. Todas as funções possuem uma raiz que representa os comandos OpenGL que correspondem às funções. Por exemplo, a função glColor3f possui Color como raiz. O prefixo gl representa a biblioteca gl, e o sufixo 3f significa que a função possui três valores de ponto flutuante como parâmetro. Resumindo, todas as funções OpenGL possuem o seguinte formato:

<PrefixoBiblioteca> <ComandoRaiz> <ContadorArgumentosOpcional> <TipoArgumentosOpcional>

Variações da função do exemplo anterior, glColor3f, podem receber três valores inteiros como parâmetro (glColor3i), três doubles (glColor3d) e assim por diante. Algumas versões da glColor também recebem quatro argumentos. Neste caso, um dos argumentos é usado para especificar o componente alfa (transparência). Esta convenção de adicionar o número e o tipo dos argumentos facilita a memorização da lista de argumentos.
 

helldanger1

GForum VIP
Entrou
Ago 1, 2007
Mensagens
29,631
Gostos Recebidos
1
05. Bibliotecas

Segundo [Woo 1999], OpenGL fornece um conjunto de comandos poderosos, mas primitivos. Portanto, todas as rotinas de desenho de alto nível devem ser elaboradas em função destes comandos. Sendo assim, foram desenvolvidas algumas bibliotecas para simplificar a tarefa de programação. Estas bibliotecas são apresentadas a seguir.

GLU - OpenGL Utility Library: contém várias rotinas que utilizam os comandos OpenGL de baixo nível para executar tarefas como, por exemplo, definir as matrizes para projeção e orientação da visualização, e fazer o rendering de uma superfície. Esta biblioteca é fornecida como parte de cada implementação de OpenGL, e suas funções usam o prefixo glu [Woo 1999].

GLUT - OpenGL Utility Toolkit: é um toolkit independente de plataforma, que inclui alguns elementos GUI (Graphical User Interface), tais como menus pop-up e suporte para joystick. Esta biblioteca, escrita por Mark Kilgard, não é domínio público, mas é free. O seu principal objetivo é esconder a complexidade das APIs dos diferentes sistemas de janelas. As funções desta biblioteca usam o prefixo glut. É interessante comentar que a GLUT substitiu a GLAUX, uma biblioteca auxiliar OpenGL que havia sido criada para facilitar o aprendizado e a elaboração de programas OpenGL independente do ambiente de programação (Linux, Windows, etc.) [Woo 1999, Wright 2000].

GLX - OpenGL Extension to the X Window System: fornecido como um "anexo" de OpenGL para máquinas que usam o X Window System. Funções GLX usam o prefixo glX. Para Microsoft Windows 95/98/NT, as funções WGL fornecem as janelas para a interface OpenGL. Todas as funções WGL usam o prefixo wgl. Para IBM/OS2, a PGL é a Presentation Manager para a interface OpenGL, e suas funções usam o prefixo pgl. Para Apple, a AGL é a interface para sistemas que suportam OpenGL, e as funções AGL usam o prefixo agl [Woo 1999].

FSG - Fahrenheit Scene Graph: é um toolkit orientado à objetos e baseado em OpenGL, que fornece objetos e métodos para a criação de aplicações gráficas 3D interativas. FSG, que foi escrito em C++ e é separado de OpenGL, fornece componentes de alto nível para criação e edição de cenas 3D, e a habilidade de trocar dados em outros formatos gráficos [Woo 1999].
 

helldanger1

GForum VIP
Entrou
Ago 1, 2007
Mensagens
29,631
Gostos Recebidos
1
06. Máquina de Estados

OpenGL é uma máquina de estados, conforme descrito por [Woo 1999]. É possível colocá-la em vários estados (ou modos) que não são alterados, a menos que uma função seja chamada para isto. Por exemplo, a cor corrente é uma variável de estado que pode ser definida como branco. Todos os objetos, então, são desenhados com a cor branca, até o momento em que outra cor corrente é especificada.

OpenGL mantém uma série de variáveis de estado, tais como estilo (ou padrão) de uma linha, posições e características das luzes, e propriedades do material dos objetos que estão sendo desenhados. Muitas delas referem-se a modos que podem ser habilitados ou desabilitados com os comandos glEnable() e glDisable().

Cada variável de estado possui um valor inicial (default) que pode ser alterado. As funções que utilizadas para saber o seu valor são: glGetBooleanv(), glGetDoublev(), glGetFloatv, glGetIntegerv, glGetPointerv() ou glIsEnabled(). Dependendo do tipo de dado, é possível saber qual destas funções deve ser usada [Woo 1999]. O trecho de programa a seguir mostra um exemplo da utilização destas funções.



int luz;
:
glEnable(GL_LIGHTING); //Habilita luz - GL_LIGHTING é a variável de estado
:
luz = glIsEnabled(GL_LIGHTING); // retorna 1 (verdadeiro)
:
glDisable(GL_LIGHTING); //Desabilita luz
:
luz = glIsEnabled(GL_LIGHTING); // retorna 0 (falso)
:
 

helldanger1

GForum VIP
Entrou
Ago 1, 2007
Mensagens
29,631
Gostos Recebidos
1
07. Primeiro Programa

A biblioteca GLUT, descrita no capítulo 5, é utilizada nos exemplos deste tutorial que começam a ser apresentados a partir deste capítulo. Portanto, estes exemplos podem ser compilados em várias plataformas sem a necessidade, por exemplo, de saber elaborar programas com interface para ambiente Windows.

Para entender o funcionamento da GLUT, logo abaixo é apresentado o menor programa OpenGL possível, implementado por [Wright 2000], que simplesmente abre uma janela OpenGL.
// PrimeiroPrograma.c - Isabel H. Manssour
// Um programa OpenGL simples que abre uma janela GLUT
// Este código está baseado no Simple.c, exemplo
// disponível no livro "OpenGL SuperBible",
// 2nd Edition, de Richard S. e Wright Jr.

#include <gl/glut.h>

// Função callback chamada para fazer o desenho
void Desenha(void)
{
//Limpa a janela de visualização com a cor de fundo especificada
glClear(GL_COLOR_BUFFER_BIT);

//Executa os comandos OpenGL
glFlush();
}

// Inicializa parâmetros de rendering
void Inicializa (void)
{
// Define a cor de fundo da janela de visualização como preta
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}

// Programa Principal
int main(void)
{
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutCreateWindow("Primeiro Programa");
glutDisplayFunc(Desenha);
Inicializa();
glutMainLoop();
}
 

helldanger1

GForum VIP
Entrou
Ago 1, 2007
Mensagens
29,631
Gostos Recebidos
1
Obs.: Clique nos links a seguir para fazer o download deste programa, incluindo o projeto e o executável, para os ambientes de programação Visual C++ e Dev-C++, respectivamente: Exemplo Visual C++, Exemplo Dev-C++.

Este programa simples contém quatro funções da biblioteca GLUT (prefixo glut), e três funções OpenGL (prefixo gl). O conteúdo deste programa é descrito detalhadamente a seguir.

O arquivo glut.h contém os protótipos das funções utilizadas pelo programa. Ele também inclui os headers gl.h e glu.h que definem, respectivamente, as bibliotecas de funções OpenGL e GLU. O header #include é requerido por todas as aplicações windows, mas a sua inclusão é opcional porque a versão WIN32 da GLUT já inclui o windows.h na glut.h. Entretanto, se o objetivo é criar um código portável, é um bom hábito incluir este arquivo.

glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); avisa a GLUT que tipo de modo de exibição deve ser usado quando a janela é criada. Neste caso os argumentos indicam a criação de uma janela single-buffered (GLUT_SINGLE) com o modo de cores RGBA (GLUT_RGB). O primeiro significa que todos os comandos de desenho são feitos na janela de exibição. Uma alternativa é uma janela double-buffered, onde os comandos de desenho são executados para criar uma cena fora da tela para depois rapidamente colocá-la na view (ou janela de visualização). Este método é geralmente utilizado para produzir efeitos de animação. O modo de cores RGBA significa que as cores são especificadas através do fornecimento de intensidades dos componentes red, green e blue separadas.

glutCreateWindow("Primeiro Programa"); é o comando da biblioteca GLUT que cria a janela. Neste caso, é criada uma janela com o nome "Primeiro Programa". Este argumento corresponde a legenda para a barra de título da janela.

glutDisplayFunc(Desenha); estabelece a função "Desenha" previamente definida como a função callback de exibição. Isto significa que a GLUT chama a função sempre que a janela precisar ser redesenhada. Esta chamada ocorre, por exemplo, quando a janela é redimensionada ou encoberta. É nesta função que se deve colocar as chamadas de funções OpenGL, por exemplo, para modelar e exibir um objeto.

 

helldanger1

GForum VIP
Entrou
Ago 1, 2007
Mensagens
29,631
Gostos Recebidos
1
Inicializa(); não é uma função OpenGL nem GLUT, é apenas uma convenção utilizada exemplos apresentados por [Wright 2000], nos quais este tutorial está baseado. Nesta função são feitas as inicializações OpenGL que devem ser executadas antes do rendering. Muitos estados OpenGL devem ser determinados somente uma vez e não a cada vez que a função “Desenha” é chamada.

glutMainLoop(); é a função que faz com que comece a execução da “máquina de estados” e processa todas as mensagens específicas do sistema operacional, tais como teclas e botões do mouse pressionados, até que o programa termine.

glClearColor(0.0f, 0.0f, 1.0f, 1.0f); é a função que determina a cor utilizada para limpar a janela. Seu protótipo é: void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alfa);. GLclampf é definido como um float na maioria das implementações de OpenGL. O intervalo para cada componente red, green, blue é de 0 a 1. O componente alfa é usado para efeitos especiais, tal como transparência.

glClear(GL_COLOR_BUFFER_BIT); "limpa" um buffer particular ou combinações de buffers, onde buffer é uma área de armazenamento para informações da imagem. Os componentes RGB são geralmente referenciados como color buffer ou pixel buffer. Existem vários tipos de buffer, mas por enquanto só é necessário entender que o color buffer é onde a imagem é armazenada internamente e limpar o buffer com glClear remove o desenho da janela.

glFlush(); faz com que qualquer comando OpenGL não executado seja executado. Neste primeiro exemplo tem apenas a função glClear [Wright 2000].
 

helldanger1

GForum VIP
Entrou
Ago 1, 2007
Mensagens
29,631
Gostos Recebidos
1
08. Desenhando Primitivas

O exemplo de programa OpenGL do capítulo anterior apenas abria uma janela vazia com um fundo azul. Neste capítulo é apresentado um exemplo que mostra como fazer um desenho, mover e redimensionar a janela [Wright 2000].
// Quadrado.c - Isabel H. Manssour
// Um programa OpenGL simples que desenha um
// quadrado em uma janela GLUT.
// Este código está baseado no GLRect.c, exemplo
// disponível no livro "OpenGL SuperBible",
// 2nd Edition, de Richard S. e Wright Jr.

#include <windows.h>
#include <gl/glut.h>

// Função callback chamada para fazer o desenho
void Desenha(void)
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

// Limpa a janela de visualização com a cor de fundo especificada
glClear(GL_COLOR_BUFFER_BIT);

// Especifica que a cor corrente é vermelha
// R G B
glColor3f(1.0f, 0.0f, 0.0f);

// Desenha um quadrado preenchido com a cor corrente
glBegin(GL_QUADS);
glVertex2i(100,150);
glVertex2i(100,100);
// Especifica que a cor corrente é azul
glColor3f(0.0f, 0.0f, 1.0f);
glVertex2i(150,100);
glVertex2i(150,150);
glEnd();

// Executa os comandos OpenGL
glFlush();
}

// Inicializa parâmetros de rendering
void Inicializa (void)
{
// Define a cor de fundo da janela de visualização como preta
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}

// Função callback chamada quando o tamanho da janela é alterado
void AlteraTamanhoJanela(GLsizei w, GLsizei h)
{
// Evita a divisao por zero
if(h == 0) h = 1;

// Especifica as dimensões da Viewport
glViewport(0, 0, w, h);

// Inicializa o sistema de coordenadas
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

// Estabelece a janela de seleção (left, right, bottom, top)
if (w <= h)
gluOrtho2D (0.0f, 250.0f, 0.0f, 250.0f*h/w);
else
gluOrtho2D (0.0f, 250.0f*w/h, 0.0f, 250.0f);
}

// Programa Principal
int main(void)
{
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(400,350);
glutInitWindowPosition(10,10);
glutCreateWindow("Quadrado");
glutDisplayFunc(Desenha);
glutReshapeFunc(AlteraTamanhoJanela);
Inicializa();
glutMainLoop();
}
 

helldanger1

GForum VIP
Entrou
Ago 1, 2007
Mensagens
29,631
Gostos Recebidos
1
Obs.:
// Quadrado.c - Isabel H. Manssour
// Um programa OpenGL simples que desenha um
// quadrado em uma janela GLUT.
// Este código está baseado no GLRect.c, exemplo
// disponível no livro "OpenGL SuperBible",
// 2nd Edition, de Richard S. e Wright Jr.

#include <windows.h>
#include <gl/glut.h>

// Função callback chamada para fazer o desenho
void Desenha(void)
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

// Limpa a janela de visualização com a cor de fundo especificada
glClear(GL_COLOR_BUFFER_BIT);

// Especifica que a cor corrente é vermelha
// R G B
glColor3f(1.0f, 0.0f, 0.0f);

// Desenha um quadrado preenchido com a cor corrente
glBegin(GL_QUADS);
glVertex2i(100,150);
glVertex2i(100,100);
// Especifica que a cor corrente é azul
glColor3f(0.0f, 0.0f, 1.0f);
glVertex2i(150,100);
glVertex2i(150,150);
glEnd();

// Executa os comandos OpenGL
glFlush();
}

// Inicializa parâmetros de rendering
void Inicializa (void)
{
// Define a cor de fundo da janela de visualização como preta
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}

// Função callback chamada quando o tamanho da janela é alterado
void AlteraTamanhoJanela(GLsizei w, GLsizei h)
{
// Evita a divisao por zero
if(h == 0) h = 1;

// Especifica as dimensões da Viewport
glViewport(0, 0, w, h);

// Inicializa o sistema de coordenadas
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

// Estabelece a janela de seleção (left, right, bottom, top)
if (w <= h)
gluOrtho2D (0.0f, 250.0f, 0.0f, 250.0f*h/w);
else
gluOrtho2D (0.0f, 250.0f*w/h, 0.0f, 250.0f);
}

// Programa Principal
int main(void)
{
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(400,350);
glutInitWindowPosition(10,10);
glutCreateWindow("Quadrado");
glutDisplayFunc(Desenha);
glutReshapeFunc(AlteraTamanhoJanela);
Inicializa();
glutMainLoop();
}

Este programa, como mostra a figura 8.1, apenas exibe um quadrado azul e vermelho numa janela com fundo preto. As novas funções utilizadas neste exemplo são descritas a seguir

Figura8.1.png



Figura 8.1 - Saída do programa Quadrado.c

glutInitWindowSize(400,350); especifica o tamanho em pixels da janela GLUT.

glutInitWindowPosition(10,10); especifica a localização inicial da janela GLUT, que neste caso é o canto superior esquerdo da tela do computador [Woo 1999].

glutReshapeFunc(AlteraTamanhoJanela); estabelece a função "AlteraTamanhoJanela" previamente definida como a função callback de alteração do tamanho da janela. Isto é, sempre que a janela é maximizada, minimizada, etc., a função "AlteraTamanhoJanela" é executada para reinicializar o sistema de coordenadas.

glColor3f(1.0f, 0.0f, 0.0f); determina a cor que será usada para o desenho (linhas e preenchimento). A seleção da cor é feita da mesma maneira que na função glClearColor, sendo que não é necessário especificar o componente alfa, cujo valor default é 1.0 (completamente opaco).

glBegin(GL_QUADS);… glEnd(); usada para desenhar um quadrado preenchido a partir dos vértices especificados entre glBegin e glEnd. O capítulo 9 descreve a utilização destas funções. OpenGL mapeia as coordenadas dos vértices para a posição atual da janela de visualização na função callback “AlteraTamanhoJanela”.

 

helldanger1

GForum VIP
Entrou
Ago 1, 2007
Mensagens
29,631
Gostos Recebidos
1
Antes de descrever os parâmetros e comandos da função “AlteraTamanhoJanela”, é necessário revisar alguns conceitos e especificações. Em quase todos ambientes de janelas, o usuário pode alterar o tamanho e dimensões da janela em qualquer momento. Quando isto ocorre, o conteúdo da janela é redesenhado levando em conta as novas dimensões. Normalmente, o esperado é que a escala do desenho seja alterada de maneira que ele fique dentro da janela, independente do tamanho da janela de visualização ou do desenho [Foley 1990]. Assim, uma janela pequena terá o desenho completo, mas pequeno, e uma janela grande terá o desenho completo e maior.

Apesar do exemplo mostrar um quadrado 2D, o desenho é feito em um espaço de coordenadas 3D. A função glBegin(GL_QUADS);… glEnd(); desenha o quadrado no plano xy em z=0. Portanto, é necessário determinar o tamanho da viewport (janela onde será feito o desenho) e do volume de visualização (parte do universo da aplicação que será mapeada para viewport), pois estes parâmetros influenciam o espaço de coordenadas e a escala do desenhos 2D e 3D na janela.

Sempre que o tamanho da janela é alterado, a viewport e o volume de visualização devem ser redefinidos de acordo com as novas dimensões da janela. Assim, a aparência do desenho não é alterada (por exemplo, um quadrado não vira um retângulo). Como a alteração do tamanho da janela é detectada e gerenciada de maneira diferente em cada ambiente, a biblioteca GLUT fornece a função glutReshapeFunc, descrita anteriormente, que registra a função callback que a GLUT irá chamar sempre que houver esta alteração. A função passada para a glutReshapeFunc deve ter o seguinte protótipo: void AlteraTamanhoJanela(GLsizei w, GLsizei h);. O nome "AlteraTamanhoJanela" foi escolhido porque descreve o que a função faz. Os parâmetros recebidos sempre que o tamanho da janela é alterado são a sua nova largura e a sua nova altura, respectivamente. Esta informação é usada para modificar o mapeamento do sistema de coordenadas desejado para o sistema de coordenadas da tela com a ajuda de duas funções uma OpenGL, glViewport, e uma da biblioteca GLU, gluOrtho2D. Estas e outras funções chamadas na "AlteraTamanhoJanela", que definem como a viewport é especificada, são descritas a seguir.
 

helldanger1

GForum VIP
Entrou
Ago 1, 2007
Mensagens
29,631
Gostos Recebidos
1
glViewport(0, 0, w, h); recebe como parâmetro a nova largura e altura da janela. O protótipo desta função é: void glViewport(GLint x, GLint y, GLsizei width, GLsizei height);. Seus parâmetros especificam o canto inferior esquerdo da viewport (x,y) dentro da janela, e a sua largura e altura em pixels (width e height). Geralmente x e y são zero, mas é possível usar a viewport para visualizar mais de uma cena em diferentes áreas da janela. Em outras palavras, a viewport define a área dentro janela, em coordenadas de tela, que OpenGL pode usar para fazer o desenho. O volume de visualização é, então, mapeado para a nova viewport.

gluOrtho2D (0.0f, 250.0f*w/h, 0.0f, 250.0f); é usada para determinar que a projeção ortográfica (2D) será utilizada para exibir na tela a imagem 2D que está na janela de seleção definida através dos parâmetros passados para esta função. O protótipo desta função é: void gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top);. No sistema de coordenadas cartesianas, os valores left e right especificam os limites mínimo e máximo no eixo X; analogamente, bottom e top especificam os limites mínimo e máximo no eixo Y.

glMatrixMode(GL_PROJECTION); e glLoadIdentity(); servem, respectivamente, para avisar a OpenGL que todas as futuras alterações, tais como operações de escala, rotação e translação, irão afetar a "câmera" (ou observador), e para inicializar o sistema de coordenadas antes da execução de qualquer operação de manipulação de matrizes. Sem este comando, cada chamada sucessiva de gluOrtho2D poderia resultar em uma corrupção do volume de visualização. Em outras palavras, a matriz de projeção é onde o volume de visualização, que neste caso é um plano, é definido; a função gluOrtho2D não estabelece realmente o volume de visualização utilizado para fazer o recorte, apenas modifica o volume existente; ela multiplica a matriz que descreve o volume de visualização corrente pela matriz que descreve o novo volume de visualização, cujas coordenadas são recebidas por parâmetro.

glMatrixMode(GL_MODELVIEW); avisa a OpenGL que todas as futuras alterações, tais como operações de escala, rotação e translação, irão afetar os modelos da cena, ou em outras palavras, o que é desenhado. A função glLoadIdentity(); chamada em seguida, faz com que a matriz corrente seja inicializada com a matriz identidade (nenhuma transformação é acumulada) [Wright 2000].
 
Topo