1
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 0 / 1 1 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
• Open Graphic Language
• Libreria C – Cross platform
– Qualche centinaio di routines
• www.opengl.org – specifiche
Specifiche ver 4.1
(da luglio 2010)
(noi useremo sostanzialmente 2.0)M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 0 / 1 1 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
• inizialmente sviluppato da Silicon Graphics
• dal 2002 al 2006:
OpenGL A AA A rchitecture R R R R eview BB B B oard – mantiene e aggiorna le specifiche – industria 90%, accademia 10%
– ogni compagnia / gruppo, un voto
• dal 2006: Khronos Gruop
– come sopra
• ci sono anche le estensioni private – Soprattutto e
Storia
etc...
etc... etc...
etc...
: derivazioni
• OpenGL ES
– per device embedded – cur version: 2.0
•
– per web – javascript!
– HTML5
– soluz emergente per 3D sul Web
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 0 / 1 1 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 0 / 1 1 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
alternative
• Direct3D Direct3D Direct3D Direct3D
– Parte di DirectX
• Microsoft – (proprietario, e non cross platform)
– Stessi scopi di OpenGL
• un API per usare lo stesso hardware
• struttura non dissimile
– di solito, meno elegante, più macchinoso
• C (e C++)
– E’ l'alternativa più comune a OpenGL
• Grossomodo:
– Direct3D = industry standard – OpenGL = academy standard (ma la distinzione è molto sfumata)
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 0 / 1 1 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
sintassi
• Tutte le funzioni di Opengl si chiamano:
glSomeThing[xxx]
– “camel-case”
– dove xxx specifica numero e tipo dei parametri:
f: float i: intero s: short (2 bytes)
d: double b: byte
u*: unsigned [*] *v: vettore di [*] (puntatore)
– esempio:
glColor3f(float, float, float);
glColor3fv( float*);
– Perche? E' ANSI-C, non C++…
• no overloading di funzioni!
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 0 / 1 1 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
sintassi
• Tutte le costanti (macro) di Opengl:
GL_SOME_THING
- upper case (underscores per separare le parole)
2
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 0 / 1 1 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
sinassi
• Esempio:
glColor3b glColor3d glColor3f glColor3i glColor3s glColor3ub glColor3ui glColor3us glColor4b glColor4d glColor4f glColor4i glColor4s glColor4ub glColor4ui glColor4us glColor3bv glColor3dv glColor3fv glColor3iv glColor3sv glColor3ubv glColor3uiv glColor3usv glColor4bv glColor4dv glColor4fv glColor4iv glColor4sv glColor4ubv glColor4uiv glColor4usv
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 0 / 1 1 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
librerie amiche GLU GLU
GLU GLU (GL utilites)
– insieme di funzioni di utility costruite sopra OpenGL,
(può far comodo)
– esempio: void gluLookAt(eyex,eyey,eyez, cx,cy,cz, upx, upy, upz);
– e funzioni per disegnare sfere, coni, … (e la Utha teapot :-)
(attraverso tri+quads)
– NB: da non confondersi con GLUT GLUT GLUT GLUT , che è il TTTToolkit di interfaccia con il SO
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 0 / 1 1 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
librerie amiche GLEW
GLEW GLEW
GLEW ( extension wrangler )
• si occupa delle estensioni 1.
2. prima di usare qualunque funz OpenGL:
(inizializza le funzioni estensione)
3. usare liberamente i comandi di OpenGL esteso es:
#include <GL/glew.h>
glewInit()
glUseProgram( 0 )
Alcuni comandi base:
• Cancellare lo screen buffer
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 0 / 1 1 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
glClearColor( r, g, b, a ); // ogni comp.: doubles // fra 0 e 1
glClear( GL_COLOR_BUFFER_BIT );
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 0 / 1 1 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
• Settare il viewport:
glViewport(int x, int y, int w, int h);
reminder: il rapporto fra w e h deve essere lo stesso specificato nella matrice di proiezione!
Alcuni comandi base:
Specifica lo spazio schermo : - dove inizia (x,y), di solito 0,0 - quanto è largo e alto (w,h), (in pixels, all’interno del widget)
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 0 / 1 1 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
… è basato sullo stato
• Una state machine – ad esempio
• il clear color (colore di cancellamento)
• la posiz posizione luci
• matrici
fanno parte dello stato corrente
• Molti comandi OpenGL non fanno nulla di immediato – cambiano lo stato,
dunque il comportamento dei comandi successivi
• (queries sullo stato: glGet[tipo]( COSTANTE, valori_da_riempire ); )
• es: double v[4];
glGetDoublev( GL_COLOR_CLEAR_VALUE, v );
3
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 0 / 1 1 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
stato di OpenGL
primitive qui
pixels tutto il pipeline
(proiezione, setup, rasterizzazione...) stato di OpenGL manipolazioni di stato (es. settare la matrice)
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 0 / 1 1 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Come si "sparano" i triangoli nel pipeline
glBegin (GL_TRIANGLES);
glVertex3d(x1,y1,z1);
glVertex3d(x2,y2,z2);
glVertex3d(x3,y3,z3);
glVertex3d(x4,y4,z4);
glVertex3d(x5,y5,z5);
glVertex3d(x6,y6,z6);
glVertex3d(x7,y7,z7);
glVertex3d(x8,y8,z8);
glVertex3d(x9,y9,z9);
...
glEnd();
primo triangolo
secondo triangolo
terzo triangolo
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 0 / 1 1 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Come si "sparano" i triangoli nel pipeline
glVertex3d(x,y,z);
oppure glVertex3f(x,y,z);
oppure glVertex3i(x,y,z);
oppure glVertex2d(x,y);
oppure glVertex4d(x,y,z,w);
oppure glVertex4dv(vett);
oppure ...
coordinata z =0 sottointesa!
coordinata w=1 sottointesa!
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 0 / 1 1 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Non solo glBegin (GL_TRIANGLES); linea finale quando si fa la glEnd()
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 0 / 1 1 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Non solo glBegin (GL_TRIANGLES);
quanti triangoli rasterizzati
per quanti vertici proiettati ?
Le specifiche OpenGL non prescrivono quale
diagonale usare
(quindi dipende dall'implementazione
fra m m en ti
(candidati pixels)Reminder Reminder Reminder Reminder
Ve rti ce
(punto in R3)pixel finali
(nello screen-buffer)
Ve rti ce pr oi et ta to
(punto in R2)co m pu ta zi on i pe r v er tic e
rasterizer triangoli
co m pu ta zi on i pe r f ra m m en to set- up
rasterizer segmenti set- up
rasterizer punti set- up
da l r es to de ll’a pp al m on ito r
Cosa avviene in queste fasi?
due opzioni…
a. Fixed Pipeline (deprecato nelle ultime vers)
b. Due programmi arbitrari
4
Fixed Pipeline Fixed Pipeline Fixed Pipeline Fixed Pipeline:
in ciascuna delle due fasi…
• …avviene un certo numero di operazioni
operazioni operazioni
operazioni prefissate prefissate prefissate prefissate
• specifiche di quella fase
• possiamo solo:
– attivarle / disattivarle
• con comandi del tipo:
glEnable( GL_XXX ); glDisable( GL_XXX );
– cambiarne i parametri
• attivazione + parametri fanno parte dello stato
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 0 / 1 1 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Programmable shaders Programmable shaders Programmable shaders Programmable shaders:
in ciascuna delle due fasi…
• Si esegue un apposito programma scritto da noi – programmi detti “Shaders”
• “Vertex Vertex Vertex Vertex Shader Shader Shader Shader”, “Fragment Fragment Fragment Fragment Shader Shader Shader Shader”
1. Scrivere i due “shaders”
– in un apposito linguaggio: in OpenGL:
GLSL GLSL GLSL
GLSL (OpenGL Shading Language) 2. Compilarli (separatamente)
– NB: a tempo di eseguzione!
– tramite appositi comandi dell’API
• (che prendono in input i sorgenti sotto forma di stringhe)
3. “Linkarli” fra loro
– risultato del link: un “program”
4. Impostare il “program” risultante come programma corrente
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 0 / 1 1 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
in OpenGL…
un Program 1 Vertex-Shader = 1 Fragment-Shader +
linkati fra loro
Comandi Comandi Comandi Comandi 1/2 1/2 1/2 1/2
1. Scrivere i due “shaders”:
2. Compilarli:
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 0 / 1 1 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a char * mioVertexShader= “ ... ”;
char * mioFragmentShader= “ ... ”;
int compilaShader(int type, const GLchar* txt) {
GLuint shd= glCreateShader(type);
glShaderSource(shd, 1, &txt, 0);
glCompileShader(shd);
GLint tmp;
glGetShaderiv(shd,GL_COMPILE_STATUS,&tmp);
if (tmp == GL_FALSE) {
return -1; // ERRORI IN PROGRAMMA!!!
} return shd;
}
// e, per es, nel main:
int a= comiplaShader(
GL_VERTEX_SHADER, mioVertexShader );
int b= comiplaShader(
GL_FRAGMENT_SHADER, mioVertexShader );
...
crea un nuovo indice per uno shader setta la stringa come
sorgente compila lo shader testa se la comp è andata ok
Comandi Comandi Comandi Comandi 2/2 2/2 2/2 2/2
3. “Linkarli” fra loro
4. Impostare il “program”
risultante come programma corrente
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 0 / 1 1 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a ...
int a= comiplaShader(
GL_VERTEX_SHADER, mioVertexShader );
int b= comiplaShader(
GL_FRAGMENT_SHADER, mioVertexShader );
GLuint progUno= glCreateProgram();
glAttachShader( progUno, a );
glAttachShader( progUno, b );
glLinkProgram( progUno );
...
glUseProgram( progUno );
su uso 0 come parametro, significa:
no shaders, usa la “FIXED PIPELINE”
QT e OpenGL
• nel file .pro (*):
– (*) che descrive le opzioni di progetto
• lista files del progetto, cartelle di include, definiz macro, opzioni del comp., etc – utilizzato da “qmake” per fare il makefile (**)
• (**) sequenza di comandi per il complilatore – linker
• fare una classe che derivi la classe QGLWidget
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 0 / 1 1 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
QT += opengl
#include <QGLWidget>
class MioWidgetGrafico : public QGLWidget { ...
};
QT e OpenGL
• nella classe che deriva QGLWidget , ridefinire (almeno) gli slot :
• altri slots utili da ridefinire:
• altri metodi utili da usare:
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 0 / 1 1 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a