Il seguente post è la traduzione di un tutorial scritto da Jérôme JOUVIE
Iniziamo con il primo tutorial relativo all'OpenGl. Tutti i tutorial funzioneranno con Gl4java, Jogl e Jogl JSR231.
Questi primi tutorial ti insegneranno come disegnare semplici forme come triangoli e quadrati. Associando semplici forme 2D, potremo creare forme 3D come una piramide (composta da 4 triangoli e un quadrato) e un cubo (composto da 6 quadrati). Guarderemo anche come aggiungere colori e vedremo i differenti tipi di rendering: point, linear e fill.
INTRODUZIONEPer disegnare una semplice forma come un triangolo, abbiamo bisogno delle coordinate dei suoi 3 vertici. Questi vertici sono segnati in bianco nella seguente immagine:
In un mondo 3D, le coordinate di un vertice sono rappresentate da 3 valori (x, y, z) nel sistema degli assi:
x è la posizione sull'asse X, y la posizione sull'asse Y, e così via.
L'origine (il centro) del sistema degli assi è il punto (0, 0, 0). Questo punto è al centro della scena (questo viene fatto quando si fa il reset della matrice di trasformazione con glLoadIdentity). Possiamo applicare trasformazioni come traslazione, rotazione e scala al sistema degli assi.
Combinando i triangoli, possiamo creare una piramide. Per il cubo useremo una combinazione di quadrati.
LA PIRAMIDE
Qui possiamo vedere la piramide rappresentata con il suo sistema di assi; i vertici sono contrassegnati da punti bianchi:
Piramide renderizzata con GL_FILL
|
Piramide renderizzata con GL_LINE
|
Per disegnare questa piramide, disegneremo ognuno dei suoi 4 triangoli in successione. La piramide ha 5 vertici diversi che chiameremo v0, v1, v2, ...
IL DISEGNOIl primo triangolo è composto dai vertici v0, v1 e v2, che hanno le coordinate:
v0 = (0, 1, 0)
v1 = (-1, -1, 1)
v2 = (0, -1, 1)
Ogni vertice ha un colore. Il colore usato da OpenGL è in modalità RGB. Il colore è inoltre composto da 3 componenti: (r, g, b). Ogni componente definisce la percentuale di rosso (r), verde (g) e blu (b). Il valore di ogni componente deve essere compreso nell'intervallo [0.0f, 1.0f]
v0 è rosso = (1.f, 0.f, 0.f) // r4D1 significa rosso pieno
v1 è verde = (0.f,"1.f, 0.f) // g=1 significa verde pieno
v2 è blu = (0.f, 0.f, 1.f) // b=1 significa blu pieno
Ecco alcuni esempi di altri colori:
bianco = (1.f, 1.f, 1.f)
// rosso, verde e blu pieni creano il bianco
neero = (0.f, 0.f, 0.f)
// nessun colore
Per disegnare un vertice (x, y, z), utilizzamo il metodo OpenGL:
gl.glVertex3f(x, y, z)Il colore assegnato a questo vertice è il colore corrente definito. Per assegnare un colore ad un vertice, semplicemente impostiamo il colore corrente PRIMA di richiamare glVertex. Questo viene fatto con:
gl.glColor3f (r, g, b) // default: biancoLe chiamate a glVertex devono essere messe in un blocco glBegin/glEnd.
Con questo blocco diciamo a OpenGL che vogliamo disegnare una forma primitiva.
Il tipo di forma disegnata è specificato con il parametro di glBegin. La seguente immagine, presa dal "
The Red Book", mostra tutte le forme primitive e il loro parametro corrispondente:
Picture Copyright © Addison-Wesley Publishing Company
Per disegnare una piramide, possiamo usare:
- GL_TRIANGLE: disegna in successione 4 triangoli indipendenti; verranno pertanto disegnati 12 vertici
- GL_TRIANGLE_FAN: sfrutta i vertici comuni della piramide, e quindi disegnerà 6 vertici
Ecco due modi di renderizzazione per visualizzare una piramide:
Primo metodo: uso di GL_TRIANGLESgl.glBegin(GL_TRIANGLES);//Triangolo 1gl.glColor3f(1.0f,0.0f,0.0f); gl.glVertex3f( 0.0f, 1.0f, 0.0f); //V0(rosso)gl.glColor3f(0.0f,1.0f,0.0f); gl.glVertex3f(-1.0f,-1.0f, 1.0f); //V1(verde)gl.glColor3f(0.0f,0.0f,1.0f); gl.glVertex3f( 1.0f,-1.0f, 1.0f); //V2(blu)//Triangolo 2gl.glColor3f(1.0f,0.0f,0.0f); gl.glVertex3f( 0.0f, 1.0f, 0.0f); //V0(rosso)gl.glColor3f(0.0f,0.0f,1.0f); gl.glVertex3f( 1.0f,-1.0f, 1.0f); //V2(blu)gl.glColor3f(0.0f,1.0f,0.0f); gl.glVertex3f( 1.0f,-1.0f,-1.0f); //V3(verde)//Triangolo 3gl.glColor3f(1.0f,0.0f,0.0f); gl.glVertex3f( 0.0f, 1.0f, 0.0f); //V0(rosso)gl.glColor3f(0.0f,1.0f,0.0f); gl.glVertex3f( 1.0f,-1.0f,-1.0f); //V3(verde)gl.glColor3f(0.0f,0.0f,1.0f); gl.glVertex3f(-1.0f,-1.0f,-1.0f); //V4(blu)//Triangolo 4gl.glColor3f(1.0f,0.0f,0.0f); gl.glVertex3f( 0.0f, 1.0f, 0.0f); //V0(rosso)gl.glColor3f(0.0f,0.0f,1.0f); gl.glVertex3f(-1.0f,-1.0f,-1.0f); //V4(blu)gl.glColor3f(0.0f,1.0f,0.0f); gl.glVertex3f(-1.0f,-1.0f, 1.0f); //V1(verde)gl.glEnd();Secondo metodo: uso di GL_TRIANGLE_FANgl.glBegin(GL_TRIANGLE_FAN);gl.glColor3f(1.0f,0.0f,0.0f); gl.glVertex3f( 0.0f, 1.0f, 0.0f); //V0(rosso)gl.glColor3f(0.0f,1.0f,0.0f); gl.glVertex3f(-1.0f,-1.0f, 1.0f); //V1(verde)gl.glColor3f(0.0f,0.0f,1.0f); gl.glVertex3f( 1.0f,-1.0f, 1.0f); //V2(blu)gl.glColor3f(0.0f,1.0f,0.0f); gl.glVertex3f( 1.0f,-1.0f,-1.0f); //V3(verde)gl.glColor3f(0.0f,0.0f,1.0f); gl.glVertex3f(-1.0f,-1.0f,-1.0f); //V4(blu)gl.glColor3f(0.0f,1.0f,0.0f); gl.glVertex3f(-1.0f,-1.0f, 1.0f); //V1(verde)gl.glEnd();IL CUBOEd ora il cubo; qui c'è la descrizione del cubo che verrà disegnato:
Cubo renderizzato con GL_FILL
|
Cubo renderizzato con GL_LINE
|
Per disegnare questa forma, potete usare GL_QUADS o GL_QUAD_STRIP. L'ordine delle chiaamte di glVertex è importante perchè definisce l'orientamento della faccia.
Un lato della faccia è quello frontale (GL_FRONT), l'altro è quello posteriore (GL_BACK).
Disegnare il cuboPrimo metodo: uso di GL_QUADSgl.glBegin(GL_QUADS);//Quadrilatero 1gl.glVertex3f( 1.0f, 1.0f, 1.0f); //V2gl.glVertex3f( 1.0f,-1.0f, 1.0f); //V1gl.glVertex3f( 1.0f,-1.0f,-1.0f); //V3gl.glVertex3f( 1.0f, 1.0f,-1.0f); //V4//Quadrilatero 2gl.glVertex3f( 1.0f, 1.0f,-1.0f); //V4gl.glVertex3f( 1.0f,-1.0f,-1.0f); //V3gl.glVertex3f(-1.0f,-1.0f,-1.0f); //V5gl.glVertex3f(-1.0f, 1.0f,-1.0f); //V6//Quadrilatero 3gl.glVertex3f(-1.0f, 1.0f,-1.0f); //V6gl.glVertex3f(-1.0f,-1.0f,-1.0f); //V5gl.glVertex3f(-1.0f,-1.0f, 1.0f); //V7gl.glVertex3f(-1.0f, 1.0f, 1.0f); //V8//Quadrilatero 4gl.glVertex3f(-1.0f, 1.0f, 1.0f); //V8gl.glVertex3f(-1.0f,-1.0f, 1.0f); //V7gl.glVertex3f( 1.0f,-1.0f, 1.0f); //V1gl.glVertex3f( 1.0f, 1.0f, 1.0f); //V2//Quadrilatero 5gl.glVertex3f(-1.0f, 1.0f,-1.0f); //V6gl.glVertex3f(-1.0f, 1.0f, 1.0f); //V8gl.glVertex3f( 1.0f, 1.0f, 1.0f); //V2gl.glVertex3f( 1.0f, 1.0f,-1.0f); //V4//Quadrilatero 6gl.glVertex3f(-1.0f,-1.0f, 1.0f); //V7gl.glVertex3f(-1.0f,-1.0f,-1.0f); //V5gl.glVertex3f( 1.0f,-1.0f,-1.0f); //V3gl.glVertex3f( 1.0f,-1.0f, 1.0f); //V1gl.glEnd();Secondo metodo: uso di GL_QUAD_STRIPgl.glBegin(GL.GL_QUAD_STRIP);//Quadrilateros 1 2 3 4gl.glVertex3f( 1.0f, 1.0f, 1.0f); //V2gl.glVertex3f( 1.0f,-1.0f, 1.0f); //V1gl.glVertex3f( 1.0f, 1.0f,-1.0f); //V4gl.glVertex3f( 1.0f,-1.0f,-1.0f); //V3gl.glVertex3f(-1.0f, 1.0f,-1.0f); //V6gl.glVertex3f(-1.0f,-1.0f,-1.0f); //V5gl.glVertex3f(-1.0f, 1.0f, 1.0f); //V8gl.glVertex3f(-1.0f,-1.0f, 1.0f); //V7gl.glVertex3f( 1.0f, 1.0f, 1.0f); //V2gl.glVertex3f( 1.0f,-1.0f, 1.0f); //V1gl.glEnd();gl.glBegin(GL.GL_QUADS);//Quadrilatero 5gl.glVertex3f(-1.0f, 1.0f,-1.0f); //V6gl.glVertex3f(-1.0f, 1.0f, 1.0f); //V8gl.glVertex3f( 1.0f, 1.0f, 1.0f); //V2gl.glVertex3f( 1.0f, 1.0f,-1.0f); //V4//Quadrilatero 6gl.glVertex3f(-1.0f,-1.0f, 1.0f); //V7gl.glVertex3f(-1.0f,-1.0f,-1.0f); //V5gl.glVertex3f( 1.0f,-1.0f,-1.0f); //V3gl.glVertex3f( 1.0f,-1.0f, 1.0f); //V1gl.glEnd();Osservazioni:"GL." messo prima delle costanti OpenGL è una caratteristica di Jogl.