Elementi di Grafica Digitale
standard grafici
primitive grafiche
grafica raster,
parte software:
librerie standardizzate:
GKS (Graphical Kernel System)
(primo standard ISO e ANSI)
GKS 3D
PHIGS (Programmer's Hierarchical
Interactive Graphics Standard
Open GL (Open Silicon Graphics Graphical Library)
Open GL 2 (vedi rete,
http://www.sgi.com/products/software/opengl/
...
DirectX (proprietario MS)
(ad es. http://www.deakin.edu.au/~agoodman/scc308/index.html ,
corso di COMPUTER GRAPHICS ... )
Core :
The Core Graphics System.
Created in the late 1970s by the ACM SIGGRAPH Graphics
Standards Planning Committee.
Designed to provide a standard set of library routines, based on
(then) current device-independent graphics practice (largely
vector terminals attached to mainframes, with off-line
processing),
it was overtaken (replaced) by the more comprehensive GKS
and (later) PHIGS, as well as by developments in raster display
systems, and the development of real-time processing on
graphics workstations.
Its significance includes the fact that many of its principles were
later adopted by both GKS and PHIGS.
http://www.deakin.edu.au/~agoodman/scc308/topic3.html
GKS: The Graphical Kernel System.
Originally devised by a combined British and German group,
GKS became the first graphics system to be fully standardised
by ANSI and ISO in 1984.
Originally a two-dimensional system, it has been extended to
three dimensions;
directly, as GKS3D, and indirectly, through PHIGS.
Still vector-based, although with much greater emphasis on
interactivity.
It introduced the idea of a 'virtual workstation' as a way of
encouraging and enforcing device-independence.
PHIGS
The Programmers Hierarchical Interactive Graphics System.
Fundamentally a development from both CORE and GKS,
with powerful 3D functionality,
reflecting the development in the late 1980s of powerful
workstations capable of real time display of complex 3D objects.
It also supports direct data structure creation and manipulation.
Greater direct support for raster operations was added with
PHIGS+ in 1986.
http://www.deakin.edu.au/~agoodman/scc308/topic3.html
negli anni 80 furono studiate diverse alternative per il
problema della scrittura di software adatto alla
progettazione e realizzazione di disegni / immagini di
vario tipo (dal disegno tecnico per meccanici al
disegno a mano libera per artisti):
soluzione gia' presente e che alla fine ha prevalso:
librerie grafiche da usare come libreria accessibile
da un linguaggio di programmazione standard (ad
es. dal Fortran)
la soluzione piu' elegante dei linguaggi grafici - con i
linguaggi standard piu' diffusi al tempo estesi alla
grafica, ad es. il Graphic Pascal, con operatori e tipi
grafici predefiniti - non ha avuto successo
con l'introduzione dei object-oriented languages e'
rimasta la prima soluzione: linguaggio
standard+libreria
Ogni libreria grafica prevede un collegamento con
diversi linguaggi,
“Language Binding",
cosi' il GKS - libreria grafica - aveva un'interfaccia
per il Fortran, una per il Pascal, una per il C ecc;
cosi' PHIGS,
e cosi' Open GL
ad es. con la libreria PHIGS,
per tracciare una spezzata di n punti e n-1 segmenti
in Fortran si scrivera': CALL GPL(n, Xtab, Ytab )
in Pascal si scrivera': polyline(n,xtab,ytab);
in C :
gpolyline(n, points);
dove points e' un array di punti, che sono a loro volta
delle struct di coordinate (x,y) oppure (x,y,z)
oppure (x,y,z,a) ecc (vedremo)
Introduzione alla Grafica Digitale
primitive
grafiche:
*
oggetti e
attributi grafici
elementari
(predefiniti)
disponibili al
programmatore
es.:
punto, linea, ...
Introduzione alla Grafica Digitale
primitive
grafiche:
*
oggetti e
attributi grafici
elementari
(predefiniti)
disponibili al
programmatore
es.:
punto, linea, ...
*
descrizione del
"mondo"
utente,
spazio di
coordinate del
problema dove si
costruisce
l'immagine
es.: limiti per x,y,z
Introduzione alla Grafica Digitale
primitive
grafiche:
*
oggetti e
attributi grafici
elementari
(predefiniti)
disponibili al
programmatore
es.:
punto, linea, ...
*
descrizione del
"mondo"
utente,
spazio di
coordinate del
problema dove si
costruisce
l'immagine
es.: limiti per x,y,z
*
descrizione dell' HW
che produce
l'immagine, per
quanto interessa la
visualizzazione
dell'immagine su
schermo e l' interazione con l' utente
del programma,
es.:finestra schermo
Introduzione alla Grafica Digitale
primitive
grafiche:
punto
segmento
triangolo
rettangolo
poligono
cerchio
ellisse
bitmap
carattere
attributi:
posizione,
orientamento,
forma, colore,
trasparenza,..
descrizione del
mondo utente o
spazio problema
dove e' costruita
l'immagine, quindi
limiti delle
coordinate,
specifica del
passaggio dalle
coordinate "mondo
alle coordinate
schermo ...
descrizione
dell'HW dove
si produce
l'immagine
caratteristiche
dello schermo,
della finestra
sullo schermo,
dei colori
disponibili,
dispositivi di
interazione
ecc
si noti che
per tracciare un'immagine sullo schermo e
per memorizzare e/o trasmettere un'immagine
devo utilizzare un insieme di primitive grafiche,
devo specificare lo spazio del problema e le
caratteristiche dello schermo e della finestra o parte
dello schermo usata ("Work-station" o "Window")
e anche il formato del "display file" o "meta-file"
ad es. in PHIGS per costruire un'immagine si fara' :
openPhigs( errFile, memSize)
openWorkstation(ws, connection,type,...)
... create and display the picture ...
closeWorkstation(ws)
closePhigs
La libreria Open GL e' stata inizialmente definita solo per
la parte delle primitive e delle operazioni disponibili,
e sono le due librerie di base, la gl e la glu,
mentre la parte "apri finestra" specifica dispositivo grafico
ecc era legata al Sistema Operativo in uso, ed era (ed
e') diversa da Unix, Windows, Apple OS 9, ecc;
in seguito fu aggiunta
una libreria di "interfaccia standard" per le funzioni di piu'
usate e piu' semplici legate al sistema operativo,
e' la libreria gl-utility library, o
glut, che rende un programma sorgente eseguibile su
sistemi operativi diversi (windows, unix, apple os)
per inizializzare una finestra di lavoro in OpenGL con la libr.
glut si avra' la sequenza di comandi:
glutInit(&argc, argv); (vedremo)
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowPosition( dove_sta_x0, dove_sta_y0 );
glutInitWindowSize( X_SIZE_width, Y_SIZE_height );
glutCreateWindow( " TITOLO " );
...
glut NON appartiene alla parte centrale di OpenGL, ma alla
libreria estesa glut - gl utility toolkit, NOTA: il Borland Builder usa la VCL (visual class lib), cosi'
MS Win NT.. usa una sua libreria (vedi NeHe.gamedev.com)
(anche la specifica del formato di un file grafico non
appartiene a OpenGL) - ma per Win NT.. esiste la versione
glut adattata per MS win (vedi http://www.opengl.com )
openGL e' disponibile su molte piattaforme (Unix,
Windows, Apple OS9, Apple OSX... su Windows
piu' versioni,
compresa quella che usa la libreria pubblica glut;
su rete si trova una gran quantita' di materiale !
http://nehe.gamedev.net/ (NEHE Jeff Molofee
univ.Hull,York,UK)
---------------------------------------------------------
windows + glut version: original (#include
<windows.h>) runs on Win NT etc; When creating
your project, uncheck OWL, uncheck Class Library,
select Static instead of Dynamic and change the
target model to Console from GUI. Also link
glut.lib to your project once its done.
-----------------------------------------------------------------------
nota: la libreria glut e' disponibile in sorgente
su rete, dalla stessa organizzazione dell'OpenGL
-----------------------------------------------------------------------
Racano (corso EGD05) segnala gl e glut per Borland 5.5,
richiesto: Borland C++5.5, OpenGL runtime sw della MS, e GLUT
da rete: scaricare OpenGL95.exe (unzip), copiare opengl32.dll in
\windows\system\ (o winnt\system32\), copiare GL.H, GLU.H,
GLAUX.H in <borland\include\gl\ (creare il dirett. gl), poi creare
da .dll le .lib di: opengl32.dll, glu32.dll, glut32.gll, glut.dll,
winmm.dll (con implib della Borland: implib <libname>.lib
<libname>.dll e poi copiare le lib in \borland\libs\
-----------------------------------------------------------------------
ricorda: manuale OpenGL "libro rosso"
istruzioni per l'installazione di OpenGL su Windows:
Istruzioni per l'installazione delle librerie
OpenGL in VS 2008:
nota: PVS sta per
C:\Program Files\Microsoft Visual Studio 9.0
scaricare da rete quanto richiesto sotto;
- copiare freeglut.h in: 'PVS\VC\include\GL\'
- copiare freeglut_ext.h in: 'PVS\VC\include\GL\'
- copiare freeglut_std.h in: 'PVS\VC\include\GL\'
- copiare freeglut.lib in: 'PVS\VC\lib\'
- copiare freeglut.dll in: 'C:\WINDOWS\system32\'
- copiare glut32.dll in: 'C:\WINDOWS\system32\'
- copiare glut32.lib in: 'PVS\VC\lib\'
- copiare glut.h in: 'PVS\VC\include\GL\'
1. Create a new C++ Console project in VS.
1a. In the Create Application Wizard, select Empty
Project.
2. Add a new cpp file to the empty project. Add a
bit of template code in there. For example:
#include
int main () { return 0; }
3. If you try to compile, VS will fail to compile. This
is because it can't see the freeglut header files.
3a. On the menu bar, go to Project -> Properties
(Alt+F7).
3b. Go to Linker -> Input
and copy and paste this line.
opengl32.lib glu32.lib glut32.lib
4. If you try to compile now, errors may still show
up. You'll probably need to add directories for
your header and lib files in Project/Solutions
directories.
5. The program should now compile.
le librerie OpenGL funzionano su
piattaforme diverse, ma hanno bisogno
di include diverse,
per cui si usa la include condizionale:
#if defined __APPLE__
#include ... sara' attivo se il sistema su cui sto
compilando e' Apple OS
#else // not apple : win or unix
#include ... ... sara' attivo se il sistema su cui sto
compilando non e' Apple OS, e quindi e'
Windows oppure Unix ...
#endif // which o.s.
// schema per include che va ok per Apple e Win
#if defined __APPLE__
#include <GLUT/glut.h> /* APPLE OSX Xcode */
typedef char BYTE;
#else // not apple : win or unix
/* #define WIN32_LEAN_AND_MEAN */
/* evita inclusione di tutti i package ms */
#include <windows.h> /* TOGLI SE UNIX */
/* following is common to win and unix */
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <GL/glaux.h>
#endif // which o.s.
/* #include <GL/glext.h> // extensions */
vi sono anche altri punti di diversita'
tra Apple OSX e Windows,
(che sono emersi durante il corso EGD)
ad es.
random(n) su Win, random()%n su Apple
e altri,
come M_PI definito nella math.h in Apple OSX
ma che richiede un
#define _USE_MATH_DEFINES
// NECESSARIO in WinMS se uso M_PI, M_PI_4
...
interfaccia "multi uso" per esempi su Apple OSX e su Windows:
/* file include.h 29/3/05 GL includes
//----------------------------------------#if defined __APPLE__
#include <GLUT/glut.h> /* includes GL/gl.h */
// #include <GL/glext.h> /* extensions ... */
#else
// avoid inclusion of all (or too much) MS stuff:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
/* and now include */
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
// #include <GL/glext.h> /* extensions ... */
#include <wingdi.h>
#endif
//----------------------------------------// nota: la libreria glut e' disponibile in sorgente
// su rete, dalla stessa organizzazione dell'OpenGL,
#ifndef myINCLUDE_H /* A.Zupan 4 mar 06 */
#define myINCLUDE_H
#if defined WIN32 /*Win98,NT,XP MS VS C++ */
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#elif defined __APPLE__ /*APPLEOSX Xcode */
#include <GLUT/glut.h>
#else
/* Linux code */
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <string.h>
#include <stdlib.h>
#endif
#include <GL/glext.h> /*seguono altri includ*/
un programma in C o C++ che usa penGL deve specificare
l'ambiente in cui si disegna - quindi una finestra grafica;
al minimo:
... includes (abbiamo visto)
... prototipi
void faDisplay( void );
/*chiamare quando il gestore eventi decide di disegnare */
void myInit();
/*inizializzazioni (una tantum) per il mio programma OGL*/
void OpenWindow( int argc, char* argv[] );
/* inizializzazione della finestra */
void myGlReshape (int wi, int he);
int main (int argc, char * argv[]) {
un programma in C o C++ che usa penGL deve specificare
l'ambiente in cui si disegna - quindi una finestra grafica;
al minimo:
... includes
... prototipi
int main (int argc, char * argv[]) {
OpenWindow( argc, argv );
glutDisplayFunc(faDisplay); /* NB: parametro e' una proc: */
/* avverti GLUT chi chiamare quando si disegna */
/* in faDisplay c'e' quanto necessario per fare il disegno */
glutReshapeFunc(myGlReshape);
myInit(); /* tutte le cose da fare una volta
glutMainLoop(); /* il programma va in letargo ...
sara' OGL a attivare le procedure in risposta agli eventi
previsti nel main prima di passare al mainloop */
return 0; /*non sara'mai eseguito */
}
/* main */
void OpenWindow( int argc, char* argv[] ){
GLint dimx, dimy;
do{ printf("dimens.x y? "); scanf("%d%d", &dimx, &dimy );
} while (dimx<100||dimx>800||dimy<100||dimy>600);
glutInit(&argc, argv); /* inizializza GLUT */
/* **** chiamata per prima ***** */
glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE );
/* modalita' RGB 8 bit/color (24 bit)+AlfaChannel */
glutInitWindowPosition(60, 20);
/* posizione angolo sopra a sinist su schermo
zero zero = angolo in alto a sinistra ... */
glutInitWindowSize(dimx, dimy);
/*dimensione della finestra, in pixel */
glutCreateWindow("OGL1A_2RIGHE"); /* crea la finestra;
non disegnata, finche' non si chiama glutMainLoop */
/*e questo e' la trafila standard per creare una finestra...*/
} /* OpenWindowPlease */
void myInit() {
glViewport( 0,0, /* punto in basso a sinistra */
glutGet(GLUT_WINDOW_WIDTH), /* in alto a destra */
glutGet(GLUT_WINDOW_HEIGHT) );
glMatrixMode( GL_PROJECTION);
/* 4x4 projection matrix for openGL hw */
glLoadIdentity(); /* si parte da una matrice unitaria */
gluOrtho2D( 0,glutGet(GLUT_WINDOW_WIDTH),
/* left right clipping planes */
0, glutGet(GLUT_WINDOW_HEIGHT) );
/* bottom and top clipping planes */
} /* MyGLInit */
void myGlReshape (int wi, int he) {
/*sara' chiamata su evento reshape (cambia forma
finestra) wi,he nuove dimensioni della finestra */
myInit();
glutPostRedisplay();
} // myGlReshape ()
Introduzione alla Grafica Digitale
riprendiamo le
primitive grafiche:
punto
segmento
triangolo
rettangolo
poligono
cerchio
ellisse
bitmap
carattere
e gli attributi delle
primitive grafiche,
come:
posizione,
orientamento,
forma,
colore
per disegnare un punto specifico
posizione coordinate x,y
colore
componenti RGB
dimensione: larghezza (==altezza)
il frammento seguente di programma
disegna due punti (nota suffissi 2f e 3f !)
glPointSize( 4.4 );
glBegin( GL_POINTS ); // NOTA INIZIO
glColor3f( 0.3, 0.3, 1.0 ); // blu
glVertex2f( width/2.0, height/2.0 );
glColor3f( 1.0, 0.0, 0.0 ); // rosso
glVertex2f( width*0.45, height*0.45 );
glEnd();
// E FINE DI SEQUENZA
Introduzione alla Grafica Digitale
procedimento standard OpenGL per disegnare piu' punti:
struct Tpunto{ float x; float y; };
...
glColor3f( colR, colG, colB );
glPointSize(10.0);
glBegin(GL_POINTS); //
<<<<<<<<<<<<
glVertex2f( Punto1.x, Punto1.y);
glVertex2f( Punto2.x, Punto2.y);
glVertex2f( Punto3.x, Punto3.y);
glVertex2f( Punto4.x, Punto4.y);
glEnd();
qui vengono disegnati quattro punti
...
tracciare o disegnare un pixel in OpenGL:
approccio standard: con la funzione glVertexABC, con A,B,C che
possono essere ... es:
int P1[]={50,110};
// un punto dato come vettore
struct TP{float x; float y;} P2={0.5, 0.5}; //pto come struct
glBegin(GL_POINTS);
glVertex2i( 50, 100 );
glVertex2iv( P1 ); // nota sufisso 2iv - vector di 2 elem.
glVertex3f( 7.2, 10.3, 100.0 ); // suffisso 3f
glVertex2f( P2.x, P2.y ); // suffisso 2f
glEnd();
// si noti le varianti della glVertex, a seconda del tipo e
// del numero dei parametri (Open GL non e' C++, ma C!)
// glFunz4f(4 parametri float) glFunz3i(tre parametri int)
Introduzione alla Grafica Digitale
Passaggio da primitiva matematica (geometrica) punto, linea
a primitiva grafica su schermo raster: pixel, linea di pixel
un punto ha dimensione zero, spessore zero, area zero
in un rettangolo astratto ("finestra" nel piano {x,y} ) vi
sono infiniti punti !
un pixel ha dimensione fissa non nulla (pixel pitch),
sullo schermo c'e' un insieme ben delimitato di punti
(ad es. 1600x1024)
linea: l'oggetto matematico linea (dimensione 1) ha
spessore zero, area zero;
linea: l'oggetto grafico e' una stringa di pixel con area, spessore,
VEDIAMO ORA COME SI
TRACCIA UNA LINEA SU SCHERMO
void myDisplay() { //due linee: una verde in basso, blu digonale
// myw,myh=limiti spazio utente, width,height = larghez,altez
// prima una LINEA SOTTILE VERDE in basso
glColor3f( 0.0, 1.0, 0.0 );//red,green,blue
glLineWidth(2.0);
a=0.02*myw; b=0.02*myh; c=0.98*myw; d=0.02*myh;
glBegin(GL_LINES); // NB: (0,0) sta in basso a sinistra
glVertex2f( a,b ); // coordinate punto sinistra,basso,
glVertex2f( c,d ); // coordinate punto destra, basso,
glEnd();
// poi una LINEA GROSSA BLU DIAGONALE
glColor3f( 0.0, 0.0, 1.0 );
glLineWidth(8.0);
x1=0.04*myw; y1=0.96*myh; x2=0.96*myw; y2=0.04*myh;
glBegin(GL_LINES);
glVertex2f(x1,y1); // punto a sinistra in alto
glVertex2f(x2,y2); // punto a destra in basso
glEnd();
// Open GL, disegna due linee:
// myw, myh = width,height spazio utente,
// LINEA SOTTILE VERDE in basso
glColor3f( 0.0, 1.0, 0.0 );//red,green,blue
glLineWidth(2.0);
a= 0.02*myw; b=0.02*myh; // sinistra,alto
c= 0.98*myw; d=0.02*myh; // destra, basso,
// QUI (0,0) sta in basso a sinistra! possibili
// entrambe le posizioni
glBegin(GL_LINES);
glVertex2f( a,b );
glVertex2f( c,d );
glEnd();
// LINEA GROSSA BLU DIAGONALE
glColor3f( 0.0, 0.0, 1.0 );
glLineWidth(8.0);
x1=0.04*myw; y1=0.96*myh;
x2=0.96*myw; y2=0.04*myh; glBegin(GL_LINES);
glVertex2f(x1,y1);//sin,alto
glVertex2f(x2,y2);//des,basso
glEnd();
0=GL_POINTS, separate points P[0],P[1],..P[k]
abbiamo visto due esempi di uso di punti e di linee:
glPointSize( 4.4 );
glBegin( GL_POINTS ); // NOTA procedura INIZIO diseg
glColor3f( 0.3, 0.3, 1.0 ); // blu
glVertex2f( width/2.0, height/2.0 );
glColor3f( 1.0, 0.0, 0.0 ); // rosso
glVertex2f( width*0.45, height*0.45 );
glEnd(); // procedura FINE DI SEQUENZA
1=GL_LINES, points pairs= separate line segments
a= 0.02*mywidth; b=0.02*myheight; // sinistra,alto
c= 0.98*mywidth; d=0.02*myheight; // destra, basso,
glColor3f( 0.0, 1.0, 0.0 ); //red,green,blue
glLineWidth(2.5);
glBegin( GL_LINES ); // procedura INIZIO disegna
glVertex2f( a,b );
glVertex2f( c,d );
glEnd();
// procedura FINE DI SEQUENZA
primitive grafiche:
ogni immagine e' costruita utilizzando elementi di base, detti
primitive grafiche: l'Open GL definisce 10 primitive grafiche
da usare come parametro di glBegin( param ); ... glEnd();
0=GL_POINTS, separate points P[0],P[1],..P[k]
1=GL_LINES, points pairs=separate line segments
2=GL_LINE_LOOP,closed line P[0],P[1]..P[n],P[0]
3=GL_LINE_STRIP, open line P[0],P[1]..P[n]
4=GL_TRIANGLES, each vert. triplet = triangle
non ripetiamo i due esempi visti di uso di punti e di linee,
dopo la tabella seguente sono dati 10 es di uso;
primitive grafiche: Open GL
5=GL_TRIANGLE_STRIP, odd and even vert.
define a triangolarized polygon 6
6=GL_TRIANGLE_FAN, vertex V[0] is common
to triangles V[0]-(V[k]-V[k+1])
7=GL_QUADS, each quadruple V[k]-V[k+3]=quadril.
8=GL_QUAD_STRIP, V[0]..V[n] = polygon mesh of
quadrilaterals, odd=one side,even the other
9=GL_POLYGON V[0]..V[n] a closed polygon
dopo la tabella (pagina seguente) sono dati 10 esempi di uso:
Tutte le primitive:
0=GL_POINTS, separate points P[0],P[1],..P[k]
1=GL_LINES, points pairs=separate line segments
2=GL_LINE_LOOP,closed line P[0],P[1]..P[n],P[0]
3=GL_LINE_STRIP, open line P[0],P[1]..P[n]
4=GL_TRIANGLES, each vertex triplet = triangle
5=GL_TRIANGLE_STRIP, odd and even vertex
define a triangolarized polygon
6=GL_TRIANGLE_FAN, vertex V[0] is common
to all triangles V[0]-(V[k]-V[k+1])
7=GL_QUADS, each quadruple V[k]-V[k+3]=quadril.
8=GL_QUAD_STRIP, V[0]..V[n] = polygon mesh of
quadrilaterals, odd=one side,even the other
9=GL_POLYGON V[0]..V[n] a closed polygon
vediamo ora altri esempi
0) figura di 6 punti ottenuta con la sequenza:
// xx2, yy2 sono le dimensioni della finestra !!
P1[0]= xx2*0.1; P1[1]= yy2*0.5;
P2[0]= xx2*0.30; P2[1]= yy2*0.2;
P3[0]= xx2*0.70; P3[1]= yy2*0.2;
P4[0]= xx2*0.9; P4[1]= yy2*0.5;
P5[0]= xx2*0.70; P5[1]= yy2*0.8;
P6[0]= xx2*0.30; P6[1]= yy2*0.8;
glColor4f(0.7, 0.7, 0.2 , 1.0 );
glLineWidth(4.0);
glPointSize(6.0);
primitiva zero - POINTS
glBegin( GL_POINTS );
// GL_POINTS = 0 = primitiva 0
glVertex2fv( P1 );
glVertex2fv( P2 );
glVertex2fv( P3 );
glVertex2fv( P4 );
glVertex2fv( P5 );
glVertex2fv( P6 );
glEnd();
Nota per tutte le figure "PRIMITIVE": e' aggiunta una
GL_LINE_STRIP che unisce i punti, e anche su
alcuni sono aggiunte le etichette dei punti P1..P6
es zero: punti singoli
la spezzata solo per
mostrare la sequenza
1) figura di segmenti di retta, ottenuta con:
// GL_LINES each couple Vk,Vk+1 define a line
P1[0]= xx2*0.1; P1[1]= yy2*0.5;
P2[0]= xx2*0.30; P2[1]= yy2*0.2;
P3[0]= xx2*0.70; P3[1]= yy2*0.2;
P4[0]= xx2*0.9; P4[1]= yy2*0.5;
P5[0]= xx2*0.70; P5[1]= yy2*0.8;
P6[0]= xx2*0.30; P6[1]= yy2*0.8;
glColor4f(0.7, 0.7, 0.2 , 1.0 );
glLineWidth(4.0);
glPointSize(6.0);
glBegin( GL_LINES );// primitiva 1
// disegna un segmento di linea
// per ogni coppia di punti
glVertex2fv( P1 ); // 1 a sinis,basso
glVertex2fv( P2 );
glVertex2fv( P3 ); // 2 a dest,basso
glVertex2fv( P4 );
glVertex2fv( P5 ); // 3 in alto
glVertex2fv( P6 );
glEnd();
nota che su tutti gli es. e' aggiunta
la GL_LINE_STRIP in rosso,
e (su alcuni) le etichette dei punti
es 1 : linee separate
2) figura di una spezzata chiusa,
ottenuta con la sequenza:
P1[0]= xx2*0.1; P1[1]= yy2*0.5;
P2[0]= xx2*0.30; P2[1]= yy2*0.2;
P3[0]= xx2*0.70; P3[1]= yy2*0.2;
P4[0]= xx2*0.9; P4[1]= yy2*0.5;
P5[0]= xx2*0.70; P5[1]= yy2*0.8;
P6[0]= xx2*0.30; P6[1]= yy2*0.8;
glColor4f(0.7, 0.7, 0.2 , 1.0 );
glLineWidth(4.0);
glPointSize(6.0);
glBegin( GL_LINE_LOOP ); // == 2
glVertex2fv( P1 );
glVertex2fv( P2 );
glVertex2fv( P3 );
glVertex2fv( P4 );
glVertex2fv( P5 );
glVertex2fv( P6 );
glEnd();
es. OGL2A_PRIMITIVE)
nota che su tutti gli es. e' aggiunta la
GL_LINE_STRIP in rosso,
es 2 : linea spezzata chiusa
3) figura di una spezzata aperta,
ottenuta con la sequenza:
primitiva 3 LINE_STRIP
P1[0]= xx2*0.1; P1[1]= yy2*0.5;
P2[0]= xx2*0.30; P2[1]= yy2*0.2;
P3[0]= xx2*0.70; P3[1]= yy2*0.2;
P4[0]= xx2*0.9; P4[1]= yy2*0.5;
P5[0]= xx2*0.70; P5[1]= yy2*0.8;
P6[0]= xx2*0.30; P6[1]= yy2*0.8;
glColor4f(0.7, 0.7, 0.2 , 1.0 );
glLineWidth(4.0);
glPointSize(6.0);
glBegin( GL_LINE_STRIP );
// primitiva == 3
glVertex2fv( P1 );
glVertex2fv( P2 );
glVertex2fv( P3 );
glVertex2fv( P4 );
glVertex2fv( P5 );
glVertex2fv( P6 );
glEnd();
es. OGL2A_PRIMITIVE; nota che anche qui
e'aggiunta la linea spezzata rossa e i nomi dei
punti
es 3: linea spezzata aperta
4) figura con due triangoli ottenuta con :
PRIMITIVA 4 = TRIANGLES
P1[0]= xx2*0.1; P1[1]= yy2*0.5;
P2[0]= xx2*0.30; P2[1]= yy2*0.2;
P3[0]= xx2*0.70; P3[1]= yy2*0.2;
P4[0]= xx2*0.9; P4[1]= yy2*0.5;
P5[0]= xx2*0.70; P5[1]= yy2*0.8;
P6[0]= xx2*0.30; P6[1]= yy2*0.8;
glColor4f(0.7, 0.7, 0.2 , 1.0 );
glLineWidth(4.0);
glPointSize(6.0);
glBegin( GL_TRIANGLES );
// primitiva 4
glVertex2fv( P1 );
glVertex2fv( P2 );
glVertex2fv( P3 );
glVertex2fv( P4 );
glVertex2fv( P5 );
glVertex2fv( P6 );
glEnd();
OGNI TERNA DI PUNTI DEFINISCE UN TRIANGL.
(nota che su tutti gli es. sono aggiunti la
GL_LINE_STRIP in rosso, e qui anche i
nomi dei punti)
es 4: triangoli separati
un poligono = superficie con contorno dato da un poligono
puo' essere pensata come formata da un mosaico di triangoli,
5) figura di poligono pieno fatto con
triangoli, ottenuta con la sequenza:
PRIMITIVA 5 = TRIANGLE STRIP
P1[0]= xx2*0.1; P1[1]= yy2*0.5;
P2[0]= xx2*0.30; P2[1]= yy2*0.2;
P3[0]= xx2*0.70; P3[1]= yy2*0.2;
P4[0]= xx2*0.9; P4[1]= yy2*0.5;
P5[0]= xx2*0.70; P5[1]= yy2*0.8;
P6[0]= xx2*0.30; P6[1]= yy2*0.8;
glColor4f(0.7, 0.7, 0.2 , 1.0 );
glLineWidth(4.0);
glPointSize(6.0);
glBegin( GL_TRIANGLE_STRIP );
// primitiva == 5
glVertex2fv( P1 );
glVertex2fv( P2 );
glVertex2fv( P6 );
glVertex2fv( P3 );
glVertex2fv( P5 );
glVertex2fv( P4 );
glEnd();
NB:i vertici dei triangoli sono
alternati (pari da una parte, dispari
dall'altra)
es 5: poligono di
triangoli pieni uniti notare l'ordine dei punti !
6) figura a poligono pieno di triangoli,
ottenuta con la sequenza:
PRIMITIVA 6 = TRIANGLE FAN
P1[0]= xx2*0.1; P1[1]= yy2*0.5;
P2[0]= xx2*0.30; P2[1]= yy2*0.2;
P3[0]= xx2*0.70; P3[1]= yy2*0.2;
P4[0]= xx2*0.9; P4[1]= yy2*0.5;
P5[0]= xx2*0.70; P5[1]= yy2*0.8;
P6[0]= xx2*0.30; P6[1]= yy2*0.8;
glColor4f(0.7, 0.7, 0.2 , 1.0 );
glLineWidth(4.0);
glPointSize(6.0);
glBegin( GL_TRIANGLE_FAN );
// primitiva == 6
glVertex2fv( P1 );
glVertex2fv( P2 );
glVertex2fv( P3 );
glVertex2fv( P4 );
glVertex2fv( P5 );
glVertex2fv( P6 );
glEnd();
i triangoli hanno tutti un vertice
in comune !(ricorda: FAN=ventaglio)
es 6: poligono di
triangoli pieni uniti
a ventaglio
7) figura di quadrilateri,
ottenuta con la sequenza:
Q1[0]= xx2*0.1; Q1[1]= yy2*0.7;
Q2[0]= xx2*0.1; Q2[1]= yy2*0.3;
Q3[0]= xx2*0.3; Q3[1]= yy2*0.3;
Q4[0]= xx2*0.3; Q4[1]= yy2*0.7;
Q5[0]= xx2*0.6; Q5[1]= yy2*0.8;
Q6[0]= xx2*0.6; Q6[1]= yy2*0.2;
Q7[0]= xx2*0.9; Q7[1]= yy2*0.2;
Q8[0]= xx2*0.9; Q8[1]= yy2*0.8;
...
glBegin( GL_QUAD ); // == 7
glVertex2fv( Q1 ); // uno
glVertex2fv( Q2 ); // uno
glVertex2fv( Q3 ); // uno
glVertex2fv( Q4 ); // uno
glVertex2fv( Q5 ); // due
glVertex2fv( Q6 ); // due
glVertex2fv( Q7 ); // due
glVertex2fv( Q8 ); // due
glEnd();
// ogni 4 punti definiscono
// un quadrilatero
primitiva 7 rettangoli
es 7: rettangoli pieni non uniti
notare l' ordine dei punti
8) figura di quadrilateri contigui,
ottenuta con la sequenza:
...
P1[0]= xx2*0.1; P1[1]= yy2*0.7;
P2[0]= xx2*0.1; P2[1]= yy2*0.3;
P3[0]= xx2*0.3; P3[1]= yy2*0.3;
P4[0]= xx2*0.3; P4[1]= yy2*0.7;
P5[0]= xx2*0.6; P5[1]= yy2*0.8;
P6[0]= xx2*0.6; P6[1]= yy2*0.2;
P7[0]= xx2*0.9; P7[1]= yy2*0.2;
P8[0]= xx2*0.9; P8[1]= yy2*0.8;
...
glBegin( GL_QUAD_STRIP );
glVertex2fv( P1 );//disp sinist
glVertex2fv( P2 );// pari dest
glVertex2fv( P4 );//disp sinist
glVertex2fv( P3 );// pari dest
glVertex2fv( P5 );//disp sinist
glVertex2fv( P6 );// pari dest
glVertex2fv( P8 );//disp sinist
glVertex2fv( P7 );// pari dest
glEnd();
//NOTA l'ordine della squenza!
NOTA: i vertici dei quadrilateri sono alternati (i
vertici pari da una parte, i dispari dall'altra)
primitiva 8 QUAD STRIP
es. 8: poligono fatto da
striscia di quadrilateri
uniti tra loro (ogni quadr.
e' fatto da due triangoli)
9) ultima primitiva, il poligono pieno :
figura ottenuta con la sequenza:
primitiva 9 poligono pieno
P1[0]= xx2*0.1; P1[1]= yy2*0.5;
P2[0]= xx2*0.30; P2[1]= yy2*0.2;
P3[0]= xx2*0.70; P3[1]= yy2*0.2;
P4[0]= xx2*0.9; P4[1]= yy2*0.5;
P5[0]= xx2*0.70; P5[1]= yy2*0.8;
P6[0]= xx2*0.30; P6[1]= yy2*0.8;
glColor4f(0.7, 0.7, 0.2 , 1.0 );
glLineWidth(4.0);
glPointSize(6.0);
glBegin( GL_POLYGON );
// == 9
glVertex2fv( P1 );
glVertex2fv( P2 );
glVertex2fv( P3 );
glVertex2fv( P4 );
glVertex2fv( P5 );
glVertex2fv( P6 );
glEnd();
primitiva 9 = un poligono chiuso, pieno (non
solo il contorno)
es. 9: poligono pieno definito
dalla linea spezzata chiusa
(e' fatto con triangoli)
MA ATTENZIONE - nota:
l'open GL disegna correttamente poligoni
convessi, mentre un poligono concavo
non viene disegnato correttamente:
il frammento di programma seguente produce
la fig a fianco:
glBegin( GL_POLYGON );
aglVertex2f(xx2*0.2, yy2*0.2);
bglVertex2f(xx2*0.5, yy2*0.75);
cglVertex2f(xx2*0.8, yy2*0.2);
dglVertex2f(xx2*0.8, yy2*0.8);
eglVertex2f(xx2*0.2, yy2*0.8);
glEnd();
glLineWidth(2.5);
glColor4f( 0.8, 0.8, 0.1 , 1.0 );
glBegin( GL_LINE_STRIP );
glVertex2f(xx2*0.2, yy2*0.2);
glVertex2f(xx2*0.5, yy2*0.75);
glVertex2f(xx2*0.8, yy2*0.2);
glVertex2f(xx2*0.8, yy2*0.8);
glVertex2f(xx2*0.2, yy2*0.8);
glEnd();
primitiva 9 poligono pieno
a
c
b
e
d
Attenzione: l'OpenGL non
disegna sempre correttamente un poligono
concavo (con rientranze)
ancora un poligono concavo, ma
con un ordine diverso di disegno:
glBegin( GL_POLYGON );
aglVertex2f(xx2*0.2, yy2*0.2);
bglVertex2f(xx2*0.8, yy2*0.2);
cglVertex2f(xx2*0.8, yy2*0.8);
dglVertex2f(xx2*0.5, yy2*0.25);
eglVertex2f(xx2*0.2, yy2*0.8);
glEnd();
..
glColor4f(0.8,0.8,0.1,1.0);
glBegin( GL_LINE_STRIP );
glVertex2f(xx2*0.2, yy2*0.2);
glVertex2f(xx2*0.8, yy2*0.2);
glVertex2f(xx2*0.8, yy2*0.8);
glVertex2f(xx2*0.5, yy2*0.25);
glVertex2f(xx2*0.2, yy2*0.8);
glEnd();
a
b
d
e
c
==>> i poligoni pieni sono sempre triangolarizzati, ma per un poligono
concavo e' meglio che lo faccia l'utente!
l' OpenGL
oltre le dieci primitive grafiche viste
offre alcune altre primitive grafiche :
BitMap = porzioni dello schermo = insiemi di pixel,
Introduzione alla Grafica Digitale
tra le primitive grafiche in Open Gl
vi sono ancora
elementi di immagine
definiti come porzioni dello schermo,
sono insiemi di pixel, o BitMap,
usati ad es. per copiare caratteri (di tipo
bitmap) sull'immagine grafica
procedura glBitMap(...)
procedura glDrawPixels(...)
e altre;
la figura a destra e' data da :
...
glWindowPos3i( x1+dd, y1+dd, 0 );
// position without transformation by
// modelview or projection and without clipping
glutBitmapCharacter(
GLUT_BITMAP_TIMES_ROMAN_24,
(char)('A'+co+ri) );
...
e
...
glColor4f( 1.0, 1.0, 1.0, 1.0 ); //MUSt call before
glRasterPos glRasterPos3i( 100, 100, 0 );
glutBitmapCharacter(
GLUT_BITMAP_TIMES_ROMAN_24, '@' );
...
(es. OGL8_STRING)
l'area dove disegno, il "foglio di disegno"
non coincide
con lo schermo
Introduzione alla Grafica Digitale
Posizionare un punto:
lo schermo corrisponde alla memoria grafica, ma (come noto) si
ricorda che la dimensione massima dell'immagine
non necessariamente e' uguale
alla dimensione massima del reticolo di pixel che lo schermo
schermo
riesce a mostrare
posso avere un'immagine piu' piccola che viene mostrata in una
finestra (parte) dello schermo,
come posso avere un'immagine piu' grande che viene mostrata
solo in parte sullo schermo (oppure intera, ma opportunamente
rimpiccolita o scalata)
schermo
vedremo negli esempi concreti ...
la memoria grafica o frame buffer
corrisponde al raster dell'immagine finale,
e quindi ogni pixel dell'immagine finale ha
una posizione in memoria data dalle sue
coordinate schermo
gli esempi seguenti
saranno ripresi in seguito,
qui solo per dire che vi
sono molte primitive ...
GLubyte bitShape[20] = { 0x1C,0x00, 0x1c, ... };
// store a bit pattern in 8-bit blocks, 10 rows, 16 bit per row
glPixelStorei(GL_UNPACK_ALIGNEMENT,1);
// set pixel storage mode
glRasterPos2i(30,40);
// raster position in world coordinates !!
glBitmap( 16, 10, 0.0, 0.0, 20.0, 15.0, bitShape);
// width,height, x0, y0, x0offset, y0offset
altre funzioni:
glDrawPixels(width,height,dataFormat,dataType,pixMap);
eg:
glDrawPixels(128,128,
GL_RGB, GL_UINSIGNED_BYTE, colorShape);
...
riprenderemo ...
cenno:
un bitmap (un reticolo binario) puo' essere definito con apposite
procedure, a cui per ora solo accenniamo:
glBitmap( width, height, x0, y0, x0offset, y0offset, bitShapeArray);
dove il bitShapeArray e' una tabella di bit compressi, come ad es:
GLubyte bitShapeArray[20]={0x1c,0x00,0x1c,..0xff,..0x00};
si deve dare la posizione prima della copia del bit-map, con lal proc
glRasterPos*(x,y); dove *(..) sono gli stessi che si possono usare con
glVertex*(..)
glDrawPixels(width,height,dataFormat,dataType, pixMapArr)
copia un array di pixel su schermo, ad es:
glDrawPixels(128,128, GL_RGB, GL_UNSIGNED_BYTE, MyColShap);
..
glReadPixels(...) per estrarre un array di pixel da un buffer,
glCopyPixels(...) per copiare una zona del buffer in un'altra..
fine parte
primitive OpenGL standard
EGD11_stnd_prmtv.ppt
Scarica

EGD11_STND_PRMTV