1 Programmazione grafica 1 Daniele Marini
2 Linguaggio di riferimento OpenGL: libreria di procedure che realizza un API (application programmers interface) –Standard de facto –Disponibile su windows, mac, IRIX, Solaris –Linux dispone di librerie free Mesa - subset di OpenGL –La struttura semantica è simile a quella di altre librerie: GKS, Direct3D, Java3D
3 Disegnare al tratto - Line drawing Il plotter a penna moveto (x,y) lineto (x,y)
4 Disegno al tratto Tracciare linee definite in uno spazio cartesiano piano Modalità molto diffusa ma con limiti: come lavorare in 3D? Come gestire strutture geometriche più evolute?
5 Disegno al tratto Possiamo pensare un disegno piano come la proiezione di un disegno tridimensionale Oppure come un disegno definito nello spazio 3d ma con punti su un medesimo piano di equazione z=0
6 Disegno al tratto I punti saranno allora vettori, o vertici: p(x,y,z) o, nel piano, p(x,y,0) Possiamo definire una primitiva grafica glVertex* dove * assume il valore: ntv con n ={2,3 o 4} dimensione dello spazio t = {i,d o f} integer, double o float v se presente e un puntatore a un array di valori
7 Primitive grafiche glVertex #define Glint integer glVertex2i(Glint xi, Glint yi) Definisce un punto di coordinate intere in uno spazio 2D #define Glfloat float glVertex3i(Glfloat x, Glfloat y, Glfloat z) Definisce un punto di coordinate float in uno spazio 3D Glfloat vertex[3] glVertex3fv(vertex) Definisce un punto le cui coordinate float, in uno spazio 3D, sono registrate nellarray vertex
8 Primitive grafiche glVertex –Possiamo raggruppare punti per costruire strutture più complesse: glBegin(GL_LINES); definisce un segmento glVertex2f(x1,y1); glVertex2f(x2,y2); glEnd(); glBegin(GL_POINTS); definisce una coppia di punti glVertex2f(x1,y1); glVertex2f(x2,y2); glEnd();
9 Triangolo di Sierpinsky Il programma seguente traccia un triangolo di Sierpinsky per punti
10 void draw_sierpinsky( void ) { /* define a point data type */ typedef GLfloat point2[2]; point2 vertices[3]={{0.0,0.0},{250.0,500.0},{500.0,0.0}}; /* i vertici di un triangolo */ int i, j, k; int rand(); /* standard random number generator */ point2 p ={75.0,50.0}; /* An arbitrary initial point inside triangle */ glClear(GL_COLOR_BUFFER_BIT); /*clear the window */ 1/2
11 /* compute and plots 5000 new points */ for( k=0; k<5000; k++) { j=rand()%3; /* pick a vertex at random */ /* Calcola il punto mdio tra il vertice scelto e il vecchio punto */ p[0] = (p[0]+vertices[j][0])/2.0; p[1] = (p[1]+vertices[j][1])/2.0; /* traccia il nuovo punto */ glBegin(GL_POINTS); glVertex2fv(p); glEnd(); } glFlush(); /* clear buffers */ } 2/2
12 Le coordinate schermo La figura precedente è definita in uno spazio cartesiano indipendente dal dispositivo di visualizzazione (display, carta, …) In passato il disegno veniva descritto direttamente in coordinate del dispositivo La conversione tra coordinate mondo - world co- ordinates e coordinate dispositivo - device co- ordinates si chiama trasformazione window-to-viewport
Spazio mondo / Spazio schermo
14 Coordinate mondo WC world co-ordinates Coordinate schermo SC screen co-ordinates window viewport Window in WC: (x min, y min ), (x max,y max ) Viewport in WC: (u min,v min ), (u max,v max ) (x min, y min ) (x max,y max ) (u min,v min ) (u max,v max )
15 Traslazione: (-x min,-y min ) Scala: Traslazione inversa : (u min,v min )
16 Caratteristiche di OpenGL (e di qualunque sistema grafico) maschera le funzioni device dependent È strutturata in primitive, attributi, funzioni di visualizzazione, funzioni di trasformazione funzioni di input, funzioni di controllo User program Graphics system API I/O devices Function calloutput input data
17 Interfaccia di OpenGL I nomi di funzione iniziano con gl È composta di più librerie: –GL libreria principale –GLU graphics utility library - contiene funzioni per definire primitive grafiche di uso frequente (sfere, e altri oggetti comuni) –GLUT GL utility toolkit - interfaccia con il sistema di windowing (windows, mac, X-Window,..)
18 Fa uso di macro per evitare costanti magiche (abbiamo visto GL_POINTS,..) Le librerie sono incluse nel codice: #include oppure #include Le primitive base sono specificate con punti (vertici): glBEGIN(type); glVertex*(…); … glVertex*(…); glEnd();
19 I tipi principali sono: GL_POINTS GL_LINES GL_LINE_STRIP GL_LINE_LOOP p1 p2 p3 p4p5 p1 p2 p3 p4p5 p1 p2 p3 p4p5 p1 p2 p3 p4p5 segmenti
20 Poligoni Hanno diversi aspetti Possono essere semplici e intrecciati Convessi o non convessi
21 Poligoni in OpenGL GL_POLYGON simili a GL_LINE_LOOP, hanno un interno e un esterno, sono fillati sulla base degli attributi associati, il bordo non ha spessore, non tratta poligoni intrecciati; gli attributi sono assegnati con glPolygonMode GL_TRIANGLES, GL_QUADS casi speciali di poligoni, sequenze di punti sono interpretate come vertici di triangoli o quadrilateri GL_TRIANGLE_STRIP, GL_QUAD_STRIP, GL_TRIANGLE_FAN triangoli o quadrilater con vertici in comune: si possono risparmiare coordinate!
22 GL_TRIANGLE_STRIPGL_QUAD_STRIP GL_TRIANGLE_FAN p0 p2 p4 p6 p1 p3 p5 p7 p0 p2 p4 p6 p1 p3 p5 p7
23 I tipi di dati numerici SuffixData Type Typical Corresponding OpenGL Type Definition C-Language Type b 8 bit integer signed char GLbyte s 16 bit integer short GLshort i 32 bit integer long GLint, GLsizei f 32 bit floating point float GLfloat, GLclampf d 64 bit floating point double GLdouble, GLclampd ub 8 bit unsigned integer unsigned char GLubyte, GLboolean us 16 bit unsigned integer unsigned short GLushort ui 32 bit unsigned integer unsigned long GLuint, GLenum, GLbitfield
24 Il testo Caratterizzato dalla fonte character font Testo stroke - o al tratto, definito con vertici e linee Testo raster - definito con rettangoli di pixel on/off, chiamati bit blocks, per massima efficienza sono implementate operazioni speciali sul frame buffer, bitblt (bit-block-transfer) OpenGL non ha funzioni per il testo, GLUT ha un set minimale di caratteri bitmap e stroke: glutBitmapCharacter(GLUT_BITMAP_8_BY_13, c)
25 Attributi di linee e poligoni Si distingue tra il tipo di primitiva e il modo in cui deve essere visualizzata Si adotta una nozione di binding degli attributi, permanente o temporaneo In Immediate mode gli attributi sono passati direttamente al sottosistema di output senza venir memorizzati Tipici attributi sono: dotted, dashed, solid per linee; bold, italic,.. per caratteri
26 Colore Il colore è descritto in OpenGL nello spazio RGB glColor3f(1.0, 0.0, 0.0) rosso pieno glClearColor3f(1.0, 0.0, 0.0) definito in RGBAlfa glutSetColor(int color, GLfloat red, Glfloat blue, Glfloat green) inizializza una LUT
27 Visualizzare (viewing) Visualizzare in 2D: window to viewport mapping, clipping Visualizzare in 3D: proiezioni e camera model –Clipping 3D Proiezioni ortografiche void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far) void glOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top) equivale a far=1.0 near=-1.0
28 Funzioni di controllo Interazione con la window: lorigine è in basso a sinistra; la window va inizializzata: glutInit(int *argcp, char **argv) glutCreateWindow(char *title) glutInitDisplayMode(GLUT_RGB|GLUT_DEPTH|GLUT_DOUBLE) glutWindowSize(480,640) glutInitWindowPosition(0,0) Rispettare i rapporti nella viewport (aspect ratio) void glViewport(GLint x, GLint y, Glsizei w, Glsizei h)
29 Mettere tutto assieme Main, draw_sierpinsky e myinit: void glutMainLoop(void) esegue un loop di processamento di eventi se non ci sono eventi resta in loop, termina quando riceve un segnale di kill void glutDisplayFunc(void (*func)(void)) la grafica viene spedita al display, func è il nome della funzione che veine chiamata quando il sistema di windowing rileva che OpenGL richiede di venire rinfrescato; questo accada almeno la prima volta; se mettiamo il nostro codice dentro func, essa viene eseguita una volta (non ce interazione) e il disegno apparirà sullo schermo.
30 main void main(int argc, char** argv) { /* Standard GLUT initialization */ glutInit(&argc,argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); /* default, not needed */ glutInitWindowSize(500,500); /* 500 x 500 pixel window */ glutInitWindowPosition(0,0); /* place window top left on display */ glutCreateWindow("Sierpinski Gasket"); /* window title */ glutDisplayFunc(draw_sierpinsky); /* display callback invoked when window opened */ myinit(); /* set attributes */ glutMainLoop(); /* enter event loop */ }
31 myinit #include void myinit(void) { /* attributes */ glClearColor(1.0, 1.0, 1.0, 1.0); /* white background */ glColor3f(1.0, 0.0, 0.0); /* draw in red */ /* set up viewing */ /* 500 x 500 window with origin lower left */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, 500.0, 0.0, 500.0); glMatrixMode(GL_MODELVIEW); }
32 Altre caratteristiche di OGL È una macchina a stati, es. il colore corrente è uno stato Gli stati sono normalmente abilitati con glEnable() glDisable() Gli stati si possono interrogare, es: glGetBooleanv(), glGetDoublev(), glGetFloatv(), or glGetIntegerv() Alcune variabili hanno comandi di interrogazione specifici, es: glGetLight*(), glGetError(), or glGetPolygonStipple())
33 Altre caratteristiche di OGL Gli stati si possono salvare e recuperare in uno stack ( appendice B OGL Book, directory OGL_doc ), es: glPushAttrib(), glPopAttrib()