Desenhos Tridimensionais

28
Desenhos Desenhos Tridimensionais Tridimensionais

description

Desenhos Tridimensionais. Primitivas Gráficas em 3D. - PowerPoint PPT Presentation

Transcript of Desenhos Tridimensionais

Page 1: Desenhos Tridimensionais

Desenhos Desenhos TridimensionaisTridimensionais

Page 2: Desenhos Tridimensionais

Primitivas Gráficas em 3DPrimitivas Gráficas em 3D

A forma de representação de objetos 3D A forma de representação de objetos 3D mais utilizada em computação gráfica mais utilizada em computação gráfica consiste na especificação de uma malha consiste na especificação de uma malha de faces poligonais. Uma superfície de faces poligonais. Uma superfície discretizada por faces planas que podem discretizada por faces planas que podem ser triângulos (preferencialmente) ou ser triângulos (preferencialmente) ou quadrados com tabela de vértices e tabela quadrados com tabela de vértices e tabela de faces.de faces.

Page 3: Desenhos Tridimensionais

A utilização de primitivas gráficas em três A utilização de primitivas gráficas em três e duas dimensões é praticamente igual. A e duas dimensões é praticamente igual. A principal diferença está na especificação principal diferença está na especificação dos vértices , pois em 3 dimensões deve-dos vértices , pois em 3 dimensões deve-se atribuir um valor para a coordenada Z. se atribuir um valor para a coordenada Z. Qualquer uma das primitivas gráficas Qualquer uma das primitivas gráficas podem ser utilizadas quando se está podem ser utilizadas quando se está trabalhando em 3 dimensões.trabalhando em 3 dimensões.

Page 4: Desenhos Tridimensionais

Implementação de um objetoImplementação de um objeto

A primeira providência é definir algumas A primeira providência é definir algumas estruturas para armazenar vértices e estruturas para armazenar vértices e faces. A estrutura de vértices é faces. A estrutura de vértices é simplesmente uma coordenada 3D:simplesmente uma coordenada 3D:

// Define um vértice// Define um vérticetypedef struct {typedef struct {

float x,y,z;float x,y,z; // posição no espaço // posição no espaço} VERT;} VERT;

Page 5: Desenhos Tridimensionais

Já na estrutura de Já na estrutura de facesfaces é preciso armazenar o é preciso armazenar o total de vértices sendo utilizados por cada uma total de vértices sendo utilizados por cada uma e um outro vetor, que contém os índices para e um outro vetor, que contém os índices para cada vértice. (Triângulos e Quadriláteros)cada vértice. (Triângulos e Quadriláteros)

// Define uma face// Define uma face typedef struct {typedef struct { int total;int total; // total de vértices// total de vértices int ind[4];int ind[4]; // índices para o vetor de // índices para o vetor de

vérticesvértices } FACE;} FACE;

Page 6: Desenhos Tridimensionais

A última estrutura é para representar um objeto A última estrutura é para representar um objeto – aqui se guardam apontadores para o vetor de – aqui se guardam apontadores para o vetor de vértices, para o vetor de faces e também a vértices, para o vetor de faces e também a quantidade de faces, uma vez que essa quantidade de faces, uma vez que essa informação não existe em nenhum outro local:informação não existe em nenhum outro local:

// Define um objeto 3D// Define um objeto 3D typedef struct {typedef struct { VERT *vertices;VERT *vertices; // aponta para os vértices// aponta para os vértices FACE *faces;FACE *faces; // aponta para as faces// aponta para as faces int total_faces;int total_faces; // total de faces no objeto// total de faces no objeto } OBJ;} OBJ;

Page 7: Desenhos Tridimensionais

Vetor de vérticeVetor de vértice

// Definição dos vértices// Definição dos vértices VERT vertices[ ] = {VERT vertices[ ] = { { -1, 0, -1 },{ -1, 0, -1 }, // 0 canto inf esquerdo tras.// 0 canto inf esquerdo tras. { 1, 0, -1 },{ 1, 0, -1 }, // 1 canfo inf direito tras.// 1 canfo inf direito tras. { 1, 0, 1 },{ 1, 0, 1 }, // 2 canto inf direito diant.// 2 canto inf direito diant. { -1, 0, 1 }, // 3 canto inf esquerdo diant.{ -1, 0, 1 }, // 3 canto inf esquerdo diant. { 0, 2, 0 }, // 4 topo{ 0, 2, 0 }, // 4 topo };};

Page 8: Desenhos Tridimensionais

Vetor de FacesVetor de Faces

// Definição das faces// Definição das facesFACE faces[] = {FACE faces[] = { { 4, { 0,1,2,3 }},{ 4, { 0,1,2,3 }}, // base// base { 3, { 0,1,4,-1 }},{ 3, { 0,1,4,-1 }}, // lado traseiro// lado traseiro { 3, { 0,3,4,-1 }},{ 3, { 0,3,4,-1 }}, // lado esquerdo// lado esquerdo { 3, { 1,2,4,-1 }},{ 3, { 1,2,4,-1 }}, // lado direito// lado direito { 3, { 3,2,4,-1 }}{ 3, { 3,2,4,-1 }} // lado dianteiro// lado dianteiro };};

Page 9: Desenhos Tridimensionais

Definição do ObjetoDefinição do Objeto

// Finalmente, define o objeto pirâmide// Finalmente, define o objeto pirâmide

OBJ piramide = {OBJ piramide = { vertices, faces, 5 };vertices, faces, 5 };

Page 10: Desenhos Tridimensionais

Por que fazer tudo isso?Por que fazer tudo isso?

Page 11: Desenhos Tridimensionais

Faces diretamente no código?Faces diretamente no código?

- - Separar o modelo 3D do código que Separar o modelo 3D do código que desenha o mesmo;desenha o mesmo;

** Se trocar o modelo não será necessário Se trocar o modelo não será necessário modificar o código.modificar o código.

- Eficiência no armazenamento: Eficiência no armazenamento: se substituirmos as estruturas por um se substituirmos as estruturas por um conjunto de chamadas de desenho, conjunto de chamadas de desenho, potencialmente vários vértices serão potencialmente vários vértices serão repetidamente informados.repetidamente informados.

Page 12: Desenhos Tridimensionais

Pirâmide:Pirâmide:

Cada vértice é compartilhado por pelo Cada vértice é compartilhado por pelo menos três faces. Isso também criaria um menos três faces. Isso também criaria um problema considerável no caso da problema considerável no caso da necessidade de alterar o modelo: todas necessidade de alterar o modelo: todas as ocorrências de cada vértice teriam que as ocorrências de cada vértice teriam que ser modificadas.ser modificadas.

Page 13: Desenhos Tridimensionais

Função:Função:

Partindo dessas razões, escrevemos uma Partindo dessas razões, escrevemos uma função que recebe um objeto genérico, função que recebe um objeto genérico, indicado por sua estrutura devidamente indicado por sua estrutura devidamente preenchida, e traça o contorno de todas preenchida, e traça o contorno de todas as suas faces (usando GL_LINE_LOOP):as suas faces (usando GL_LINE_LOOP):

Page 14: Desenhos Tridimensionais

// Desenha um objeto em wireframe// Desenha um objeto em wireframe void DesenhaObjetoWireframe(OBJ *objeto)void DesenhaObjetoWireframe(OBJ *objeto) {{ OBJ *obj = objeto;OBJ *obj = objeto; // Percorre todas as faces// Percorre todas as faces for(int f=0; f < obj->total_faces; ++f)for(int f=0; f < obj->total_faces; ++f) {{ glBegin(GL_LINE_LOOP);glBegin(GL_LINE_LOOP); // Percorre todos os vértices da face// Percorre todos os vértices da face for(int v=0; v < obj->faces[f].total; ++v)for(int v=0; v < obj->faces[f].total; ++v) glVertex3f(obj-glVertex3f(obj-

>vertices[faces[f].ind[v]].x,>vertices[faces[f].ind[v]].x, obj->vertices[faces[f].ind[v]].y,obj->vertices[faces[f].ind[v]].y, obj->vertices[faces[f].ind[v]].z);obj->vertices[faces[f].ind[v]].z); }} glEnd();glEnd(); }}

Page 15: Desenhos Tridimensionais

Para desenhar um objeto, basta agora Para desenhar um objeto, basta agora chamar a função chamar a função “DesenhaObjetoWireframe” e passar um “DesenhaObjetoWireframe” e passar um apontador para o objeto desejado (se apontador para o objeto desejado (se houver mais de um). Isso é feito na função houver mais de um). Isso é feito na função callback de desenho:callback de desenho:

Page 16: Desenhos Tridimensionais

// Função callback de redesenho da janela de visualização// Função callback de redesenho da janela de visualização void Desenha(void)void Desenha(void) {{ // Limpa a janela de visualização com a cor // Limpa a janela de visualização com a cor // de fundo definida previamente// de fundo definida previamente glClear(GL_COLOR_BUFFER_BIT);glClear(GL_COLOR_BUFFER_BIT);

// Altera a cor do desenho para preto// Altera a cor do desenho para preto glColor3f(0.0f, 0.0f, 0.0f);glColor3f(0.0f, 0.0f, 0.0f);

// Desenha o objeto definido anteriormente: uma // Desenha o objeto definido anteriormente: uma pirâmidepirâmide

DesenhaObjetoWireframe(&piramide);DesenhaObjetoWireframe(&piramide);

// Executa os comandos OpenGL// Executa os comandos OpenGL glFlush();glFlush(); }}

Page 17: Desenhos Tridimensionais

Este exemplo também introduz um Este exemplo também introduz um conceito muito importante: comandos de conceito muito importante: comandos de navegação, que serão incluidos em quase navegação, que serão incluidos em quase todos os demais códigos, como segue:todos os demais códigos, como segue:

- Movimento do mouse: botões esquerdo, - Movimento do mouse: botões esquerdo, direito e centro.direito e centro.

- Teclas Home e End- Teclas Home e End

Page 18: Desenhos Tridimensionais

A implementação desses comandos é A implementação desses comandos é realizada em funções diferentes: para realizada em funções diferentes: para rotacionar o objeto, utilizam-se duas rotacionar o objeto, utilizam-se duas variáveis – rotX e rotY - que são variáveis – rotX e rotY - que são empregados na função que posiciona o empregados na função que posiciona o observador (PosicionaObservador). Nessa observador (PosicionaObservador). Nessa mesma função também se empregam as mesma função também se empregam as variáveis obsX, obsY e obsZ, que variáveis obsX, obsY e obsZ, que informam a posição do objeto em relação informam a posição do objeto em relação ao observador.ao observador.

Page 19: Desenhos Tridimensionais

// Função usada para especificar a posição do // Função usada para especificar a posição do observador virtualobservador virtual

void PosicionaObservador(void)void PosicionaObservador(void) {{ // Especifica sistema de coordenadas do // Especifica sistema de coordenadas do

modelomodelo glMatrixMode(GL_MODELVIEW);glMatrixMode(GL_MODELVIEW); // Inicializa sistema de coordenadas do // Inicializa sistema de coordenadas do

modelomodelo glLoadIdentity();glLoadIdentity(); // Posiciona e orienta o observador// Posiciona e orienta o observador glTranslatef(-obsX,-obsY,-obsZ);glTranslatef(-obsX,-obsY,-obsZ); glRotatef(rotX,1,0,0);glRotatef(rotX,1,0,0); glRotatef(rotY,0,1,0);glRotatef(rotY,0,1,0); }}

Page 20: Desenhos Tridimensionais

Ângulo de VisãoÂngulo de Visão

Já o ângulo de visão (variável Já o ângulo de visão (variável angleangle) é ) é empregada na funçãoempregada na função

EspecificaParametrosDeVisualizacao:EspecificaParametrosDeVisualizacao:

Page 21: Desenhos Tridimensionais

// Função usada para especificar o volume de // Função usada para especificar o volume de visualizaçãovisualização

void EspecificaParametrosVisualizacao(void)void EspecificaParametrosVisualizacao(void) {{ // Especifica sistema de coordenadas de projeção// Especifica sistema de coordenadas de projeção glMatrixMode(GL_PROJECTION);glMatrixMode(GL_PROJECTION); // Inicializa sistema de coordenadas de projeção// Inicializa sistema de coordenadas de projeção glLoadIdentity();glLoadIdentity();

// Especifica a projeção // Especifica a projeção perspectiva(angulo,aspecto,zMin,zMax)perspectiva(angulo,aspecto,zMin,zMax)

gluPerspective(angle,fAspect,0.1,1200);gluPerspective(angle,fAspect,0.1,1200);

PosicionaObservador();PosicionaObservador(); }}

Page 22: Desenhos Tridimensionais

Callbacks de mouseCallbacks de mouse // Função callback para eventos de botões do mouse// Função callback para eventos de botões do mouse void GerenciaMouse(int button, int state, int x, int y)void GerenciaMouse(int button, int state, int x, int y) {{ if(state==GLUT_DOWN)if(state==GLUT_DOWN) {{ // Salva os parâmetros atuais// Salva os parâmetros atuais x_ini = x;x_ini = x; y_ini = y;y_ini = y; obsX_ini = obsX;obsX_ini = obsX; obsY_ini = obsY;obsY_ini = obsY; obsZ_ini = obsZ;obsZ_ini = obsZ; rotX_ini = rotX;rotX_ini = rotX; rotY_ini = rotY;rotY_ini = rotY; bot = button;bot = button; }} else bot = -1;else bot = -1; }}

Page 23: Desenhos Tridimensionais

Durante o movimento em si, a GLUT chama a Durante o movimento em si, a GLUT chama a função função GerenciaMovimGerenciaMovim, a qual recebe as , a qual recebe as coordenadas atualizadas do mouse. coordenadas atualizadas do mouse. Primeiramente, determina-se qual botão foi Primeiramente, determina-se qual botão foi pressionado: se foi o botão esquerdo, calculam-pressionado: se foi o botão esquerdo, calculam-se as diferenças (em X e Y) entre a posição se as diferenças (em X e Y) entre a posição atual e a inicial (salva na função atual e a inicial (salva na função GerenciaMouseGerenciaMouse), e atualizamos as variáveis ), e atualizamos as variáveis que controlam a rotação do objeto. A constante que controlam a rotação do objeto. A constante SENS_ROT, definida antes da função, permite SENS_ROT, definida antes da função, permite especificar a sensibilidade do movimento: especificar a sensibilidade do movimento: quanto maior o valor, mais o mouse terá que ser quanto maior o valor, mais o mouse terá que ser deslocado para afetar a rotação.deslocado para afetar a rotação.

Page 24: Desenhos Tridimensionais

// Função callback para eventos de movimento do mouse// Função callback para eventos de movimento do mouse #define SENS_ROT#define SENS_ROT5.05.0 #define SENS_OBS#define SENS_OBS15.015.0 #define SENS_TRANSL#define SENS_TRANSL 30.030.0 void GerenciaMovim(int x, int y)void GerenciaMovim(int x, int y) {{ // Botão esquerdo ?// Botão esquerdo ? if(bot==GLUT_LEFT_BUTTON)if(bot==GLUT_LEFT_BUTTON) {{ // Calcula diferenças// Calcula diferenças int deltax = x_ini - x;int deltax = x_ini - x; int deltay = y_ini - y;int deltay = y_ini - y; // E modifica ângulos// E modifica ângulos rotY = rotY_ini - deltax/SENS_ROT;rotY = rotY_ini - deltax/SENS_ROT; rotX = rotX_ini - deltay/SENS_ROT;rotX = rotX_ini - deltay/SENS_ROT; }}

Page 25: Desenhos Tridimensionais

No segundo trecho, trata-se o botão No segundo trecho, trata-se o botão direito: nesse caso, basta calcular a direito: nesse caso, basta calcular a diferença apenas em Y e atualizar a diferença apenas em Y e atualizar a variável obsZ. É utilizada outra constante, variável obsZ. É utilizada outra constante, SENS_OBSSENS_OBS, também para definira , também para definira sensibilidade do movimento: sensibilidade do movimento:

Page 26: Desenhos Tridimensionais

// Botão direito ?// Botão direito ? else if(bot==GLUT_RIGHT_BUTTON)else if(bot==GLUT_RIGHT_BUTTON) {{ // Calcula diferença// Calcula diferença int deltaz = y_ini - y;int deltaz = y_ini - y; // E modifica distância do // E modifica distância do

observadorobservador obsZ = obsZ_ini + obsZ = obsZ_ini +

deltaz/SENS_OBS;deltaz/SENS_OBS; }}

Page 27: Desenhos Tridimensionais

Por fim, o último trecho considera o botão Por fim, o último trecho considera o botão do meio: o processo é praticamente o do meio: o processo é praticamente o mesmo do primeiro trecho, mas atualizam-mesmo do primeiro trecho, mas atualizam-se as variáveis que controlam a translação se as variáveis que controlam a translação em X e Y: obsX e obsY. Porém, note que em X e Y: obsX e obsY. Porém, note que as diferenças são somadas em X, mas as diferenças são somadas em X, mas subtraídas em Y, de modo que se o subtraídas em Y, de modo que se o mouse for deslocado para baixo, o objeto mouse for deslocado para baixo, o objeto também será movido na mesma direção. também será movido na mesma direção. A constante de sensibilidade empregada A constante de sensibilidade empregada aqui é denominada SENS_TRANSL: aqui é denominada SENS_TRANSL:

Page 28: Desenhos Tridimensionais

// Botão do meio ?// Botão do meio ? else if(bot==GLUT_MIDDLE_BUTTON)else if(bot==GLUT_MIDDLE_BUTTON) {{ // Calcula diferenças// Calcula diferenças int deltax = x_ini - x;int deltax = x_ini - x; int deltay = y_ini - y;int deltay = y_ini - y; // E modifica posições// E modifica posições obsX = obsX_ini + deltax/SENS_TRANSL;obsX = obsX_ini + deltax/SENS_TRANSL; obsY = obsY_ini - deltay/SENS_TRANSL;obsY = obsY_ini - deltay/SENS_TRANSL; }} PosicionaObservador();PosicionaObservador(); glutPostRedisplay();glutPostRedisplay(); }}