Capítulo 2. Desenhando linhas e
pontos
- Índice
- 2.1. Descrição
do programa linha.c - 2.2. Outros programas relacionados
- 2.3. Exercícios
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.
#include <GL/glut.h> #include <stdlib.h> // prototipos das funcoes void init(void); void display(void); void keyboard(unsigned char key, int x, int y); // funcao principal int main(int argc, char** argv){ glutInit(&argc, argv); // inicializa o glut glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); // especifica o uso de cores e buffers glutInitWindowSize (256, 256); // especifica as dimensoes da janela glutInitWindowPosition (100, 100); // especifica aonde a janela aparece na tela glutCreateWindow ("Desenhando uma linha"); // cria a janela init(); glutDisplayFunc(display); // funcao que sera redesenhada pelo GLUT glutKeyboardFunc(keyboard); // funcoes de teclado glutMainLoop(); // mostra todas as janelas criadas return 0; } // definicao de cada funcao void init(void){ glClearColor(1.0, 1.0, 1.0, 1.0); // cor de fundo glOrtho (0, 256, 0, 256, -1 ,1); // modo de projecao ortogonal } void display(void){ glClear(GL_COLOR_BUFFER_BIT); // limpa a janela glColor3f (0.0, 0.0, 0.0); // cor da linha glBegin(GL_LINES); glVertex2i(40,200); glVertex2i(200,10); // coordenadas inicial e final da linha glEnd(); glFlush(); } void keyboard(unsigned char key, int x, int y){ switch (key) { case 27: // tecla Esc (encerra o programa) 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, 256×256 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 apresentados, 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.