Conheça a iniciativa da Biblioteca dos Desenvolvedores
Índice da Biblioteca
Área dos Usuários
Fórum de Discussão
38 - Extruturando um Objeto 3D
Até aqui estivemos aprendendo como desenhar pontos, um triângulo e um quadrado nas 3 coordenadas do mundo 3D.
Apartir deste tutorial, iremos demonstrar como criar realmente a extrutura de um objeto 3D.
Iremos aprender como, a partir de um triangulo, criar uma Tetraedro 3D ( a pirâmide é um poliedro ) e como, a partir de um quadrado, criar um cubo 3D.
A primeira coisa que precisamos ter em mente é, como é um objeto em 3D.
Um cubo em 3D tem a seguinte representação gráfica:
Os pontos rosas, são os nossos conhecidos pontos, ou vértices.
Em programas de modelagem 3D esses pontos também podem ser chamados de Meshes ou Vertex.
Como estudamos no capítulo 34 o parâmetro GL_QUADS imprime um quadrado na tela sempre que o quarto ponto é desenhado.
Esse quadrado que é mostrado pela OpenGL é chamado de Face.
Na figura acima, precisamos conseguir identificar, quantas faces tem um cubo:
Com isto, chegamos a conclusão de que, teremos que imprimir 6 quadrados, sendo que cada um deles vai ter 4 pontos.
Agora, vamos tentar identificar quantas faces tem um Tetraedro:
Como estudamos no capítulo 34 o parâmetro GL_TRIANGLES imprime um triangulo na tela sempre que o terceiro ponto é desenhado.
Esse triangulo que é mostrado pela OpenGL é chamado também de Face.
Agora precisamos identificar em quais coordenadas iremos imprimir cada ponto. E isso não é muito fácil.
No caso do Cubo 3D é mais fácil, já que as coordenas são exatas.
Agora, entender as coordenadas do triangulo é uma tarefa um pouco complicada.
Para escrever o Cubo eu irei criar uma primeira face da mesma forma que vinhemos criando até aqui:
Observe que os pontos estão posicionados a 0.30 pontos de distancia entre si.
Certo, esta é a face da frente, para fazer a face de traz, basta adicionar 0.30 para a coordenada Z também.
Beleza, acredito que tenha ficado fácil de entender agora. Mais esta é a primeira vez que usamos a coordenada Z.
Estamos tentando apresentar os pontos bases da OpenGL separadamente para que você não se confunda na leitura.
Usando o programa base, para fazer o cubo 3d, teremos o seguinte programa abaixo:
CÓDIGO... // Exemplo de Cubo3D usando Allegro e AllegroGL - exemplo não completo // Autor: Adriano Waltrick
// BDJogos
// Data: 09/10/2007
#include <allegro.h>
#include <alleggl.h>
int main()
{
// Iniciações básicas da Allegro
allegro_init();
install_keyboard();
Você vai perceber que o resultado do programa é meio estranho..
É meio que um cubo 3D renderizado errado, mostrando cores de fundo sobrepostas pelas cores de cima,
e outra horas como se as cores de cima fossem incolor. Um resultado bem estranho.
Isto está acontecendo por que precisamos configurar o OpenGL para aceitar as declarações de profundidade.
Os comandos que usaremos para configurar a OpenGL serão estes:
void glShadeModel(GLenum mode);
Especifica a técnica de sombreamento usada na hora da renderização.
Por padrão, a OpenGL interpola as cores dos objetos primitivos na hora da impressão na tela.
Por isso aconteceu o resultado da imagem acima.
Este modo pode habilitar duas opções:
GL_FLAT
Este modo escolhe a cor de uma vértice e traibui a todos os pixels ao seu lado.
GL_SMOOTH
É praticamente a mesma coisa que o Flat, porém mais suavisado.
Independente do modo escolhido, as cores podem ser alteradas dependendo do tipo de iluminação ( ainda não estamos usando );
void glClearDepth(GLclampd depth);
Especifica um valor que será usado pela função glClear para limpar o buffer de profundidade ( depth buffer ).
Os valores podem ser 0 e 1
void glEnable(GLenum cap);
Esta função serve para habilitar várias funcionalidades da OpenGL
GL_DEPTH_TEST
Quando ativamos este parâmetro, a OpenGL poderá fazer comparações de profundade,
atualizando assim o buffer de profundidade ( depth buffer ).
No manual da OpenGL está escrito que,
mesmo tentando dizer que a profundidade é maior que zero,
o sistema de profundidade não vai funcionar se o parâmetro GL_DEPTH_TEST não estiver habilitado.
void glDepthFunc(GLenum func);
Esta função espeficica qual será a função de comparação usada para especificar o sistema de profundidade.
As funções que podem ser escolhidas são:
GL_NEVER
Nunca será comparado
GL_LESS
Sera comparado somente se o valor passado for menor que o valor antigo
GL_EQUAL Sera comparado somente se o valor passado for igual ao valor antigo
GL_LEQUAL
Sera comparado se o valor passado for igual ou menor que o valor antigo
GL_GREATER
Sera comparado se o valor de profundidade passado for maior que o valor de profundidade antigo
GL_NOTEQUAL
Compara qualquer valor que não for igual ao valor antigo
GL_GEQUAL
Compara se o valor for maior ou igual ao antigo
GL_ALWAYS
Sempre compara
void glHint(GLenum target, GLenum mode);
Especifica o modo de comportamento de alguma função/objeto ( no prototipo da função, é o Glenum target ).
Esta função será usada no nosso exemplo para melhorar a forma de renderização.
Iremos passar o seguinte parâmetro para a função:
GL_PERSPECTIVE_CORRECTION_HINT
Indica qual a qualidade das cores, texturas e nublado ( fumaça ).
Quanto maior a qualidade, mais lento será a aplicação.
Iremos usar a qualidade GL_NICEST.
GL_NICEST
A melhor qualidade de gráficos do OpenGL.
Com todas essas funções e parâmetros, teremos definido as seguintes linhas no nosso programa:
glShadeModel( GL_SMOOTH );
// Faz a OpenGL aceitar profunidade
glClearDepth( 1.0f );
glEnable( GL_DEPTH_TEST );
glDepthFunc(GL_LEQUAL);
// Maior qualidade nos gráficos
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
Veja o código acima implementado no novo programa e seu resultado:
// 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...
Certo.. conseguimos fazer o quadrado.
Para fazer o Tetraedo, funciona da mesma maneira.
O único problema é, achar os pontos 3D do Tetraedo, o que pode dificultar um pouco.
A primeira coisa que devemos fazer é criar um triângulo no chão e achar o seu centro.
O centro dele será o topo do poliedro. E nós sabemos que o centro está na metade dos 2 pontos de baixo.
Eu optei por iniciar como nos outros programas antigos, tendo a frente como referência para a primeira face.
Observe que eu usei muito como referencia o ponto mais alto do triângulo da primeira face que é 0.15.
Tende desenhar no papel para tentar visualizar o triangulo em 3D.. Desenhando um triangulo, crie um ponto bem no centro dele, ele será o
ponto mais alto do Tetraedo.
Use o código abaixo nos displays para ver o resultado:
glBegin(GL_TRIANGLES);
// Face da Frente do triângulo, que acaba se tornando a base
glColor3f( 255, 0 , 0 );
glVertex3f( 0.00, 0.00, 0.00 );
glVertex3f( 0.30, 0.00, 0.00 );
glVertex3f( 0.15, 0.30, 0.00 );
// Face de baixo baixo
glColor3f( 0, 255 , 0 );
glVertex3f( 0.00, 0.00, 0.00 );
glVertex3f( 0.30, 0.00, 0.00 );
glVertex3f( 0.15, 0.15, 0.30 );
Para deixar o código mais fácil de ler e de forma organizada, estou usando 2 cadas após a virgula.
Da seguinte forma
"0.00" quando estivermos trabalhando com valores do estilo 0.10 ou 0.35.
Isto faz com que o código não fique desorganizado.
Quanto mais organizado o código, melhor será para lê-lo e alterá-lo.
// função de rotação, estamos rotacionando em todos os ângulos
glRotatef(angulo, 1.0f, 1.0f, 1.0f );
glBegin(GL_TRIANGLES);
// Face da Frente do triângulo, que acaba se tornando a base glColor3f( 255, 0 , 0 ); glVertex3f( 0.00, 0.00, 0.00 ); glVertex3f( 0.30, 0.00, 0.00 ); glVertex3f( 0.15, 0.30, 0.00 );
// Face de baixo baixo glColor3f( 0, 255 , 0 ); glVertex3f( 0.00, 0.00, 0.00 ); glVertex3f( 0.30, 0.00, 0.00 ); glVertex3f( 0.15, 0.15, 0.30 );
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.