OpenGL Parte I: Geometria Waldemar Celes Departamento de Informática Tecgraf/PUC-Rio
API OpenGL: : o que é? Interface para programador de aplicação Aplicação API Hardware & Software API abstrata Dispositivo de saída Dispositivo 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 Vértices Operações geométricas Rasterização Operações sobre fragmentos Imagens Operações sobre imagens Textura 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 Sistema de Interface (GLUT) OpenGL GLU Hardware
Programa simples (usando( GLUT) #ifdef _WIN32 #include <windows.h> #endif #include "GL/gl.h" #include "GL/glu.h #include GL/glut.h int main (int argc, char* argv[]) { /* open GLUT */ glutinit(&argc, argv); glutinitdisplaymode (GLUT_SINGLE GLUT_RGB); 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) { glviewport(0,0,w,h); glclearcolor(1,1,1,1); } void display (void) { /* clear window */ 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" #include "iupgl.h" #ifdef _WIN32 #include <windows.h> #endif #include "GL/gl.h" #include "GL/glu.h" int main (void) { Ihandle *dg, *cv; /* open GUI */ IupOpen(); IupGLCanvasOpen(); /* create canvas and dialog */ 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 #include iupgl.h Inicialização IupOpen(); IupGLCanvasOpen(); Criação em C cv = IupGLCanvas( "redraw" ); Criação em LED cv = GLCanvas(redraw) Bibliotecas: IUP iup.lib & iupgl.lib OpenGL opengl.lib & glu.lib (SGI) opengl32.lib & glu32.lib (MS) Atributos BUFFER = SINGLE ou DOUBLE COLOR = RGBA ou INDEX...
Pipeline de renderização Vértices Operações geométricas Rasterização Operações sobre fragmentos Imagens Operações sobre imagens Textura Frame Buffer
Operações sobre vértices Transferência de dados Atrib globais Material Fontes de luz Matrizes... Vértices Posição Normal Cor Primária Cor Secundária Coord. Texs... Pipeline Transformação Iluminação Projeção Clip - Mapeamento
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
Validação Máquina de estado 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
GKS Especificação de primitivas 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 0 2 GL_POINTS 0 1 3 5 2 GL_LINES 4 1 3 0 2 GL_LINE_STRIP 4 3 0 1 GL_LINE_LOOP 2 2 3 1 3 4 1 3 5 1 0 2 5 GL_TRIANGLES 0 4 2 GL_TRIANGLE_STRIP 0 GL_TRIANGLE_FAN 4 1 2 5 6 1 3 5 1 2 3 0 3 4 7 GL_QUADS 0 2 4 GL_QUAD_STRIP 0 4 GL_POLYGON (convexo)
Especificação de vértice Especificação da posição glvertex{tam}{tipo}{vetor} ( ); Exemplo: ou GLfloat pos[ ] = {0.4F,9.0F,2.0F}; glvertex3fv(pos); 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 Considerações glbegin(tipo_de_prim); define attributo de vértice define vértice glend( ); 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 );... 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 Substitui glvertex* (e glnormal*, glcolor*, etc.)
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 5 1 3 0 2 GL_LINES 4 0 2 GL_LINE_STRIP 2 3 1 3 4 1 3 5 1 0 2 5 GL_TRIANGLES 0 4 2 GL_TRIANGLE_STRIP 0 GL_TRIANGLE_FAN 4 1 2 5 6 1 3 5 1 2 3 0 3 4 7 GL_QUADS 0 2 4 GL_QUAD_STRIP 0 4 GL_POLYGON
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 1 a 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 2 a opção: QUAD strip 4 (topo) + 4 (base) + 8 (strip) = 16 vértices
Renderização de cubos 3 a 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 4 a 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 Begin/End 1.00 1.00 1.00
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... glmatrixmode(gl_modelview); glloadidentity(); glrotatef(30,0,0,1); gltranslatef(10,0,0);... X X
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 near far glmatrixmode(gl_projection); glloadidentity( ); gluperspective (teta_y,aspect,znear,zfar);... h aspect = w / h Ou: glfrustum (xmin eye, xmax eye, ymin eye, ymax eye, znear, zfar);
Ortográfica Projeção ortográfica near glmatrixmode(gl_projection); glloadidentity( ); glortho (xleft,xright,ybottom,ytop,znear,zfar);... far 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 difusa especular Modelo de iluminação: Phong
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 Raio Rotação diária Sol: desenhado na origem Planeta: pensando em sistema local Rotação anual Translação em x Rotação diária Rotação anual