[JOGL/JSR-231] Specular problem

Hi everybody.

First, I’m french, so I’m sorry for my poor english.

I’m a JOGL (JSR-231) newbie and I have 2 difficulties with the specular component of my lighting.

1 / when my camera is pointing to z -, all seems to be working. The good code portion:

final float[] CAMERA_POSITION = new float[]{0F, 5F, 15F};
final float[] CAMERA_DIRECTION = new float[]{0F, 0F, 0F};
final float[] SPOT_POSITION = new float[]{0F, 5F, 15F, 1F};
final float[] SPOT_DIRECTION = new float[]{0F, 0F, -1F, 1F};

but if I’m pointing to the z-, I lose the specular component. The bad code portion:

final float[] CAMERA_POSITION = new float[]{0F, 5F, -15F};
final float[] CAMERA_DIRECTION = new float[]{0F, 0F, 0F};
final float[] SPOT_POSITION = new float[]{0F, 5F, -15F, 1F};
final float[] SPOT_DIRECTION = new float[]{0F, 0F, 1F, 1F};

2 / If i activate this :

gl.glLightModeli(GL.GL_LIGHT_MODEL_LOCAL_VIEWER, GL.GL_TRUE)

I’m losing also the specular composant

The entire code :

package Test1;

import com.sun.opengl.util.Animator;
import com.sun.opengl.util.GLUT;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Insets;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.media.opengl.*;
import javax.media.opengl.glu.*;
import javax.swing.SwingUtilities;

public class TestAPoster extends Frame implements GLEventListener {

    private final GLU GLU = new GLU();
    private final GLUT GLUT = new GLUT();
    private final Dimension CLIENT_MINIMUM_DIMENSION = new Dimension(640, 480);

    final float[] CAMERA_POSITION = new float[]{0F, 5F, 15F};
    final float[] CAMERA_DIRECTION = new float[]{0F, 0F, 0F};
    final float[] SPOT_POSITION = new float[]{0F, 5F, 15F, 1F};
    final float[] SPOT_DIRECTION = new float[]{0F, 0F, -1F, 1F};

    public TestAPoster() {

        // Hardware OpenGl
        GLCapabilities glCapabilities = new GLCapabilities();
        glCapabilities.setDoubleBuffered(true);
        glCapabilities.setHardwareAccelerated(true);

        // Canvas JOGL
        GLCanvas canvas = new GLCanvas();
        canvas.addGLEventListener(this);
        canvas.setPreferredSize(CLIENT_MINIMUM_DIMENSION);
        add(canvas);

        // Fenêtre
        setTitle(getClass().getSimpleName());
        setLocation(20, 20);
        setVisible(true);
        final Insets insets = getInsets();
        setMinimumSize(new Dimension(CLIENT_MINIMUM_DIMENSION.width + insets.left + insets.right, CLIENT_MINIMUM_DIMENSION.height + insets.top + insets.bottom));
        pack();

        // Boucle d'affichage
        final Animator animator = new Animator(canvas);
        addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        animator.stop();
                        System.exit(0);
                    }
                }).start();
            }
        });
        // Et c'est parti ...
        animator.start();
    }

    @Override
    public void init(GLAutoDrawable _glDrawable) {
    }

    @Override
    public void display(GLAutoDrawable _glDrawable) {
        final GL gl = _glDrawable.getGL();
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
        GLUT.glutSolidTeapot(3);
    }

    @Override
    public void reshape(GLAutoDrawable _glDrawable, int _x, int _y, int _width, int _height) {
        final GL gl = _glDrawable.getGL();

        // Couleur de fond et du zbuffer
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        gl.glClearDepth(1.0f);

        // Caméra et projection
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();
        GLU.gluPerspective(45, (double) ((double) _width / (double) _height), 0.1D, 100D);
        GLU.gluLookAt(CAMERA_POSITION[0], CAMERA_POSITION[1], CAMERA_POSITION[2], CAMERA_DIRECTION[0], CAMERA_DIRECTION[1], CAMERA_DIRECTION[2], 0D, 1D, 0D);

        // Matrix de vue
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glLoadIdentity();

        // Modèle d'éclairage
        gl.glShadeModel(GL.GL_SMOOTH);
        //gl.glLightModeli(GL.GL_LIGHT_MODEL_LOCAL_VIEWER, GL.GL_TRUE);

        // Lumière ponctiuelle
        gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, SPOT_POSITION, 0);
        gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPOT_DIRECTION, SPOT_DIRECTION, 0);
        gl.glLightf(GL.GL_LIGHT0, gl.GL_SPOT_CUTOFF, 60F);
        gl.glLightf(GL.GL_LIGHT0, GL.GL_SPOT_EXPONENT, 3.0F);

        gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, new float[]{0.2F, 0.2F, 0.2F, 1F}, 0);
        gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, new float[]{1F, 0F, 0F, 1F}, 0);
        gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, new float[]{1F, 1F, 1F, 1F}, 0);

        // Matériau de l'objet
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, new float[]{0.2F, 0.2F, 0.2F, 1F}, 0);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, new float[]{1F, 0F, 0F, 1F}, 0);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, new float[]{1F, 1F, 1F, 1F}, 0);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_SHININESS, new float[]{30F}, 0);

        // Etats
        gl.glEnable(GL.GL_DEPTH_TEST);
        gl.glEnable(GL.GL_LIGHTING);
        gl.glEnable(GL.GL_LIGHT0);
    }

    @Override
    public void displayChanged(GLAutoDrawable _glDrawable, boolean _modeChanged, boolean _deviceChanged) {
    }

    public static void main(String[] _args) {
        final TestAPoster test = new TestAPoster();
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                test.setVisible(true);
            }
        });
    }
}

In attachment the pictures.

Thank you very much for your answers.