Você está na página 1de 58

OpenGL

Parte I: Geometria

Waldemar Celes
Departamento de Informática
Tecgraf/PUC-Rio
OpenGL: o que é?

 API
 Interface para programador de aplicação
Aplicação

API abstrata

API

Hardware & Software

Dispositivo Dispositivo
de saída de entrada
Por que OpenGL?

 rápido
 relativamente simples
 arquitetura bem definida
 bem documentado
 independente de sistemas de janelas
 primitivas geométricas e imagens
 padrão
 disponível em diversas plataformas
Pipeline de renderização

Operações Operações
Vértices Rasterização
geométricas sobre
fragmentos

Operações Textura
Imagens
sobre imagens
Frame
Buffer
Primitivas geométricas básicas

Ponto Linha Triângulo

Quadrado Polígono
Objetos 3D

From SIGGRAPH’97 course


Imagem e Textura
Aplicação típica

Aplicação

GLU
Sistema de
Interface (GLUT) OpenGL

Hardware
Programa simples (usando GLUT)

#ifdef _WIN32 int main (int argc, char* argv[])


#include <windows.h> {
#endif /* open GLUT */
#include "GL/gl.h" glutInit(&argc, argv);
#include "GL/glu.h” glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
#include “GL/glut.h” glutInitWindowSize (250, 250);

/* create window */
glutCreateWindow ("simple");
glutReshapeFunc(reshape);
glutDisplayFunc(display);

/* interact … */
glutMainLoop();
return 0;
}
Programa simples (usando GLUT)

void reshape (int w, int h) void display (void)


{ {
glViewport(0,0,w,h); /* clear window */
glClearColor(1,1,1,1); glClear(GL_COLOR_BUFFER_BIT);
}
/* draw red triangle */
glColor3d(1,0,0);
glBegin(GL_TRIANGLES);
glVertex2d(-1,-1);
glVertex2d(1,-1);
glVertex2d(0,1);
glEnd();

/* update screen */
glFlush();
}
Programa simples (usando IUP)

#include "iup.h" int main (void)


#include "iupgl.h" {
Ihandle *dg, *cv;
#ifdef _WIN32 /* open GUI */
#include <windows.h> IupOpen();
#endif IupGLCanvasOpen();
#include "GL/gl.h" /* create canvas and dialog */
#include "GL/glu.h" cv = IupGLCanvas( "redraw" );
dg = IupDialog(cv);
IupSetAttribute(dg,"SIZE","200x200");
IupSetFunction("redraw",(Icallback)redraw);
IupShow(dg);
/* interact... */
IupMainLoop();
IupClose();
return 0;
}
Programa simples (usando IUP)
int redraw (Ihandle *cv, double x, double y)
{
IupGLMakeCurrent(cv);
/* clear window */
glClearColor(1,1,1,1);
glClear(GL_COLOR_BUFFER_BIT);
/* draw red triangle */
glColor3d(1,0,0);
glBegin(GL_TRIANGLES);
glVertex2d(-1,-1);
glVertex2d(1,-1);
glVertex2d(0,1);
glEnd();
/* update screen */
glFlush();
return IUP_DEFAULT;
}
OpenGL & IUP
#include “iup.h”
Bibliotecas:
#include “iupgl.h” • IUP
iup.lib & iupgl.lib
Inicialização • OpenGL
IupOpen(); opengl.lib & glu.lib (SGI)
IupGLCanvasOpen(); opengl32.lib & glu32.lib (MS)

Criação em C
cv = IupGLCanvas( "redraw" ); Atributos
BUFFER = SINGLE ou DOUBLE
COLOR = RGBA ou INDEX
Criação em LED ...
cv = GLCanvas(redraw)
Pipeline de renderização

Operações Operações
Vértices Rasterização
geométricas sobre
fragmentos

Operações Textura
Imagens
sobre imagens
Frame
Buffer
Operações sobre vértices
Transferência de dados

Atrib globais
Material
Fontes de luz
Matrizes
...

Vértices Pipeline
Transformação – Iluminação – Projeção – Clip - Mapeamento
Posição
Normal
Cor Primária
Cor Secundária
Coord. Texs...
Máquina de estado

 Trabalha com o conceito de valor corrente


 Define estado que é usado na renderização
 Do ponto de vista do programador:

Siggraph Course 37/2002


Máquina de estado
 Validação
 Assegura estado consistente
 Máquina de estado com fase de validação:

Siggraph Course 37/2002


Inicialização e Controle

 Cor de fundo e limpeza do buffer


glClearColor(red,green,blue,alpha);
glClear(GL_COLOR_BUFFER_BIT);

 Atualização é uma operação cara!


glFlush( );
glFinish( ); // modal

 Ativação de recursos
glEnable/glDisable
Especificação de primitivas

 GKS
 Antigo padrão gráfico 2D
typedef struct {
float x, y;
} Gwpoint;

gpolyline (int n, Gwpoint* p);

 Desvantagem
 Impunha uma estruturação particular
Se ED: conversão
float x[ ]
float y[ ] Gwpoint p[ ]
Especificação de primitivas

 OpenGL 1.0
glBegin(tipo_de_prim);
…define attributo de vértice
…define vértice
glEnd( );
Tipos de primitivas

1 3 4 3 2
1 1 3 5
0 2 0 4 0 1
2 2 0
GL_POINTS
GL_LINES GL_LINE_STRIP GL_LINE_LOOP

2 3
1 3 1 3 5 1
4

0 4
2 5 0 4 0
2

GL_TRIANGLES GL_TRIANGLE_STRIP GL_TRIANGLE_FAN

1 5 2
1 5 6 3
2 1 3

0
0 4 7 2 4 0
3 4
GL_QUAD_STRIP GL_POLYGON
GL_QUADS
(convexo)
Especificação de vértice

 Especificação da posição
glVertex{tam}{tipo}{vetor} (…);
Exemplo:
GLfloat pos[ ] = {0.4F,9.0F,2.0F};
glVertex3fv(pos);
ou
glVertex3f(0.4F,9.0F,2.0F);

 Considerações
 Coordenadas homogêneas
 Tipo: double x float
Especificação de atributos

 Especificação de normal

glNormal* (…);

 Vetores não unitários

glEnable/Disable (GL_NORMALIZE);
glEnable/Disable (GL_RESCALE_NORMAL); (OpenGL1.2)
Especificação de atributos

 Especificação de cor
 Modelo RGB
glColor*(...);
 Tipo char: 0 a 255
 Tipo short: 0 a 65535
 Tipos float e double: 0.0 a 1.0

 Modelo de índice
 Palheta previamente definida
glutSetColor ( index, red, green, blue );
ou
IupGLPalette ( handle, index, red, green, blue );
 Especificação do índice corrente
glIndexi(index);
Especificação de primitivas

 OpenGL 1.0
glBegin(tipo_de_prim);
…define attributo de vértice
…define vértice
glEnd( );

 Considerações
 Não impõe estruturação dos dados
 Ineficiente para primitivas complexas
 Muitas chamadas de funções
 Não permite compartilhamento de vértices
Especificação de primitivas

 OpenGL 1.1
 Propriedades de vértices em arrays do cliente
 Array de vértice (especificação da posição)

glVertexPointer ( size, type, stride, pointer )

size: 2, 3 ou 4 coordenadas
type: GL_SHORT, GL_INT, GL_FLOAT, GL_DOUBLE
stride: offset, em bytes, entre vértices consecutivos
valor zero indica posições consecutivas
pointer: ponteiro para o array
memória sob responsabilidade do cliente
Uso de arrays
 Flexibilidades para estruturação de dados
struct {
float x, y, z;
float r, g, b;
} MyVertex;
...
MyVertex p[N];
...
glVertexPointer ( 3, GL_FLOAT, sizeof(MyVertex), p );

 Exige ativação
glEnable/Disable (GL_VERTEX_ARRAY);

 API análoga para atributos


 normal, cor, coordenada de textura
Uso de arrays
 Acessando um elemento
glBegin (mode);
glArrayElement ( i ); Substitui glVertex*
... (e glNormal*, glColor*, etc.)
glEnd ( );
 Acessando um conjunto de elementos
glDrawElements (mode, count, type, indices);
count: número de elementos (vértices)
indices: vetor de índices (apenas unsigned)
 Indicando intervalo dos índices
glDrawRangeElements (mode, start, end, count, type, indices);
start, end: delimitam acesso para permitir pré-processamento
 Extensões
 NVIDIA: compiled_vertex_array
 Vertex buffer
Atributos de primitivas

 Ponto: tamanho em pixel


glPointSize (float size); // fração útil para anti-aliasing

 Linha: largura e estilo


glLineWidth (float size); // fração útil para anti-aliasing
glLineStipple (int factor, ushort pattern); // pattern de bits

 Polígono: modo, estilo e orientação


glPolygonMode (enum face, enum mode);
face: GL_FRONT, GL_BACK, GL_FRONT_AND_BACK
mode: GL_POINT, GL_LINE, GL_FILL

glPolygonStipple (ubyte* mask); // máscara de bits (32 x 32)

glFrontFace (enum mode); // GL_CCW ou GL_CW


glCullFace (enum face); // GL_FRONT ou GL_BACK
Modelo de shading

 Suave (Gouraud)
glShadeModel(GL_SMOOTH); // default
glBegin(GL_TRIANGLES);
glColor3f(1.0,0.0,0.0); // red
glVertex2f(-1.0,-1.0);
glColor3f(0.0,1.0,0.0); // green
glVertex2f(1.0,-1.0);
glColor3f(0.0,0.0,1.0); // blue
glVertex2f(0.0,1.0);
glEnd( );
Modelo de shading

 Constante
glShadeModel(GL_FLAT);
glColor3f(0.0,0.0,1.0); // blue
glBegin(GL_TRIANGLES);
glVertex2f(-1.0,-1.0);
glVertex2f(1.0,-1.0);
glVertex2f(0.0,1.0);
glEnd( );
Shading constante

 Seleção do vértice usado


1 3
1 3 5
0 4
2 0 2
GL_LINES GL_LINE_STRIP
2 3
1 3 1 3 5 1
4

0 4
2 5 0 4 0
2
GL_TRIANGLES GL_TRIANGLE_STRIP GL_TRIANGLE_FAN

1 5 2
1 5 6 3
2 1 3

0
0 4 7 2 4 0
3 4
GL_QUAD_STRIP GL_POLYGON
GL_QUADS
Shading constante

glShadeModel(GL_FLAT);
glBegin(GL_TRIANGLES);
glColor3f(1.0,0.0,0.0); // red
glVertex2f(-1.0,-1.0);
glColor3f(0.0,1.0,0.0); // green
glVertex2f(1.0,-1.0);
glColor3f(0.0,0.0,1.0); // blue
glVertex2f(0.0,1.0);
glEnd( );
Renderização de cubos

 1a opção: seqüência de QUADS


 6 x 4 = 24 vértices
void drawCube( GLfloat color[], GLfloat* vertex[] )
{
static int idx[6][4] = {{ ... },...};
glColor3fv( color );
glBegin(GL_QUADS);
for ( int i = 0; i < 6; ++i )
for ( int j = 0; j < 4; ++j )
glVertex3fv( verts[idx[i][j]] );
glEnd( );
}
Renderização de cubos

 2a opção: QUAD strip


 4 (topo) + 4 (base) + 8 (strip) = 16 vértices
Renderização de cubos

 3a opção: TRIANGLE strip


 14 vértices
Renderização de cubos

 Teste comparativo

 Gforce 2
 1600 cubos em movimento, com iluminação

 QUADS: ~32 fps

 QUAD_STRIP: ~35 fps

 TRIANGLE_STRIP: ~47 fps


Renderização de cubos

 Cubos estáticos

 Sugestões?
Renderização de cubos
 Cubos estáticos
 4a opção: seqüência de QUADS
void drawCube( GLfloat color[], GLfloat* vertex[] )
{
static int idx[6][4] = {{ ... },...};
glColor3fv( color );
for ( int i = 0; i < 6; ++i )
for ( int j = 0; j < 4; ++j )
glVertex3fv( verts[idx[i][j]] );
}

 glBegin/End no laço externo


glBegin( GL_QUADS );
for ( int i = 0; i < numCubes; ++i )
drawCube( color[i], vertex[8*i] );
glEnd();
Renderização de cubos

 Teste comparativo com cubos estáticos

 Resultados normalizados
SIGGRAPH 2002, Course # 37, Performance OpenGL: Platform Independent Techniques

Estratégia Máquina A Máquina B Máquina C

QUADS 3.99 4.36 2.23

QUAD_STRIP 3.99 4.50 2.15

QUAD sem 1.00 1.00 1.00


Begin/End
Exemplo real

 Visualizador de reservatórios
 Reservatório composto por células
 QUAD_STRIP: 1.49
 TRIANGLE_STRIP: 1.32
 QUAD sem B/E: 1.00
Transformações

 Sistema global fixo


 Ordem inversa para especificação
Y Y Y

X X X

...
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(30,0,0,1);
glTranslatef(10,0,0);
...
Transformações

• Sistema local móvel


–Ordem natural para especificação
Y Y Y y
x
y
x

X X X


glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(30,0,0,1);
glTranslatef(10,0,0);
...
Pilha de matrizes

glMatrixMode(GL_MODELVIEW);
glLoadIdentity( );
glPushMatrix( ); // duplica topo
glRotate(30,0,0,1);
glTranslate(10,0,0);
draw_object_1( );
glPopMatrix( ); // restaura estado
...

API para matrix genérica: representação coluna a coluna


glLoadMatrixf (float m[16]);
glMultMatrix (float m[16]);
Tutor Transform
Posicionamento do mundo em
relação à câmera
 Função auxiliar

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(eye_x, eye_y, eye_z,
center_x, center_y, center_z,
up_x, up_y, up_z
);
...
Projeção perspectiva

 Perspectiva
teta w

h
near
far

aspect = w / h
glMatrixMode(GL_PROJECTION);
glLoadIdentity( );
gluPerspective (teta_y,aspect,znear,zfar);
...

Ou:
glFrustum (xmineye, xmaxeye, ymineye, ymaxeye, znear, zfar);
Projeção ortográfica
• Ortográfica

near
far

glMatrixMode(GL_PROJECTION);
glLoadIdentity( );
glOrtho (xleft,xright,ybottom,ytop,znear,zfar);
...

2D:
gluOrtho2D (xleft,xright,ybottom,ytop); Tutor Projection
Mapeamento

 Viewport
glViewport (x, y, width, height);
GLUT & IUP:
• A função default de “resize” define a viewport
como sendo a área total do canvas.

 Z-buffer
glDepthRange(znear, zfar); // default: 0, 1
Tratamento de visibilidade

 Z-BUFFER
 Requisita buffer (GLUT ou IUP)
 Habilita teste em Z
glEnable (GL_DEPTH_TEST);
 Define teste
glDepthFunc (GL_LESS); // default
 Limpa buffer
glClear (GL_DEPTH_BUFFER_BIT);
Animação

 Double color buffer: BACK & FRONT


 Inicialização
 GLUT
glutInitDisplayMode (GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB);
 IUP/C
cv = IupGLCanvas (“redraw”);
IupSetAttribute (cv, IUP_BUFFER, IUP_DOUBLE);
 IUP/LED
cv = GLCanvas [BUFFER=DOUBLE] (redraw)
 Atualização da tela
 GLUT
glutSwapBuffer( );
 IUP
IupGLSwapBuffers (cv);
Iluminação

 Cor do objeto depende de:


 Orientação da superfície
 Posição do observador
 Fonte de luz
 Material
 Componentes
 ambiente
Modelo de iluminação: Phong
 difusa
 especular
Fontes de luz
 Tipos Direcional Pontual Spot

Glfloat pos[ ] = {x,y,z,w};


glLightf (GL_LIGHT0, GL_POSITION, pos);

 Cor e intensidade
 ambiente, difusa, especular
Glfloat dif[ ] = {red,green,blue,alpha};
glLightf (GL_LIGHT0, GL_DIFFUSE, dif);

 Ativação
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
Variação do desempenho
com o número de fontes de luz

Quatro diferentes máquinas com fontes de luz local (pontual)


(SIGGRAPH 2002, Course # 37, Performance OpenGL: Platform Independent Techniques)
Luz direcional apresenta variação semelhante
Parâmetros globais de iluminação

 Luz ambiente global


GLfloat amb[ ] = {0.2,0.2,0.2,1.0};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb);

 Posição do observador: local ou infinito


glLightModeli (GL_LIGHT_MODEL_VIEWER, GL_TRUE);

 Iluminação de faces: back e front


glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);

 Iluminação especular em separado


glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,
GL_SEPARATE_SPECULAR_COLOR)
Tutor Lighting
Material

 Cor (reflexividade)
 Ambiente
 Difusa
 Especular
 Brilho (shininess)
 Emissão

Glfloat color [ ] = { red, green, blue, alpha };


glMaterialf (GL_BACK_AND_FRONT,
GL_AMBIENT_AND_DIFFUSE,
color);

Tutor material
Cor como material

 Usando cor para definição de material

glColorMaterial (GL_BACK_AND_FRONT,
GL_AMBIENT_AND_DIFFUSE);

glEnable (GL_COLOR_MATERIAL);


glColor3f (red, green, blue);
...
Pilha de grupos de atributos

 Permite restaurar atributos eficientemente


 Pilha de atributos (no servidor)
glPushAttrib ( GL_FOG_BIT | GL_LIGHTING_BIT | etc );
glPopAttrib ( );

 Pilha de atributos do cliente


glPushClientAttrib ( GL_CLIENT_PIXEL_STORE |
GL_CLIENTE_VERTEX_ARRAY_BIT );
glPopClientAttrib ( );
Trabalho 1: “sistema solar”

 Sol e um planeta Rotação


diária
Raio

Rotação
anual
Sol: desenhado na origem
Planeta: pensando em sistema local
• Rotação anual
• Translação em x
• Rotação diária

Você também pode gostar