Conheça a iniciativa da Biblioteca dos Desenvolvedores  
Índice da Biblioteca  
Área dos Usuários  
Fórum de Discussão  
Forúm
 
  33 - O primeiro programa com OpenGL

Você vai precisar instalar 2 bibliotecas no seu compilador para seguir os tutoriais daqui para frente.
Veja como instalar em:

OpenGL - > Instalando do AllegroGL e a Glut no Dev-CPP

Nós iremos fazer todos os programas, quando possível sempre duas vezes.
Uma vez com a ajuda do Allegro e AllegroGL e outra vez com a Ajuda do Glut, tudo isto em cima da OpenGL.

Você deve estar se perguntando.. ué?? mais para que essa loucura?
- Simplemente por que já conhecemos a Allegro, então será mais fácil para a gente.

Como as funções utilizadas pela AllegroGL e a Glut são muito parecidas, vale a pena já ir vendo como funciona a Glut para mais tarde
ter embasamento técnico para outros tipos de programação como o DirectX.

Tentaremos fazer sempre todos os exemplos usando AllegroGL e Glut, mais nem sempre isso vai funcionar..
Ou seja, mais desafio para mim e para você :P    (  ... e todo mundo endoidar / pirar / enlouquecer junto )

Bom, primeiro, precisamos saber exatamente o que é OpenGL:

OpenGL é uma biblioteca de rotinas gráficas para a impressão de gráficos em 3 dimensões.
A OpenGL não é uma linguagem de programação, ela é uma API (Application Programming Interface) assim como a Allegro, porém com vantagem de ter maior velocidade para a geração de gráficos em 3 dimensões.

VOCÊ PRECISA SABER...

A OpenGL Não é uma linguagem de Programação!

 

Nossos programas daqui para frente irão chamar funções da OpenGL para criação de gráficos primitivos, polígonos, iluminação, transparência e efeitos especiais como renderização de objetos 3D.

Um programa escrito em OpenGL pode ser executado tanto no Linux quando no Windows, isto quer dizer que a biblioteca é portavel, e nosso programa também, porém temos que ter em mente que a OpenGL não possuí gerenciamento de janelas ou entrada e saída de dados.
Por isto iremos usar a Allegro e a GLUT.

 

Como funciona a OpenGL


Eu li na Wikipedia que a OpenGL possui 250 funções, quando estivermos chamando uma das funções o processo vai
funcionar da seguinte maneira:

1 - Os comandos serão guardados em um Buffer próprio da OpenGL.

1.2 - Alguns comandos básicos serão processados

2 - A OpenGL vai executar a conversão das matrizes e/ou vetores para os gráficos ( Rasterização )

3 - A OpenGL vai colocar a imagem final no Frame Buffer
( Frame buffer é o buffer de imagens da OpenGL assim como nosso antigo BITMAP * buffer ).

VOCÊ PRECISA SABER...

Rasterização é o processo de conversão entre representações vetoriais e matriciais

 

Primeiro Programa com AllegroGL


Meus amigos, este será nosso programa base.
Eu estou usando praticamente o exemplo que já vem com o DevCPP.
O programa está o mais básico possível para que possamos entender as primeiras funções utilizadas pelo AllegroGL e OpenGL.

Abaixo está o código base e a explicação das funções:

VOCÊ PRECISA SABER...

Este tutorial explica todas as funções utilizadas nos programas abaixo.
A idéia não é gravar o nome das funções, mais apenas saber por que elas estão ali.

Como este é o programa base, você não precisa se preocupar em saber exatamente tudo o que o programa está fazendo, isto por que, estas funções estarão em praticamente todos os programas.

Gravar o nome das funções pode tornar extressante a leitura do tutorial, com o tempo iremos aprendendo como utiliza-las. Por isso, não se preocupe com isto agora.

 


CÓDIGO...
// Exemplo de código usando Allegro e AllegroGL
#include <allegro.h>
#include <alleggl.h>

int main()
{
   
   // Iniciações básicas da Allegro
   allegro_init();
   install_keyboard();
   
   // Iniciação da AllegroGL
   install_allegro_gl();   
   
   allegro_gl_set(AGL_Z_DEPTH, 8);
   allegro_gl_set(AGL_COLOR_DEPTH, 16);
   allegro_gl_set(AGL_SUGGEST, AGL_Z_DEPTH | AGL_COLOR_DEPTH);
   
   // Setando o Modo Gráfico
   set_gfx_mode(GFX_OPENGL_WINDOWED, 640, 480, 0, 0);
   
   
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   
   // Iniciando a camera
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   glFrustum(-1.0, 1.0, -1.0, 1.0, 1, 60.0);
   
   glLoadIdentity();
   
   allegro_gl_flip();
   
   
   // Laço principal
   while( !key[KEY_ESC] )
   {
      //Código
   }
   
   
   allegro_exit();
   return 0;
}
END_OF_MAIN();


FIM DE CÓDIGO...

 

No programa acima, começamos a fazer uso da extenção da Allegro, a AllegroGL incluindo ela através do comando
#include <alleggl.h>

O código segue como um programa com Allegro normal:

int allegro_init();
Nossa velha conhecida, função macro responsável por iniciar a biblioteca allegro.



int install_keyboard();
Esse comando é responsável por instalar e tornar as interrupções do teclado disponíveis para o nosso projeto.
Nós também já trabalhamos com ela anteriormente na Allegro.




int install_allegro_gl ()
Macro que inicia o addon AllegroGL, antes é preciso ter iniciado a allegro corretamente.



void allegro_gl_set ( int option, int value )

Nossa primeira função de configuração nova.

Esta função serve apenas para setar configurações necessárias na AllegroGL.
Ela deve ser utilizanda antes de setar o modo gráfico padrão da Allegro.

Todas as opções para esta função são inteiros.

No nosso programa base, iremos usar esta função 3 vezes.

allegro_gl_set(AGL_Z_DEPTH, 8);
Seta o total de profundidade, neste caso, o total do ponto Z máximo.

allegro_gl_set(AGL_COLOR_DEPTH, 16);
Seta o total de profundidade de cores utilizadas no programa. Neste caso 16 bits.

allegro_gl_set(AGL_SUGGEST, AGL_Z_DEPTH | AGL_COLOR_DEPTH);

Quando setamos a opção AGL_SUGGEST, setamos uma opção especial.
Esta opção diz para o Allegro que estamos sugerindo as opções anteiores.

Caso, não for possivel usar AGL_Z_DEPTH = 8 ou AGL_COLOR_DEPTH = 16 então o OpenGL vai procurar uma profundidade melhor para a gente.

Caso você queria que seu programa use obrigatóriamente as primeiras opções setadas com allegro_gl_set, então, no lugar de usar AGL_SUGGEST, use AGL_REQUIRE.

Todas essas opções são usadas pela Allegro quando chamamos nossa conhecida funções set_gfx_mode.

DICA...

Se você não marcar as opções como Sugeridas ( AGL_SUGGEST ) ou requiridas ( AGL_REQUIRE ) as opções serão ignoradas!

 

DICA...

Você pode usar o separador binario | ( ou ) para setar várias opções ao usar o AGL_SUGGEST.



 

int set_gfx_mode(int card, int w, int h, int v_w, int v_h);

O comando acima é responsável por detectar a placa de vídeo, setar o tamanho da tela em pixel e o posicionamento inicial x,y.

Como estamos usando OpenGL, temos um novo parametro para o card.
GFX_OPENGL_WINDOWED

As opções de card podem ser:

GFX_OPENGL_WINDOWED ( Windowed OpenGL graphics driver for Allegro. )
Em janela windows.

GFX_OPENGL_FULLSCREEN ( Fullscreen OpenGL graphics driver for Allegro. )
Em tela cheia.

GFX_OPENGL ( Non-specific OpenGL graphics driver for Allegro. )
Sem especificar.

 




Com todos estes comandos, configuramos nossa janela.
Agora iremos configurar as opções da Biblioteca OpenGL.

void glClear(GLbitfield mask);

Aqui nós já temos uma função legal.
As funções apresentadas acima eram funções da Allegro ou da AllegroGL.

Esta função, é uma função da OpenGL!!

Esta função serve para limpar um buffer. Funciona mais ou menos como nossa conhecida função clear( BITMAP * ) da Allegro.

No nosso programa base, estamos limpando os buffers de GL_COLOR_BUFFER_BIT e GL_DEPTH_BUFFER_BIT.
Essa função pode combinar também vários buffer ( do tipo GLbitfield ) com o comando binário | ( ou ).

GL_COLOR_BUFFER_BIT
É o Buffer de cores da OpenGL.

GL_DEPTH_BUFFER_BIT
É o Buffer de profundidade da OpenGL.

GL_ACCUM_BUFFER_BIT
É um Buffer acumulativo de informações

GL_STENCIL_BUFFER_BIT
Este Buffer armazena informações especiais para cada pixel, como renderizar ou não o mesmo.
É particularmente útil na criação de feitos especiais como sombreamento a partir de fontes de luz múltiplas.



 

void glMatrixMode(GLenum mode);

Seta qual modo matrix será utilizado pelo nosso programa.

Essa função pode setar os seguintes valores:

GL_MODELVIEW
Aplica operações em matrizes que estão sequencialmente guardadas na pilha modelview matrix stack.

GL_PROJECTION
Aplica operações em matrizes que estão sequencialmente guardadas na pilha projection matrix stack.

GL_TEXTURE
Aplica operações em matrizes que estão sequencialmente guardadas na pilha texture matrix stack.

GL_COLOR
Aplica operações em matrizes que estão sequencialmente guardadas na pilha color matrix stack.




 

void glLoadIdentity( void);

Esta função troca a matrix atual ( em que estamos trabalhando. No caso do programa base, ainda não estamos trabalhando com nenhuma ) pela matrix identidade!

Alguem ai se lembra da matrix identidade da matemática?







void glFrustum( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearVal, GLdouble farVal);

Amigos, estava demorando para aparecer uma função complicada.. eheheh, esta é uma delas.

Esta função é responsável por multiplicar a matriz atual pela matriz de perspectiva.
Esta função produz como resultado final uma projeção de perspectiva;

A matriz atual não é a matriz passada na função. A matriz atual ( ainda não estamos trabalhando com nenhuma ) é multiplicada pela matriz passada, e o resultado é colocado no lugar da matriz atual.

Basicamente essa função vai dizer qual será a posição de nossa camera com relação aos objetos 3D.

 



void allegro_gl_flip ( void ) 

O OpenGL já trabalha por padrão com double buffer. Então, a gente não vai mais precisar ficar criando buffers.
Tudo que é escrito na tela pelo OpenGL é colocado em um buffer de fundo.

Ao chamar a função allegro_gl_flip o buffer de fundo se torna o buffer atual.

Cuidado, os buffers não são limpos com essa função.

 


E assim temos nosso programa básico iniciado.
Ele não mostra nada na tela até agora :)

Entender os comandos até aqui é muito importante para nosso progresso.

 

 

 

 

Primeiro Programa com GLUT


Agora iremos fazer um comparativo.
Descrevemos um programa usando OpenGL com o Allegro, agora vamos fazer o mesmo com a Glut e vamos visualizar as diferenças




CÓDIGO...
#include <GL/glut.h>
#include <stdlib.h>

// Prototipos das funções que serão chamadas pela Glut ( Callback )
static void display(void);
static void key(unsigned char key, int x, int y);
static void idle(void);
static void resize(int width, int height);

// Main padrão, o programa inicia aqui
int main(int argc, char *argv[])
{
   glutInit(&argc, argv);
   glutInitWindowSize(640,480);
   glutInitWindowPosition(10,10);
   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
   
   glutCreateWindow("Programa Base");
   
   // callbacks
   glutReshapeFunc(resize);
   glutDisplayFunc(display);
   glutKeyboardFunc(key);
   glutIdleFunc(idle);
   
   
   glClearColor(0,0,0,0);
   glutMainLoop();
   
   return EXIT_SUCCESS;
}
   
// Função que é chamada quando a janela é redimencionada
static void resize(int width, int height)
{
   const float ar = (float) width / (float) height;
   
   glViewport(0, 0, width, height);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
       
   glLoadIdentity();
}
   
// Função que é chamada quando for preciso mostrar ou atualizar a tela
static void display(void)
{
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   
   glutSwapBuffers();
}
   
// Função que é chamada quando uma tecla é apertada
static void key(unsigned char key, int x, int y)
{
   switch (key)
   {
      // caso aperte ESC
      case 27 :
      exit(0);
      break;
   }
   
   glutPostRedisplay();
}
   
// Função que executa rotinas padrões da Glut
static void idle(void)
{
   glutPostRedisplay();
}


FIM DE CÓDIGO...


Precisamos ler nosso programa sempre a partir da função main.
Alguns exemplos da internet poderão mostrar outras funções antes da função main, isto é bem normal.

Nosso programa com GLUT começa chamando a função glutInit.

void glutInit(int *argcp, char **argv);
Essa função serve para iniciar a biblioteca Glut.

Alguns parametros podem ser enviados para a função, e esses parametros servem para controlar a janela.
Veja no manual da Glut como esses parametros podem funcionar.



glutInitWindowSize e glutInitWindowPosition
Seta o tamanho inicial da janela e a posição em que ela será mostrada.

 

void glutInitDisplayMode(unsigned int mode);

Seta os parametros de inicialização do OpenGL.
No nosso programa base estamos usando 3 parametros:

GLUT_RGB
Inicia a janela com modo RGB

GLUT_DOUBLE
Inicia a janela em modo double buffer da OpenGL

GLUT_DEPTH
Indica que nossa janela terá profundidade ( o eixo Z )




int glutCreateWindow(char *name);

Cria uma janela top-level window. O nome que você dará para esta janela, será o nome utilizado pelo sistema operacional também.

 



void glutReshapeFunc(void (*func)(int width, int height));

Esta aqui é uma função muito importante.
Ela é uma função que recebe outra função. Estas funções são funções muito comuns em programas Win32, pois elas registram a chamada de outra função.

Ao fazer o registro, sempre que um determinado comando acontecer, a função registrada será chamada.
Neste caso, registramos a função que será chamada quando a janela for Redimencionada.

 



void glutDisplayFunc(void (*func)(void));

Esta função também é uma função que registra outra função.
Ela registra uma função que irá mostrar os gráficos na tela.

 



void glutKeyboardFunc(void (*func)(unsigned char key, int x, int y));

Ela registra uma função que irá receber as interrupções de teclado.

 



void glutIdleFunc(void (*func)(void));

Registra uma função para executar comandos ou executar animações enquanto a janela não estiver recebendo eventos do Sistema Operacional.

 



void glutIdleFunc(void (*func)(void));

Registra uma função para executar comandos ou executar animações enquanto a janela não estiver recebendo eventos do Sistema Operacional.

 



glClearColor

Nossa primeira função pura de OpenGL, nós já vimos a definição dela.
Ela vai dexar nossa tela preta.

Veja definição

 



glutMainLoop

Essa função chama todos os Callbacks ( funções registradas ) para que o programa funcione perfeitamente.
Ela vai chamar as funções de testes de teclado, de testes de redimencionamento da janela, e até funções internas da Glut.

Esta função não pode ser esquecida.

 


Além da função main, em um programa com GLUT nós tivemos que registrar funções que seriam executadas pela GLUT posteriormente.
Dentro dessas funções, temos outras funções que precisamos conhecer.

A primeira função é a função de rezise:

void glViewport( GLint x, GLint y, GLsizei width, GLsizei height);

Essa função especifica as novas coordenadas de janela para a OpenGL.

 


 

O resto das funções nós já conhecemos:

glMatrixMode - Veja definição
glLoadIdentity - Veja definição
glFrustum - Veja definição



A segunda função é a função de display:

glutSwapBuffers

Ao chamar a função o buffer de fundo da OpenGL se torna o buffer atual.

 


E as últimas funções fazem uso da seguinte função da GLUT:

glutPostRedisplay

Esta função indica para a Glut que a janela atual precisa ser redesenhada.

 


 

 

Algumas explicações


Conseguimos enfim ver todas as funções utilizadas pela AllegroGL e pela Glut para criar uma janela usando OpenGL.
Quando você compilar os programas acima, vai ver que uma janela preta será aberta.

Basta apertar ESC para sair.

Praticamente as duas bibliotecas fizeram a mesma função. A Glut de uma forma bem diferente, se parece muito com um programa windows.
Ela registra funções para fazer a biblioteca funcionar, enquanto a AllegroGL é mais compacta e escreve apenas o que é necessário.

Você deve ter percebido que o comando glFrustum ficou diferente para os dois programas.
Eu fiz isso para que você prestasse mais atenção quanto a este comando.

glFrustum(-1.0, 1.0, -1.0, 1.0, 1, 60.0); // AllegroGL
glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0); // GLUT

Você pode usar os mesmos parametros para os 2 programas, mais no GLUT deve passar a variavel ar devido a função de redimencionamento.

 

Espero que você tenha entendido e executado os dois programas!

Download do exemplo 1 - Allegro - Clique Aqui

Download do exemplo 1 - Glut - Clique Aqui


Contribuidor
Adriano Waltrick
19/09/2007


 

« Anterior

 

Próximo »

 
 

01/06/2007 (C) Copyright. Todos os Direitos Reservados. Leia a política de privacidade do portal.
É proibida a cópia de conteúdo deste site de acordo com a Lei Brasileira de Direitos Autorais.