Jonh Edson Ribeiro de Carvalho | IC-UFF
Computação Visual e Interfaces
 
 
Tutorial OpenGL

Capítulo 2. Desenhando linhas e pontos

O propósito desta lição é entender recursos fundamentais da biblioteca OpenGL e da biblioteca auxiliar GLUT, tais como abrir uma janela, definir sistemas de coordenadas, limpar a tela e especificar cores de desenho. Este propósito será alcançado através da análise do programa linha.c, mostrado no Exemplo 2-1, cuja única funcionalidade desenhar uma reta entre dois pontos de uma janela gráfica.

Exemplo 2-1. programa linha.c

#include <GL/glut.h>
#include <stdlib.h>

void init(void);
void display(void);
void keyboard(unsigned char key, int x, int y);

int main(int argc, char** argv){
  glutInit(&argc, argv);
  glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
  glutInitWindowSize (256, 256); 
  glutInitWindowPosition (100, 100); 
  glutCreateWindow ("Desenhando uma linha");
  init();
  glutDisplayFunc(display); 
  glutKeyboardFunc(keyboard);
  glutMainLoop();
  return 0;
}

void init(void){
  glClearColor(1.0, 1.0, 1.0, 1.0);
  glOrtho (0, 256, 0, 256, -1 ,1);
}

void display(void){
  int i;
  glClear(GL_COLOR_BUFFER_BIT);
  glColor3f (0.0, 0.0, 0.0);
  glBegin(GL_LINES);
  glVertex2i(40,200);  glVertex2i(200,10);
  glEnd();
  glFlush();
}

void keyboard(unsigned char key, int x, int y){
  switch (key) {
  case 27:
	exit(0);
	break;
  }
}

Para compilar e executar o programa linha.c, salve-o juntamente com o arquivo Makefile em um diretório e execute a seguinte seqüência de comandos:

$ make linha
$ linha

A saída do programa linha é mostrado na Figura 2-1.

2.1. Descrição do programa linha.c

#include <GL/glut.h>
#include <stdlib.h>

Estes includes definem os protótipos das funções utilizadas pelo programa. stdlib.h contém o protótipo da função exit(3); O arquivo de cabeçalho glut.h inclui, além dos protótipos das funções GLUT, os arquivos gl.h e glu.h, que contém os protótipos das funções principais e auxiliares do OpenGL.

void init(void);
void display(void);
void keyboard(unsigned char key, int x, int y);

Funções implementadas após a função main devem ser prototipadas aqui, de modo a evitar erros de compilação.

int main(int argc, char** argv){

Todo programa em C/C++ inicia com a função main.

  glutInit(&argc, argv);

Inicializa a biblioteca GLUT e negocia uma seção com o gerenciador de janelas. É possível passar argumentos para a função glutInit provenientes da linha de execução, tais como a variável de ambiente DISPLAY, ou informações sobre a geometria da tela.

  glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);

Informa à biblioteca GLUT o modo do display a ser utilizado quando a janela gráfica for criada. O flag GLUT_SINGLE força o uso de uma janela com buffer simples, significando que todos os desenhos serão feitos diretamente nesta janela. O flag GLUT_RGB diz que o modelo de cor utilizado será o RGB.

  glutInitWindowSize (256, 256); 
  glutInitWindowPosition (100, 100); 

Define o tamanho inicial da janela, 256x256 pixels, e a posição inicial do seu canto superior esquerdo na tela, (x, y)=(100, 100).

  glutCreateWindow ("Desenhando uma linha");

Cria uma janela e define seu título como "Desenhando uma linha".

  init();

Nesta função é definido o estado inicial do OpenGL, antes de qualquer desenho seja feito.

  glutDisplayFunc(display); 

Define display() como a função de desenho (display callback) para a janela corrente. Quando GLUT determina que esta janela deve ser redesenhada, a função de desenho é chamada. A função de desenho deve possuir o seguinte protótipo:

void funcao()(void);

  glutKeyboardFunc(keyboard);

Indica que sempre que uma tecla for pressionada no teclado, GLUT deverá chama a função keyboard() para tratar eventos de teclado (keyboard callback). A função de teclado deve possuir o seguinte protótipo:

void funcao()(unsigned char key, int x, int y);

  glutMainLoop();

Inicia o loop de processamento de desenhos com GLUT. Esta rotina deve ser chamada pelo menos uma vez em um programa que utilize a biblioteca GLUT.

  return 0;
}

Finaliza o programa.

void init(void){
  glClearColor(1.0, 1.0, 1.0, 1.0);

Especifica as intensidade de vermelho (RED), verde (GREEN) e azul (BLUE) utilizadas para limpar a janela. Cada parâmetro pode varia de 0 a 1, o equivalente a uma variação de 0 a 255, usada convecionalmente no sistema de janelas. O último argumento é o canal alfa, usado para compor superfícies transparentes ou translucentes. Como estes conceitos ainda não foram, o canal alfa deve ser mantido com valor igual a 1.

  glOrtho (0, 256, 0, 256, -1 ,1);
}

A função glOrtho define as coordenadas do volume de recorte (clipping volume), possuindo o seguinte protótipo:

void glOrtho()( GLdouble left , GLdouble right , GLdouble bottom , GLdouble top , GLdouble zNear , GLdouble zFar );

Os parâmetros left e right especificam as coordenadas esquerda e direita, respectivamente, dos planos de corte verticais. Os parâmetros bottom e top especificam as coordenadas inferior e superior, respectivamente, dos planos de corte horizontais. zNear e zFar, por sua vez, especificam a coordenada mais próxima e mais distante do observador, respectivamente, no eixo de profundidade. Assim, o volume de recorte definido no exemplo será xmin=0 e xmax=256; ymin=0 e ymax=256; zmin=-1 e zmax=1.

void display(void){
  int i;
  glClear(GL_COLOR_BUFFER_BIT);

A função glClear() serve para limpar buffers utilizados pelo OpenGL com valores pré-definidos. A máscara utilizada neste exemplo, (GL_COLOR_BUFFER_BIT, diz à função glClear() que apenas o buffer de desenho deve ser limpo. Após a execução desta função, a tela ficará branca, uma vez que a init() define (R, G, B)=(1.0, 1.0, 1.0) como cor de limpeza de tela.

  glColor3f (0.0, 0.0, 0.0);

Especifica (R, G, B)=(0, 0, 0), preto, como a cor de desenho. Todos os objetos desenhados a partir daqui terão cor preta.

  glBegin(GL_LINES);
  glVertex2i(40,200);  glVertex2i(200,10);
  glEnd();

As funções glBegin() e glEnd() delimitam os vértices de uma primitiva de desenho ou de um grupo de primitivas. O parâmetro passado para a função especifica o tipo de primitiva a ser desenhado. Neste exemplo, o parâmetro GL_LINES indica que os vértices especificados devem ser tratados como pares de pontos que comporão segmentos de reta independentes. A função glVertex2i() define as coordenadas de um vértice.

void keyboard(unsigned char key, int x, int y){
  switch (key) {
  case 27:
	exit(0);
	break;
  }
}

Conforme mencionado, a função keyboard() serve para tratar eventos de teclado. Sua implementação especifica que quando a tecla ESC (keycode=27) for pressionada o programa deverá ser finalizado.

CopyLeft Webmaster |Atualizado em 22/11/2003
Contato   Pesquisas e Projetos  Publicações   Home