Computer Graphics Immagine sul Raster Display Il RASTER è costituito da più SCAN LINES Ogni Scan Line è formata da più PIXEL La matrice di Pixel è memorizzata nel FRAME BUFFER Un unico frame buffer porterebbe a vedere l immagine comporsi durante la sua realizzazione - Se ne usano almeno due (double buffering): primario, per l immagine dello schermo, secondario, che prepara la nuova. Quando questa è pronta, i buffer si scambiano i ruoli (page flipping)
Grafica 3D Grafica 3D: analogia con fotocamera Posta in un punto dello spazio (VIEWPOINT) Realizza un immagine bidimensionale (FRAME) dell ambiente 3D (SCENE) Passi per un corretto scatto Specifica del tipo di proiezione (Ortografica o Prospettica) e dei parametri di vista: coordinate del modello (object coordinates, in un obj) posizione dell osservatore e del viewplane Clipping: specifica del VIEW VOLUME Proiezione sul VIEW PLANE e Visualizzazione sul VIEWPORT
Grafica 3D Rendere finito il View Volume Introduzione di NEAR e FAR Plane
Perspective Transformation Per procedere al clipping possiamo ricorrere alla perspective transformation o normalization, che trasforma il viewfrustum nel Volume di Vista Canonico (CVV) top left top left right - right 1-1 bottom bottom adapted from F. Pfenning
Grafica 3D Analogia con camera Collocare camera e modello nello spazio Impostare il campo visivo (lente) La catena di trasformazioni La pipeline grafica
La pipeline di rendering Modello semplificato DATI 3D PIXEL TRASFORMAZIONE Operazioni geometriche: si determinano le coordinate dei pixel ILLUMINAZIONE Operazioni cromatiche: si determina il colore dei pixel RASTERIZZAZIONE Operazioni bidimensionali: si elaborano i singoli pixel
OpenGL OpenGL (Open Graphics Library) è una collezione di API multilinguaggio e multipiattaforme per applicazioni orientate alla computer grafica 2D e 3D. OpenGL permette di: astrarre l interfaccia con hardware grafici differenti, offrendo al programmatore una API unica ed uniforme; astrarre le capacità offerte dai diversi acceleratori 3D, richiedendo che tutte le implementazioni supportino completamente l'insieme di funzioni OpenGL, ricorrendo ad un'emulazione software se necessario. Il compito di OpenGL è quello di ricevere primitive come punti, linee e poligoni, e di convertirle in pixel. OpenGL è una macchina a stati, e mantiene una serie di strutture (stack di matrici, buffer di valori, etc.) per memorizzare le variabili che ne identificano lo stato
La pipeline di rendering Modello più realistico (GeForce 3) interpolazione
La pipeline di rendering opengl reale
L evoluzione di OpenGL Nelle sue prime versioni OpenGL consentiva di usare solo l immediate mode, una modalità basata sull esecuzione immediata dei comandi Per quanto garantisca il massimo della flessibilità (es. geometrie variabili) le performance sono rallentate dal continuo trasferimento dati per l esecuzione dei comandi (primitive) opengl Il retained mode consente invece di raggruppare comandi che vengono eseguiti tutti in un colpo, al fine di minimizzare il trasferimento dei dati Le display list, ad es., consentono di conservare una serie di comandi in memoria grafica. PRO: utilissime per comandi ripetitivi (es. disegno di una mesh rigida), risparmio di banda e di performance CONTRO: se la geometria cambia vanno ricreate (pericolo di thrashing), grosso utilizzo di memoria grafica
La pipeline di rendering Specifica dei dati di input Definizione di un vertice : glvertex () I vertici devono essere definiti dentro un blocco associato ad una determinata primitiva (mode) geometrica : void glbegin (Glenum mode)...def di vertici (e normali) void glend (void) Possibili primitive : GL_POINTS (punti) GL_LINES, GL_LINE_STRIP, _LOOP (linee) GL_TRIANGLES, GL_TRIANGLE_STRIP, _FAN (triangoli) GL_QUADS, GL_QUAD_STRIP, GL_POLYGON (quadrati e poligoni) STRIP : Sfruttano il concetto di adiacenza. Associazione di un colore ad un vertice : glcolor () Modalità di colorazione : glpolygonmode (Glenum face, Glenum mode) GL_POINT, il poligono sarà disegnato con dei punti GL_LINE, il poligono sarà disegnato in modalità Wireframe GL_FILL, il poligono sarà disegnato in modalità Solid Associazione di una normale : glnormal ()
La pipeline di rendering Es. Specifica di un triangolo glpolygonmode (GL_FRONT, GL_FILL); glpolygonmode (GL_BACK, GL_LINE); glbegin (GL_TRIANGLES); glnormal (0.0,0.0,1.0); glcolor (1.0,1.0,0.0); glvertex (0.0,0.0,0.0); glvertex (1.0,0.0,0.0); glvertex (0.0,1.0,0.0); glend (); z y GL_FRONT x y GL_BACK z x
La pipeline di rendering Specifica di un triangolo con Display List // creation GLuint index = glgenlists (1); // compile the display list glnewlist (index, GL_COMPILE); glpolygonmode (GL_FRONT, GL_FILL); glpolygonmode (GL_BACK, GL_LINE); glbegin (GL_TRIANGLES); glnormal (0.0,0.0,1.0); glcolor (1.0,1.0,0.0); glvertex (0.0,0.0,0.0); glvertex (1.0,0.0,0.0); glvertex (0.0,1.0,0.0); glend (); glendlist (); // drawing glcalllist (index); Dopo la creazione, basta chiamare: glcalllist (index); N.B. L esecuzione di una display list causa l esecuzione di TUTTI i comandi,che però sono già presenti in memoria grafica
L evoluzione di OpenGL Una maniera di economizzare le chiamate OpenGL per la specifica dei dati geometrici è usare i Vertex Array // creation GLfloat vertices[] = {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}; GLubyte indices[] = {0, 1, 2}; // activate and specify pointer to vertex array glenableclientstate (GL_VERTEX_ARRAY); glvertexpointer (3, GL_FLOAT, 0, vertices); // drawing gldrawelements (GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, indices); I Vertex Buffer Objects, uniscono i vantaggi di entrambi gli approcci: i dati vengono conservati nella memoria grafica (come per la display list) vengono usate le chiamate dei Vertex Array (dunque vengono eseguiti meno comandi) I VBO possono essere aggiornati! (le Dlist vanno ricreate)
L evoluzione di OpenGL Vertex Buffer Objects GLfloat vertices[] = {0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.0}; GLubyte indices[] = {0, 1, 2}; GLuint vboid1, vboid2; // generate a new VBO and get the associated ID glgenbuffers(1, &vboid1); glgenbuffers(1, &vboid2); // bind VBO in order to use glbindbuffer(gl_array_buffer, vboid1); glbindbuffer(gl_element_array_buffer, vboid2); // upload data to VBO glbufferdata(gl_array_buffer, bytedatasize, vertices, GL_STATIC_DRAW); glbufferdata(gl_element_array_buffer, datasize, indices, GL_STATIC_DRAW); glenableclientstate(gl_vertex_array); // activate vertex coords array glvertexpointer(3, GL_FLOAT, 0, 0); // last 0 is the offset in the bound VBO gldrawelements(gl_quads, 24, GL_UNSIGNED_BYTE, 0); // idem
L evoluzione di OpenGL Nelle prime versioni di OpenGL (fino alla 1.5) l intera pipeline era completamente STATICA (ovvero usava funzioni e modalità predefinite) Da OpenGL 2.0 (2004) in poi, gli stadi della pipeline POSSONO essere personalizzati attraverso particolari programmi detti SHADERS Da OpenGL 3.0 (2008) in poi, la pipeline statica viene DEPRECATA. Questo vuol dire che gli stadi della pipeline DEVONO essere programmati tramite shaders. Esiste tuttavia un compatibility mode che consente ancora l utilizzo delle funzionalità statiche. Per finalità didattiche esamineremo ora il funzionamento della pipeline STATICA, torneremo successivamente sulla pipeline programmabile
Stadio di Trasformazione TRASFORMATION Mesh e primitive Le coordinate omogenee Trasformazioni di Modelviewing Trasformazioni di Proiezione (dal volume di vista al cubo unitario) Trasformazioni di Viewport
Stadio di Trasformazione Concetto di Matrice Corrente che identifica una delle tre matrici relative alle trasformazioni (GL_MODELVIEW, GL_PROJECTION, GL_TEXTURE): glmatrixmode () Altre funzioni generalmente riferite alle operazioni su queste matrici: glmultmatrix () glloadmatrix () glloadidentity () glpushmatrix () glpopmatrix () Viewing Trasformation: glulookat () Modeling Trasformation : Traslazione : gltranslate () Scalatura : glscale () Rotazione: glrotate ()
Stadio di Trasformazione Projection Trasformation. Prospettica : glfrustum (left, right, bottom,top, near, far); gluperspective (fovy, aspect, near, far) (cambia la modalità di definizione del volume di vista) Ortografica : glortho (left, right, bottom, top, near, far ) Viewport Trasformation. glviewport (x, y, width, height)
Stadio di Illuminazione LIGHTING Modello di PHONG Diffuse, Specular, Ambient Sorgenti luminose e materiali Per ogni primitiva deve essere specificato un materiale, i cui parametri possono essere applicati uniformemente alla superficie della primitiva, o modulati da una tessitura (texture).
Stadio di Illuminazione In OpenGL possono esistere fino a 8 sorgenti di luci. Le loro proprietà si specificano con: gllight (Glenum light, Glenum pname, TYPE param) Componenti: GL_AMBIENT, componente ambientale GL_DIFFUSE, componente diffusa GL_SPECULAR, componente speculare Fattori di Attenuazione : GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION, GL_QUADRATIC_ATTENUATION GL_POSITION, con cui è possibile impostare la posizione o creare una luce direzionale (posizionata all infinito) SpotLight: una luce posizionale per default emana luce in tutte le direzioni. E possibile però restringere la sua produzione di luce con un cono di illuminazione GL_SPOT_CUTOFF, angolo del cono ([0.0, 90.0]) GL_SPOT_EXPONENT, focalizzazione della luce GL_SPOT_DIRECTION, direzione della luce Per abilitare una luce : glenable (light) Per abilitare l illuminazione : glenable (GL_LIGHTING ).
Stadio di Illuminazione Impostazione dei Materiali: glmaterial (face, pname, param) GL_AMBIENT, componente ambientale GL_DIFFUSE, componente diffusa GL_SPECULAR, componente speculare GL_EMISSIVE, componente emissiva Modalità di Shading : glshademodel (mode) mode può assumere i valori : - GL_FLAT (per avere una modalità Flat) - GL_SMOOTH (per avere una modalità Gouraud).
Stadio di Clipping etc. Clipping: glclipplane (GL_CLIP_PLANEi, equation) Specifica piani addizionali di clipping. Back Face Culling: glcullface (mode) GL_FRONT, GL_BACK Specifica la modalità di taglio dei poligoni a seconda del loro orientamento
Stadio di Rasterizzazione RASTERIZZAZIONE Texture mapping: Texture: matrice di texel contenenti dati relativi al colore L immagine 2D viene mappata sulle primitive del modello 3D La texture condivide con le primitive tutte le trasformazioni su di esse compiute + = Z-buffering Alpha Blending
Stadio di Rasterizzazione Le fasi per creare un oggetto Texture sono le seguenti : Fase 1: Creazione di un nome univoco di Texture. glgentextures (NumNomi, * texturenames) Fase 2: Creazione un oggetto Texture e associzione ( bind ) di un nome glbindtextures (GL_TEXTURE_2D, texturename) Fase 3: Associazione di una immagine all oggetto Texture. glteximage2d ( ) Fase 4: Impostazione dell ambiente texture GL_ADD gltexenv (GL_TEXTURE_ENV, GL_TEXTURE_ENV _MODE, param). Fase 5: Impostazione dei Filtri di Texture (magnification, minification) gltexparameter (GL_TEXTURE_2D, tipofiltro, valore) Impostazione della modalità (param) di uso del colore di Texture. ColoreSuperficieFinale = GL_REPLACE GL_MODULATE -> Tex -> Tex x ColSup. -> Tex + ColSup Le fasi di utilizzo di un oggetto Texture sono : Fase 1. Attivazione del Texture Mapping glenable (GL_TEXTURE_2D) Fase 2. Associare le coordinate di texture ad un vertice attraverso il comando : gltexcoord (u,v)
Altre funzioni OpenGL BUFFER Depth: gldepthmask gldepthfunc glpolygonoffset glblendfunc Color: glclearcolor glcolormask gldrawbuffer General: glclear Stencil: glstencilfunc glstencilop glstencilmask glscissor DATA STORING/RETRIEVAL General: glgetfloatv glgetstring Attributes: glpopattrib glpushattrib Transformation: gluproject gluunproject Frame buffer: glcopytexsubimage2d glcopyteximage2d glreadpixels DISPLAY LIST glnewlist glgenlists glcalllist glendlist