Você está na página 1de 60

Primitivas do OpenGL

Tomás Antônio C. Badan

1
Primitivas

 Formas simples que combinadas, geram


objetos mais complexos
 Blocos de construção de objetos
 Podem ser 1D, 2D ou 3D
 Vão desde pontos, linhas até polígonos

2
Volume de Visualização

 Estabelecido no espaço de modelagem


 Definido, por exemplo, pela função:
 glOrtho(-100, 100, -100, 100, -100, 100);

3
Pixel e Vertex

 Pixel
 Menor elemento do monitor de computador
 Definido em um plano 2D
 Vertex
 Um ponto no espaço de modelagem
 Definido em um espaço 3D
 Pode ser definido em um espaço 2D
 Basta considerar Z = 0
 No OpenGL → glVertex
4
Definindo pontos no Espaço
3D
 É estabelecido por uma série de pontos
(função glVertex), encapsulado pelo bloco
glBegin(GL_POINTS)/glEnd()

5
Vertex* - GL_POINTS
GLint p[5][2] = {{0,50},
{-47,15},
{-29,-40}, {29,-40},
{47,15}};

glBegin(GL_POINTS);
glVertex2iv(p[0]);
glVertex2iv(p[2]);
glVertex2iv(p[4]);
glVertex2iv(p[1]);
glVertex2iv(p[3]);
glEnd();

6
Propriedades de Pontos

 Tamanho do ponto (padrão) → 1 pixel


 Alterando o tamanho:
 void glPointSize(GLfloat size);
 Existem valores máximos e mínimos
 Obtendo a faixa permissível:
 GLfloat sizes[2], step;

 glGetFloatv(GL_POINT_SIZE_RANGE, sizes);
 glGetFloatv(GL_POINT_SIZE_GRANULARITY, &step);

7
Propriedades de Pontos (2)

 Pontos são desenhados no formato


quadricular
 Valores de tamanhos não necessitam ser
inteiros
 São aproximações do diâmetro de um círculo
contendo todos os pixels que são usados para
desenhar o ponto

8
Definindo Retas no Espaço 3D

 Uma reta é definida por 2 pontos


 Ponto é definido pela função glVertex
 Em OpenGL
 Encapsular os pontos pelo bloco
glBegin(GL_LINES)/glEnd()
 Cada 2 pontos define uma reta
 Ponto solteiro é descartado

9
Vertex* - GL_LINES
GLint p[5][2] = {{0,50},
{-47,15},
{-29,-40}, {29,-40},
{47,15}};

glBegin(GL_LINES);
glVertex2iv(p[0]);
glVertex2iv(p[2]);
glVertex2iv(p[4]);
glVertex2iv(p[1]);
glVertex2iv(p[3]);
glEnd();

10
Definindo Segmentos de
Retas
 Reta definida por 2 pontos
 Último ponto de um segmento de reta pode
ser considerado como primeiro ponto para o
próximo segmento
 Em OpenGL
 Encapsular os pontos pelo bloco
glBegin(GL_LINE_STRIP)/glEnd()
 Todos os pontos são utilizados

11
Vertex* - GL_LINE_STRIP
GLint p[5][2] = {{0,50},
{-47,15},
{-29,-40}, {29,-40},
{47,15}};

glBegin(GL_LINE_STRIP);
glVertex2iv(p[0]);
glVertex2iv(p[2]);
glVertex2iv(p[4]);
glVertex2iv(p[1]);
glVertex2iv(p[3]);
glEnd();

12
Definindo Segmentos
Fechados
 Equivale ao caso anterior, exceto que o
último ponto é conectado ao primeiro
 Em OpenGL
 Encapsular os pontos pelo bloco
glBegin(GL_LINE_LOOP)/glEnd()

13
Vertex* - GL_LINE_LOOP
GLint p[5][2] = {{0,50},
{-47,15},
{-29,-40}, {29,-40},
{47,15}};

glBegin(GL_LINE_LOOP);
glVertex2iv(p[0]);
glVertex2iv(p[2]);
glVertex2iv(p[4]);
glVertex2iv(p[1]);
glVertex2iv(p[3]);
glEnd();

14
Propriedades das Linhas

 Tamanho da linha → 1 pixel


 Alterando o tamanho:
 void glLineWidth(GLfloat width);
 Obtendo os valores máximo e mínimo
 Sizes[0] → valor mínimo
 Sizes[1] → valor máximo
 GLfloat sizes[2], step;

 glGetFloatv(GL_LINE_WIDTH_RANGE, sizes);
 glGetFloatv(GL_LINE_WIDTH_GRANULARITY, &step);
15
Propriedades das Linhas (2)

 Tracejado
 Primeiramente, deve ser habilitado com:
 glEnable(GL_LINE_STIPPLE);
 Pode ser desabilitado a qualquer momento por:
 glDisable(GL_LINE_STIPPLE);
 Tipo de tracejado é definido por:
 void glLineStipple(GLint factor, Glushort pattern);

16
Propriedades do Tracejado (2)

 Pattern → 16 bits, onde cada bit


representa 1 pixel que está on ou off
 Factor → multiplicador de pixels
 Cada pixel do pattern é multiplicado por este
valor

17
Definindo Polígonos

 Polígonos são consideradas superfícies


 Não definem apenas o perímetro, mas são
fechadas e opacas
 Possuem dois lados → Definido pela
ordem que pontos são definidos (winding)
 Interno
 Sentido horário → regra da mão esquerda
 Externo
 Sentido antihorário → mão direita

18
Polígonos – Definições
Composto de vértices,
arestas (edges) e faces
Devem ser convexos

Não podem haver

arestas cruzadas

19
Triângulos

 É definido por 3 pontos


 Ponto é definido pela função glVertex
 Em OpenGL
 Encapsular os pontos pelo bloco
glBegin(GL_TRIANGLES)/glEnd()
 Se os pontos forem menor do que 3, são
descartados

20
Triângulos (2)

GLint pts[6][2] = {{-100, 0}, {-50, -86},


{50, -86}, {100, 0}, {50, 86},
{-50, 86}};

glBegin(GL_TRIANGLES);
glVertex2iv(pts[0]);
glVertex2iv(pts[1]);
glVertex2iv(pts[5]);
glVertex2iv(pts[2]);
glVertex2iv(pts[3]);
glVertex2iv(pts[4]);
glEnd();

21
Winding

22
Tiras de Triângulos

 Um novo triângulo pode ser definido pelos


dois últimos pontos do triângulo anterior e
definindo um novo ponto
 Em OpenGL
 Encapsular os pontos pelo bloco
glBegin(GL_TRIANGLE_STRIP)/glEnd()

23
Tiras de Triângulos (2)

GLint pts[6][2] = {{-100, 0}, {-50, -86},


{50, -86}, {100, 0}, {50, 86},
{-50, 86}};

glBegin(GL_TRIANGLE_STRIP);
glVertex2iv(pts[0]);
glVertex2iv(pts[1]);
glVertex2iv(pts[5]);
glVertex2iv(pts[2]);
glVertex2iv(pts[4]);
glVertex2iv(pts[3]);
glEnd();

24
Tiras de Triângulos (3)

Definição do winding

 Triângulos numerados de 0 a n → face


externa é definida como:
 Triângulos pares → pn, pn+1 pn+2
 Triângulos impares → pn+1 , pn, pn+2

25
Ventoinha de Triângulos

 Um novo triângulo é formado pelo primeiro


ponto, pelo último utilizado e pelo novo
ponto definido
 Em OpenGL
 Encapsular os pontos pelo bloco
glBegin(GL_TRIANGLE_FAN)/glEnd()

26
Ventoinha de Triângulos (2)

GLint pts[6][2] = {{-100, 0}, {-50, -86},


{50, -86}, {100, 0}, {50, 86},
{-50, 86}};

glBegin(GL_TRIANGLE_FAN);
glVertex2iv(pts[0]);
glVertex2iv(pts[1]);
glVertex2iv(pts[2]);
glVertex2iv(pts[3]);
glVertex2iv(pts[4]);
glVertex2iv(pts[5]);
glEnd();

27
Cores
 É especificado por Vertex
 Cada vértice pode ter uma cor distinta
 Função: glColor
 Qual cor o polígono vai ter?
 Depende do modelo de sombreamento
 glShadeModel(GL_FLAT);
 Cor do último vértice define a cor do polígono
 glShadeModel(GL_SMOOTH);
 Cor do polígono é a interpolação das cores de cada
vértice
28
Exemplo do glShadeModel

29
Escondendo Superfícies
Ocultas – Performance
 Se superfície oculta não precisa ser vista
 Performance é melhorada se não for desenhada
 Chamado de culling
 glEnable(GL_CULL_FACE);
 Voltando a desenhar as superfícies
 glEnable(GL_CULL_FACE);
 Note que superfícies parcialmente ocultas são
desenhadas
 Note a diferença entre superfície interna e
externa → interna não é vista quando habilitada
30
Culling

31
Formatação do Polígono

 Padrão → polígono é preenchido pela cor


sólida
 glPolygonMode(face, modo);
 Onde:
 Face → GL_FRONT, GL_BACK,
GL_FRONT_AND_BACK
 Mode → GL_POINT, GL_LINE, GL_FILL

32
Quadriláteros (2)

GLint pts[8][2] = {
{-10, 10}, {-10, 0}, {0, 0}, {0,10},
{5,5}, {5,0}, {10,0}, {10,5}};

glBegin(GL_QUADS);
glVertex2iv(pts[0]);
glVertex2iv(pts[1]);
glVertex2iv(pts[2]);
glVertex2iv(pts[3]);
glVertex2iv(pts[4]);
glVertex2iv(pts[5]);
glVertex2iv(pts[6]);
glVertex2iv(pts[7]);
glEnd();

33
Tiras de Quadriláteros

 Novo quadrilátero é definido usando os


dois últimos pontos e definindo 2 novos
pontos
 Em OpenGL
 Encapsular os pontos pelo bloco
glBegin(GL_QUAD_STRIP)/glEnd()

34
Tiras de Quadriláteros (2)

GLint pts[8][2] = {
{-10, 10}, {-10, 0}, {0, 0}, {0,10},
{5,5}, {5,0}, {10,0}, {10,5}};

glBegin(GL_QUAD_STRIP);
glVertex2iv(pts[0]);
glVertex2iv(pts[1]);
glVertex2iv(pts[3]);
glVertex2iv(pts[2]);
glVertex2iv(pts[4]);
glVertex2iv(pts[5]);
glVertex2iv(pts[7]);
glVertex2iv(pts[6]);
glEnd();

35
Tiras de Quadriláteros (3)

Definição do winding

 GL_QUAD_STRIP
 Vertices → face externa
 2n – 1, 2n, 2n + 2 e 2n + 1

36
Preenchimento de Polígonos

 2 modos:
 Texturização
 Aplicando padrões
 Composto de um bitmap de 32x32 pontos

37
Resumo
Note que está sendo usado a regra da mão esquerda
(visão interior das faces

38
FIM

39
GL – Funções

 Funções de linhas:
GL_POINTS, GL_LINES, GL_LINE_STRIP,

GL_LINE_LOOP
 Funções de preenchimento de áreas:
GL_TRIANGLES, GL_TRIANGLE_STRIP,
GL_TRIANGLE_FAN, GL_QUADS,
GL_QUAD_STRIP, GL_POLYGON
 Curvas são aproximadas por polígonos
Processo conhecido por Tessellation

40
Polígonos - Definições

Composto de vértices,
arestas (edges) e faces
Devem ser convexos

Não podem haver

arestas cruzadas

41
Face Frontal e Traseira

 Todo polígono tem duas faces


 Visibilidade diferente para cada face
 glPolygonMode(face, mode);
Vetor normal à superfície mostra a face externa,

ou frontal
Vértices posicionados no sentido contrário do relógio
fornece a face frontal
Regra da mão direita

 Eliminar faces escondidas


glEnable(GL_CULL_FACE);
glDisable(GL_CULL_FACE);

42
GL – Funções
 glVertex*: especifica pontos
 glBegin, glEnd
Delimita os vértices de uma primitiva
Primitivas de linha

GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_LINE_LOOP,


Primitivas de Área

GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN,

GL_QUADS, GL_QUAD_STRIP, GL_POLYGON

glRect*: desenha um retângulo 2D


glPushMatrix, glPopMatrix

 Operações de pilha sobre a matriz corrente


43
GL – Operação de Matrizes

 glMatrixMode
GL_MODELVIEW, GL_PROJECTION,

GL_TEXTURE e GL_COLOR
 glLoadIdentity:
Substitui a corrente pela matriz identidade

 glLoadMatrix*:
substitui a matriz corrente pela especificada

 glMultMatrix*
Multiplica a matriz corrente com a especificada

44
Exemplo
void desenha(void) { glBegin(GL_QUADS);
GLfloat cubo[8][3] = { glColor3fv(cuboColor[0]); glVertex3fv(cubo[0]);
{ 1.000000, -1.000000, -1.000000}, glColor3fv(cuboColor[1]); glVertex3fv(cubo[1]);
{ 1.000000, -1.000000, 1.000000}, glColor3fv(cuboColor[2]); glVertex3fv(cubo[2]);
{-1.000000, -1.000000, 1.000000}, glColor3fv(cuboColor[3]);glVertex3fv(cubo[3]);
{-1.000000, -1.000000, -1.000000},
{ 1.000000, 1.000000, -1.000000}, glColor3fv(cuboColor[4]); glVertex3fv(cubo[4]);
{ 1.000000, 1.000000, 1.000000}, glColor3fv(cuboColor[7]); glVertex3fv(cubo[7]);
{-1.000000, 1.000000, 1.000000}, glColor3fv(cuboColor[6]); glVertex3fv(cubo[6]);
{-1.000000, 1.000000, -1.000000} glColor3fv(cuboColor[5]); glVertex3fv(cubo[5]);
};
glColor3fv(cuboColor[0]); glVertex3fv(cubo[0]);
GLfloat cuboColor[8][3] = { glColor3fv(cuboColor[4]); glVertex3fv(cubo[4]);
{1.0, 0.0, 0.0}, glColor3fv(cuboColor[5]); glVertex3fv(cubo[5]);
{0.0, 1.0, 0.0}, glColor3fv(cuboColor[1]); glVertex3fv(cubo[1]);
{0.0, 0.0, 1.0},
{1.0, 1.0, 0.0}, glColor3fv(cuboColor[1]); glVertex3fv(cubo[1]);
{0.0, 1.0, 1.0}, glColor3fv(cuboColor[5]); glVertex3fv(cubo[5]);
{1.0, 0.0, 1.0}, glColor3fv(cuboColor[6]); glVertex3fv(cubo[6]);
}; glColor3fv(cuboColor[2]); glVertex3fv(cubo[2]);
glColor3fv(cuboColor[2]); glVertex3fv(cubo[2]);
// limpa o buffer para um novo quadro glColor3fv(cuboColor[6]); glVertex3fv(cubo[6]);
glClear(GL_COLOR_BUFFER_BIT); glColor3fv(cuboColor[7]); glVertex3fv(cubo[7]);
glColor3fv(cuboColor[3]); glVertex3fv(cubo[3]);
glMatrixMode(GL_MODELVIEW); // matrix de modelagem
glLoadIdentity(); // zera qualquer transformação glColor3fv(cuboColor[4]); glVertex3fv(cubo[4]);
gluLookAt(eye[0], eye[1], eye[2], 0, 0, 0, 0, 1, 0); glColor3fv(cuboColor[0]); glVertex3fv(cubo[0]);
glColor3fv(cuboColor[3]); glVertex3fv(cubo[3]);
glColor3fv(cuboColor[7]); glVertex3fv(cubo[7]); 45
glEnd(); glFlush(); }
GL – Miscelâneas

 glColor* → especifica a cor corrente


glClearColor → cor de fundo do buffer
glClear:

GL_COLOR_BUFFER_BIT ou

GL_DEPTH_BUFFER_BIT ou
GL_ACCUM_BUFFER_BIT ou
GL_STENCIL_BUFFER_BIT
 glFlush:
força a execução da pilha de comandos

46
GL – Miscelâneas (2)

glRasterPos*
especifica a posição de raster para operações de

pixel
glNewList, glGenLists, glCallList, glEndList
Comandos que podem ser chamados e

executados posteriormente
Úteis para a modelagem de objetos repetitivos

 glFrustum: matriz perspectiva

47
Display List

 Otimiza a criação de objetos estáticos


Armazena os comandos em linguagem de

hardware para futuro processamento


Depois de criado não pode ser alterado
Lista pode ser armazenada no buffer da placa de vídeo ou

na memória
Normalmente é criada na inicialização do programa

Depende do tipo de aplicação (jogos, por exemplo, as utilizaria para


inicializar os níveis ou fases)

48
Display List - comandos

 GLuint glGenLists(faixa);
 Reserva uma faixa de ID de listas
Retorna zero no caso de erro

 glNewList(id, tipo); / glEndList();


 Cria uma lista estática
Tipo = GL_COMPILE ou

GL_COMPILE_AND_EXECUTE
Permitido definição de objetos e mudanças de estado na
máquina OpenGL
Permite chamar outras listas também
49
Display List – comandos (2)

 glCallList(id);
 Invoca uma lista previamente criada
 glDeleteLists(id inicial, faixa);
 Libera a memória de uma lista
Evitar colocar informações de textura em
lista
 Desperdício de memória
Acesso ao buffer de vídeo não tem sentindo

numa lista 50
Exemplo
void init(void) {
GLfloat cubo[8][3] = { glColor3fv(cuboColor[4]); glVertex3fv(cubo[4]);
{ 1.000000, -1.000000, -1.000000}, glColor3fv(cuboColor[7]); glVertex3fv(cubo[7]);
{ 1.000000, -1.000000, 1.000000}, glColor3fv(cuboColor[6]); glVertex3fv(cubo[6]);
{-1.000000, -1.000000, 1.000000}, glColor3fv(cuboColor[5]); glVertex3fv(cubo[5]);
{-1.000000, -1.000000, -1.000000},
{ 1.000000, 1.000000, -1.000000}, glColor3fv(cuboColor[0]); glVertex3fv(cubo[0]);
{ 1.000000, 1.000000, 1.000000}, glColor3fv(cuboColor[4]); glVertex3fv(cubo[4]);
{-1.000000, 1.000000, 1.000000}, glColor3fv(cuboColor[5]); glVertex3fv(cubo[5]);
{-1.000000, 1.000000, -1.000000} glColor3fv(cuboColor[1]); glVertex3fv(cubo[1]);
};
GLfloat cuboColor[8][3] = { glColor3fv(cuboColor[1]); glVertex3fv(cubo[1]);
{1.0, 0.0, 0.0}, glColor3fv(cuboColor[5]); glVertex3fv(cubo[5]);
{0.0, 1.0, 0.0}, glColor3fv(cuboColor[6]); glVertex3fv(cubo[6]);
{0.0, 0.0, 1.0}, glColor3fv(cuboColor[2]); glVertex3fv(cubo[2]);
{1.0, 1.0, 0.0},
{0.0, 1.0, 1.0}, glColor3fv(cuboColor[2]); glVertex3fv(cubo[2]);
{1.0, 0.0, 1.0}, glColor3fv(cuboColor[6]); glVertex3fv(cubo[6]);
}; glColor3fv(cuboColor[7]); glVertex3fv(cubo[7]);
list = glGenLists(1); glColor3fv(cuboColor[3]); glVertex3fv(cubo[3]);
if ( !list) {
printf("Impossível alocar nova lista\n"); glColor3fv(cuboColor[4]); glVertex3fv(cubo[4]);
exit(EXIT_FAILURE); glColor3fv(cuboColor[0]); glVertex3fv(cubo[0]);
} glColor3fv(cuboColor[3]); glVertex3fv(cubo[3]);
glColor3fv(cuboColor[7]); glVertex3fv(cubo[7]);
glNewList(list, GL_COMPILE); glEnd();
glBegin(GL_QUADS); glEndList();
glColor3fv(cuboColor[0]); glVertex3fv(cubo[0]);
glColor3fv(cuboColor[1]); glVertex3fv(cubo[1]); glClearColor(0, 0, 0, 1.0); // cor de fundo (branco) 51
glColor3fv(cuboColor[2]); glVertex3fv(cubo[2]); }
glColor3fv(cuboColor[3]);glVertex3fv(cubo[3]);
Exemplo - Continuação
void desenha(void) {
// limpa o buffer para um novo quadro
glClear(GL_COLOR_BUFFER_BIT); // todos os bit são iguais à branco

glMatrixMode(GL_MODELVIEW); // matrix de modelagem


glLoadIdentity(); // zera qualquer transformação
gluLookAt(eye[0], eye[1], eye[2], 0, 0, 0, 0, 1, 0); // direção de visualização

glCallList(list);

glFlush(); // força a visualização


}

52
Display list - comentários

 Ganho de performance?
 Não precisa criar o objeto toda vez que é invocado
Objetos do mesmo tipo pode ser chamado várias
vezes, com uma única inicialização

53
Vetor de vértices

 Permite a criação de lista de forma dinâmica


Pode ser mudado o formato do objeto dentro do
vetor previamente calculado
Exemplo, uma mesh que define o oceano, em cada quadro,

a mesh pode ser atualizada


No OpenGL, o vetor é transferido do cliente para o
servidor em lote
Ganho de performance

54
Vetor de Vértices - Etapas

Construir os vetores – vértice, cor,


coordenadas de textura, vetor normal, etc


Dizer ao OpenGL onde se encontram esses
vetores
Dizer quais vetores a aplicação está
interessada
Executar a renderização do quadro

55
Vetor de Vértices - Comandos

 Habilitando vetores:
 gGlEnableClientState(x); glDisableClientState(x);
X = GL_VERTEX_ARRAY, GL_COLOR_ARRAY,
GL_NORMAL_ARRAY, etc
Note que é uma operação realizada do lado do cliente e

não do servidor

56
Vetor de Vértices – Comandos
(2)
 Onde estão os dados?
 glVertexPointer(...);
 glColorPointer(...);
 glNormalPointer(...);
 Desenhando
 glArrayElement(índice);
Especifica o indice do vetor previamente registrado

57
Vetor de Vértices – Comandos
(3)
 Forma mais econômica:
 glDrawArrays(mode, first, count);
Desenha o objeto (mode = GL_TRIANGLES, etc), com o
índice iniciando em first e count especificando a quantidade
 Forma usando vetor de índices
 glDrawElements(mode, count, tipo, indices);
Mesmo comentário anterior, onde índice é um vetor

58
Exemplo
// váriaveis globais, ou estáticas na função
// desenha()
GLfloat cubo[24] = { void init(void) {
1.000000, -1.000000, -1.000000, glEnableClientState(GL_VERTEX_ARRAY);
1.000000, -1.000000, 1.000000, glEnableClientState(GL_COLOR_ARRAY);
-1.000000, -1.000000, 1.000000,
-1.000000, -1.000000, -1.000000, glClearColor(0.5, 0.5, 0.5, 1.0); // cor de fundo (cinza)
1.000000, 1.000000, -1.000000, }
1.000000, 1.000000, 1.000000,
-1.000000, 1.000000, 1.000000, void desenha(void) {
-1.000000, 1.000000, -1.000000 // limpa o buffer para um novo quadro
}; glClear(GL_COLOR_BUFFER_BIT); // todos os bit são iguais à branco

GLfloat cuboColor[24] = { glMatrixMode(GL_MODELVIEW); // matrix de modelagem


1.0, 0.0, 0.0, glLoadIdentity(); // zera qualquer transformação
0.0, 1.0, 1.0, gluLookAt(eye[0], eye[1], eye[2], 0, 0, 0, 0, 1, 0); // direção de
0.0, 0.0, 1.0, // visualização
1.0, 1.0, 0.0,
0.0, 1.0, 1.0, glVertexPointer(3, GL_FLOAT, 0, cubo);
1.0, 0.0, 1.0 glColorPointer(3, GL_FLOAT, 0, cuboColor);
}; glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, indices);

GLubyte indices[24] = { glFlush(); // força a visualização


0, 1, 2, 3, }
4, 7, 6, 5,
0, 4, 5, 1,
1, 5, 6, 2,
2, 6, 7, 3,
4, 0, 3, 7 59
};
Bibliografia Adicional

http://www.opengl.org/sdk/docs/man/
http://www.opengl.org/resources/libraries/glut/sp

http://www.opengl.org/resources/code/samples/gl

ut_examples/examples/examples.html

60