Materiali

In questo esempio vedremo come utilizzare i materiali per modificare il colore della superficie degli oggetti, come visualizzare del testo e tracciare delle linee. A programma completato sarà visibile la molecola di acqua che ruota, così come appare nel video della pagina iniziale di questo sito.

acqua

GLRenderer.java

public class GLRenderer implements GLEventListener {

    float a = 0.0f;

    @Override
    public void init(GLAutoDrawable drawable) {
        GL2 gl = drawable.getGL().getGL2();

        // imposta le caratteristiche della sorgente di luce 0
        float[] lAmbiente = new float[]{1, 1, 1, 1};
        float[] lDiffusa = new float[]{1, 1, 1, 1};
        float[] lSpeculare = new float[]{1, 1, 1, 1};
        float[] lPosizione = new float[]{0, 5, 5, 1};

        gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_AMBIENT, lAmbiente, 0);
        gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_DIFFUSE, lDiffusa, 0);
        gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_SPECULAR, lSpeculare, 0);
        gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, lPosizione, 0);

        // imposta le caratteristiche del materiale
        float[] mAmbiente = new float[]{0, 0, 0, 1};
        float[] mDiffusa = new float[]{1, 1, 1, 1};
        float[] mSpeculare = new float[]{1, 1, 1, 1};
        float[] mEmissione = new float[]{0, 0, 0, 1};
        float[] mLucentezza = new float[]{10};

        gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_AMBIENT, mAmbiente, 0);
        gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_DIFFUSE, mDiffusa, 0);
        gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_SPECULAR, mSpeculare, 0);
        gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_EMISSION, mEmissione, 0);
        gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_SHININESS, mLucentezza, 0);

        // attiva la sorgente di luce 0
        gl.glEnable(GL2.GL_LIGHT0);
        // attiva l'iluminazione
        gl.glEnable(GL2.GL_LIGHTING);
        // attiva il materiale
        gl.glEnable(GL2.GL_COLOR_MATERIAL);
        // attiva il test di profondità per disegnare solo parti visibili
        gl.glEnable(GL2.GL_DEPTH_TEST);
        // imposta il colore di sfondo
        gl.glClearColor(0, 0, 0.1f, 0);
    }

    @Override
    public void dispose(GLAutoDrawable drawable) {
    }

    @Override
    public void display(GLAutoDrawable drawable) {
        GL2 gl = drawable.getGL().getGL2();
        GLUT glut = new GLUT();

        // 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(a, 1, 1, 1);
        gl.glBegin(GL2.GL_LINES);
        gl.glVertex3f(0, 0, -3);
        gl.glVertex3f(0, 0, 3);
        gl.glEnd();

        // ossigeno
        gl.glColor3f(0.4f, 0.05f, 0.05f);
        gl.glLoadIdentity();
        gl.glRotatef(a, 1, 1, 1);
        glut.glutSolidSphere(1, 72, 36);
        // lettera O
        gl.glColor3f(0.4f, 0.4f, 0.4f);
        gl.glRotatef(104.45f/2, 0, 0, 1);
        gl.glTranslatef(-2.4f, -0.5f, 0);
        gl.glScalef(0.01f, 0.01f, 0.01f);
        glut.glutStrokeCharacter(GLUT.STROKE_ROMAN, 'O');

        // idrogeno 1
        gl.glColor3f(0.05f, 0.05f, 0.4f);
        gl.glLoadIdentity();
        gl.glRotatef(a, 1, 1, 1);
        gl.glTranslatef(3, 0, 0);
        glut.glutSolidSphere(0.6f, 72, 36);
        // lettera H
        gl.glColor3f(0.4f, 0.4f, 0.4f);
        gl.glTranslatef(1, -0.5f, 0);
        gl.glScalef(0.01f, 0.01f, 0.01f);
        glut.glutStrokeCharacter(GLUT.STROKE_ROMAN, 'H');

        // idrogeno 2
        gl.glColor3f(0.05f, 0.05f, 0.4f);
        gl.glLoadIdentity();
        gl.glRotatef(a, 1, 1, 1);
        gl.glRotatef(104.45f, 0, 0, 1);
        gl.glTranslatef(3, 0, 0);
        glut.glutSolidSphere(0.6f, 72, 36);
        // lettera H
        gl.glColor3f(0.4f, 0.4f, 0.4f);
        gl.glTranslatef(1, -0.5f, 0);
        gl.glScalef(0.01f, 0.01f, 0.01f);
        glut.glutStrokeCharacter(GLUT.STROKE_ROMAN, 'H');

        // legame 1
        gl.glColor3f(0.4f, 0.4f, 0.4f);
        gl.glLoadIdentity();
        gl.glRotatef(a, 1, 1, 1);
        gl.glRotatef(90, 0, 1, 0);
        glut.glutSolidCylinder(0.15, 3, 24, 10);

        // legame 2
        gl.glLoadIdentity();
        gl.glRotatef(a, 1, 1, 1);
        gl.glRotatef(105, 0, 0, 1);
        gl.glRotatef(90, 0, 1, 0);
        glut.glutSolidCylinder(0.15, 3, 24, 10);
        
        // angolo 104.45°
        gl.glColor3f(0.4f, 0.4f, 0.4f);
        gl.glLoadIdentity();
        gl.glRotatef(a, 1, 1, 1);
        gl.glRotatef(104.45f/2, 0, 0, 1);
        gl.glTranslatef(1.2f, -0.25f, 0);
        gl.glScalef(0.005f, 0.005f, 0.005f);
        glut.glutStrokeString(GLUT.STROKE_ROMAN, "104,45");
        gl.glTranslatef(0, 75.0f, 0);
        gl.glScalef(0.5f, 0.5f, 0.5f);
        glut.glutStrokeCharacter(GLUT.STROKE_ROMAN, 'o');

        // incrementa l'angolo di rotazione di 1°
        a += 1.0f;
    }

    @Override
    public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {
        GL2 gl = drawable.getGL().getGL2();
        GLU glu = new GLU();

        // imposta la matrice di trasformazione per la proiezione
        gl.glMatrixMode(GL2.GL_PROJECTION);
        gl.glLoadIdentity();
        glu.gluPerspective(45, (float) w / h, 5, 50);
        glu.gluLookAt(0, 0, 15, 0, 0, 0, 0, 1, 0);

        // imposta la matrice di trasformazione per gli oggetti
        gl.glMatrixMode(GL2.GL_MODELVIEW);
        gl.glLoadIdentity();
    }

}