All’interno del metodo init viene attivato il test di profondità per disegnare solo le parti visibili. Il disegno che si vuole realizzare viene definito all’interno del metodo display della classe GLRenderer che implementa l’interfaccia GLEventListener. Prima del disegno vengono cancellati, sia l’immagine visualizzata (GL_COLOR_BUFFER_BIT), sia il buffer per il test di profondità (GL_DEPTH_BUFFER_BIT), quindi vengono applicate 2 trasformazioni geometriche (rotazioni) alla figura che verrà rappresentata. Nel nostro esempio disegniamo una piramide a partire dal quadrilatero di base, seguito dalle 4 facce laterali; il listato è riportato di seguito. All’interno del metodo reshape viene impostata una trasformazione di visualizzazione di tipo proiezione ortogonale: glOrtho(x1, x2, y1, y2, z1, z2) passando come parametri i limiti reali x e y della finestra di rendering e le posizioni dei 2 piani di “clipping” z1 e z2 all’interno dei quali viene rappresentata la scena.
GLRenderer.java
public class GLRenderer implements GLEventListener { int a = 0; @Override public void init(GLAutoDrawable drawable) { GL2 gl = drawable.getGL().getGL2(); // attiva il test di profondità per disegnare solo le parti visibili gl.glEnable(GL2.GL_DEPTH_TEST); } @Override public void dispose(GLAutoDrawable drawable) { } @Override public void display(GLAutoDrawable drawable) { GL2 gl = drawable.getGL().getGL2(); // cancella l'immagine e il buffer per il test di profondità gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT); gl.glLoadIdentity(); gl.glRotatef(10, 0, 0, 1); // rotazione fissa di 10° intorno a Z gl.glRotatef(a, 1, 0, 0); // rotazione variabile di a intorno a X // la base della piramide è blu, ma il 4° vertice è più scuro gl.glBegin(GL2.GL_QUADS); gl.glColor3d(0, 0, 1); gl.glVertex3d(1, 1, 0); gl.glVertex3d(-1, 1, 0); gl.glVertex3d(-1, -1, 0); gl.glColor3d(0, 0, 0.1); gl.glVertex3d(1, -1, 0); gl.glEnd(); // la 1° faccia è rossa, ma il 3° vertice è più scuro gl.glBegin(GL2.GL_TRIANGLES); gl.glColor3d(1, 0, 0); gl.glVertex3d(0, 0, 1); gl.glVertex3d(1, 1, 0); gl.glColor3d(0.1, 0, 0); gl.glVertex3d(-1, 1, 0); gl.glEnd(); // la 2° faccia è verde, ma il 3° vertice è più scuro gl.glBegin(GL2.GL_TRIANGLES); gl.glColor3d(0, 1, 0); gl.glVertex3d(0, 0, 1); gl.glVertex3d(-1, 1, 0); gl.glColor3d(0, 0.1, 0); gl.glVertex3d(-1, -1, 0); gl.glEnd(); // la 3° faccia è magenta, ma il 3° vertice è più scuro gl.glBegin(GL2.GL_TRIANGLES); gl.glColor3d(1, 0, 1); gl.glVertex3d(0, 0, 1); gl.glVertex3d(-1, -1, 0); gl.glColor3d(0.1, 0, 0.1); gl.glVertex3d(1, -1, 0); gl.glEnd(); // la 4° faccia è gialla, ma il 3° vertice è più scuro gl.glBegin(GL2.GL_TRIANGLES); gl.glColor3d(1, 1, 0); gl.glVertex3d(0, 0, 1); gl.glVertex3d(1, -1, 0); gl.glColor3d(0.1, 0.1, 0); gl.glVertex3d(1, 1, 0); gl.glEnd(); a++; } @Override public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) { GL2 gl = drawable.getGL().getGL2(); // imposta la matrice di trasformazione per la proiezione gl.glMatrixMode(GL2.GL_PROJECTION); gl.glLoadIdentity(); gl.glOrtho(-2.0 * w / h, 2.0 * w / h, -2.0, 2.0, -2.0, 2.0); // imposta la matrice di trasformazione per gli oggetti gl.glMatrixMode(GL2.GL_MODELVIEW); gl.glLoadIdentity(); } }
Progetto Eclipse: Piramide.zip
(controllare nelle Referenced Libraries che i percorsi dei file gluegen-rt.jar e jogl-all.jar siano corretti)