LWJGL Forum

Programming => Lightweight Java Gaming Library => Topic started by: hawkettc on February 12, 2006, 05:20:41

Title: lwjgl Lighting problems compared to JOGL
Post by: hawkettc on February 12, 2006, 05:20:41
Hi,

  I'm having difficulty getting lighting to work effectively under lwjgl on OS X.  The lighting works, but it produces shadow-like artefacts that look similar to aliasing, but not.  I recently moved to lwjgl from JOGL so it didn't take too much effort to put together a test in jogl using exactly the same gl commands.  The lighting is much better in JOGL.  The only thing I can think of at the moment is that some performance enhancement is on by default in lwjgl that is off by default in JOGL.  Or perhaps the bindings to the underlying gl are implemented differently.
 
Anyway - here is the lwjgl code -


public class CubeLightingTest {
private boolean closing = false;

private boolean lighting = true;

private float rotation = 0;

private void initGL() {
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

ByteBuffer temp = ByteBuffer.allocateDirect(16);
temp.order(ByteOrder.nativeOrder());
GL11.glLightModel(GL11.GL_LIGHT_MODEL_AMBIENT, (FloatBuffer)temp.asFloatBuffer().put(new float[] {0.9f, 0.9f, 0.9f, 1.0f}).flip());

GL11.glLight(GL11.GL_LIGHT1, GL11.GL_POSITION, (FloatBuffer)temp.asFloatBuffer().put(new float[] {0.0f, 0.0f, 0.0f, 1.0f}).flip());
GL11.glLight(GL11.GL_LIGHT1, GL11.GL_DIFFUSE, (FloatBuffer)temp.asFloatBuffer().put(new float[] {1.0f, 1.0f, 1.0f, 1.0f}).flip());
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_LIGHT1);

GL11.glClearDepth(1.0f);
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glDepthFunc(GL11.GL_LEQUAL);

GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);

GL11.glViewport(0, 0, Display.getDisplayMode().getWidth(), Display.getDisplayMode().getHeight());
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GLU.gluPerspective(45.0f, (float) Display.getDisplayMode().getWidth() / (float) Display.getDisplayMode().getHeight(), 0.1f, 100.0f);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
}

private void render() {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glLoadIdentity();

GL11.glTranslated(0, 0, -60);
GL11.glRotatef(rotation, 1f, 1f, 0f);

rotation += 0.15f;
if(rotation > 360) rotation -= 360;

GL11.glBegin(GL11.GL_QUADS); // Start Drawing Quads
// Front Face
GL11.glNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Towards Viewer
GL11.glVertex3f(-1.0f, -1.0f, 1.0f); // Point 1 (Front)
GL11.glVertex3f(1.0f, -1.0f, 1.0f); // Point 2 (Front)
GL11.glVertex3f(1.0f, 1.0f, 1.0f); // Point 3 (Front)
GL11.glVertex3f(-1.0f, 1.0f, 1.0f); // Point 4 (Front)
// Back Face
GL11.glNormal3f(0.0f, 0.0f, -1.0f); // Normal Pointing Away From Viewer
GL11.glVertex3f(-1.0f, -1.0f, -1.0f); // Point 1 (Back)
GL11.glVertex3f(-1.0f, 1.0f, -1.0f); // Point 2 (Back)
GL11.glVertex3f(1.0f, 1.0f, -1.0f); // Point 3 (Back)
GL11.glVertex3f(1.0f, -1.0f, -1.0f); // Point 4 (Back)
// Top Face
GL11.glNormal3f(0.0f, 1.0f, 0.0f); // Normal Pointing Up
GL11.glVertex3f(-1.0f, 1.0f, -1.0f); // Point 1 (Top)
GL11.glVertex3f(-1.0f, 1.0f, 1.0f); // Point 2 (Top)
GL11.glVertex3f(1.0f, 1.0f, 1.0f); // Point 3 (Top)
GL11.glVertex3f(1.0f, 1.0f, -1.0f); // Point 4 (Top)
// Bottom Face
GL11.glNormal3f(0.0f, -1.0f, 0.0f); // Normal Pointing Down
GL11.glVertex3f(-1.0f, -1.0f, -1.0f); // Point 1 (Bottom)
GL11.glVertex3f(1.0f, -1.0f, -1.0f); // Point 2 (Bottom)
GL11.glVertex3f(1.0f, -1.0f, 1.0f); // Point 3 (Bottom)
GL11.glVertex3f(-1.0f, -1.0f, 1.0f); // Point 4 (Bottom)
// Right face
GL11.glNormal3f(1.0f, 0.0f, 0.0f); // Normal Pointing Right
GL11.glVertex3f(1.0f, -1.0f, -1.0f); // Point 1 (Right)
GL11.glVertex3f(1.0f, 1.0f, -1.0f); // Point 2 (Right)
GL11.glVertex3f(1.0f, 1.0f, 1.0f); // Point 3 (Right)
GL11.glVertex3f(1.0f, -1.0f, 1.0f); // Point 4 (Right)
// Left Face
GL11.glNormal3f(-1.0f, 0.0f, 0.0f); // Normal Pointing Left
GL11.glVertex3f(-1.0f, -1.0f, -1.0f); // Point 1 (Left)
GL11.glVertex3f(-1.0f, -1.0f, 1.0f); // Point 2 (Left)
GL11.glVertex3f(-1.0f, 1.0f, 1.0f); // Point 3 (Left)
GL11.glVertex3f(-1.0f, 1.0f, -1.0f); // Point 4 (Left)
GL11.glEnd(); // Done Drawing Quads

GL11.glFlush();
}

protected void execute() {
setupDisplay();
while (!closing) {
handleWindow();
handleKeyboard();
render();
}
Display.destroy();
}

private void setupDisplay() {
try {
Display.setDisplayMode(new DisplayMode(1024, 768));
Display.setFullscreen(false);
Display.create();
} catch (Exception e) {
e.printStackTrace();
System.exit(-1);
}

initGL();
}

protected void handleWindow() {
Display.update();
closing = Display.isCloseRequested();
}

protected void handleKeyboard() {
while (Keyboard.next()) {
if (Keyboard.getEventKey() == Keyboard.KEY_ESCAPE && Keyboard.getEventKeyState()) {
closing = true;
}
if (Keyboard.getEventKey() == Keyboard.KEY_L && Keyboard.getEventKeyState()) {
if(!lighting) GL11.glEnable(GL11.GL_LIGHT1);
else GL11.glDisable(GL11.GL_LIGHT1);
lighting = !lighting;
}
}
}

public static void main(String[] args) {
new CubeLightingTest().execute();
}
}


And here is the JOGL code


public class CubeLightingTest extends JFrame implements GLEventListener {
public static final Dimension PREFERRED_FRAME_SIZE = new Dimension (1024,768);

private GLCanvas canvas;
private Animator anim;

private float rotation = 0;

public CubeLightingTest() {
super("Cube Lighting Test");

addWindowListener(new ShutdownWindowAdapter());

canvas = GLDrawableFactory.getFactory().createGLCanvas( new GLCapabilities());
canvas.addGLEventListener(this);
anim = new Animator(canvas);
anim.start();

getContentPane().add(canvas, BorderLayout.CENTER);

}

public static void main (String[] args) {
CubeLightingTest f = new CubeLightingTest();
f.pack();
f.setVisible(true);
   }

public void init(GLDrawable drawable) {
final GL gl = drawable.getGL();

gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
gl.glShadeModel(GL.GL_SMOOTH);

gl.glLightModelfv(GL.GL_LIGHT_MODEL_AMBIENT, new float[] {0.9f, 0.9f, 0.9f, 1.0f});
gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, new float[] {0.0f, 0.0f, 0.0f, 1.0f});
gl.glLightfv(GL.GL_LIGHT1, GL.GL_DIFFUSE, new float[] {1.0f, 1.0f, 1.0f, 1.0f});
gl.glEnable(GL.GL_LIGHTING);
gl.glEnable(GL.GL_LIGHT1);

gl.glClearDepth(1.0f);
gl.glEnable(GL.GL_DEPTH_TEST);
gl.glDepthFunc(GL.GL_LEQUAL);

gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
}

public void reshape(final GLDrawable drawable, final int x, final int y, final int width, int height) {
final GL gl = drawable.getGL();
final GLU glu = drawable.getGLU();

if (height <= 0) height = 1;
final float h = (float) width / (float) height;
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(45.0f, h, 0.1, 100.0);
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
}

public void display(GLDrawable drawable) {
final GL gl = drawable.getGL();

gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();

gl.glTranslated(0, 0, -60);
gl.glRotatef(rotation, 1f, 1f, 0f);

rotation += 0.15f;
if(rotation > 360) rotation -= 360;

gl.glBegin(GL.GL_QUADS); // Start Drawing Quads
// Front Face
gl.glNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Towards Viewer
gl.glVertex3f(-1.0f, -1.0f, 1.0f); // Point 1 (Front)
gl.glVertex3f(1.0f, -1.0f, 1.0f); // Point 2 (Front)
gl.glVertex3f(1.0f, 1.0f, 1.0f); // Point 3 (Front)
gl.glVertex3f(-1.0f, 1.0f, 1.0f); // Point 4 (Front)
// Back Face
gl.glNormal3f(0.0f, 0.0f, -1.0f); // Normal Pointing Away From Viewer
gl.glVertex3f(-1.0f, -1.0f, -1.0f); // Point 1 (Back)
gl.glVertex3f(-1.0f, 1.0f, -1.0f); // Point 2 (Back)
gl.glVertex3f(1.0f, 1.0f, -1.0f); // Point 3 (Back)
gl.glVertex3f(1.0f, -1.0f, -1.0f); // Point 4 (Back)
// Top Face
gl.glNormal3f(0.0f, 1.0f, 0.0f); // Normal Pointing Up
gl.glVertex3f(-1.0f, 1.0f, -1.0f); // Point 1 (Top)
gl.glVertex3f(-1.0f, 1.0f, 1.0f); // Point 2 (Top)
gl.glVertex3f(1.0f, 1.0f, 1.0f); // Point 3 (Top)
gl.glVertex3f(1.0f, 1.0f, -1.0f); // Point 4 (Top)
// Bottom Face
gl.glNormal3f(0.0f, -1.0f, 0.0f); // Normal Pointing Down
gl.glVertex3f(-1.0f, -1.0f, -1.0f); // Point 1 (Bottom)
gl.glVertex3f(1.0f, -1.0f, -1.0f); // Point 2 (Bottom)
gl.glVertex3f(1.0f, -1.0f, 1.0f); // Point 3 (Bottom)
gl.glVertex3f(-1.0f, -1.0f, 1.0f); // Point 4 (Bottom)
// Right face
gl.glNormal3f(1.0f, 0.0f, 0.0f); // Normal Pointing Right
gl.glVertex3f(1.0f, -1.0f, -1.0f); // Point 1 (Right)
gl.glVertex3f(1.0f, 1.0f, -1.0f); // Point 2 (Right)
gl.glVertex3f(1.0f, 1.0f, 1.0f); // Point 3 (Right)
gl.glVertex3f(1.0f, -1.0f, 1.0f); // Point 4 (Right)
// Left Face
gl.glNormal3f(-1.0f, 0.0f, 0.0f); // Normal Pointing Left
gl.glVertex3f(-1.0f, -1.0f, -1.0f); // Point 1 (Left)
gl.glVertex3f(-1.0f, -1.0f, 1.0f); // Point 2 (Left)
gl.glVertex3f(-1.0f, 1.0f, 1.0f); // Point 3 (Left)
gl.glVertex3f(-1.0f, 1.0f, -1.0f); // Point 4 (Left)
gl.glEnd(); // Done Drawing Quads

gl.glFlush();
}

public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {
System.out.println("displayChanged() called");
}

public Dimension getPreferredSize () {
       return PREFERRED_FRAME_SIZE;
   }

public void stop() {
anim.stop();
System.exit(0);
}

private class ShutdownWindowAdapter extends WindowAdapter {
       public void windowClosing(WindowEvent e) {
           stop();
       }
   }
}


The shadowy things I am talking about are clearly visible along the edges of the cube at various points during the rotation when running under lwjgl, and not at all under JOGL.  The aliasing seems to be about the same - the chunky shadow things are what is different.  If anyone has any ideas why one would look good and the other not - it would be much appreciated - lwjgl is much better to develop with.  

Its bound to be something really obvious - but I can't spot it.

Cheers,

Colin
Title: lwjgl Lighting problems compared to JOGL
Post by: hawkettc on February 12, 2006, 11:44:41
Additional information -

lwjgl ver : 0.99
jogl ver  : 1.1.1

The cube is smallish in the example because that's the distance at which the effect is most obvious.  If it is close to the viewer, then the effect iis negligible.  Unfortunately not all objects in my scene are close to the viewer.

The more objects there are in the scene the worse the effect gets - combining together to produce dark diagonal strips pulstaing across the whole scene.

The other thing is that the faces of the cube appear bettter lit - clearly the JOGL faces vary in shading depending on their angle to the light, whereas  the lwjgl faces appear all the same colour (except for the unwanted shadow effects).

I'd even be interested to know if the effect is OS X only or appears on windows/linux as well. Thanks,

Colin
Title: hmmmmmm....
Post by: Fool Running on February 13, 2006, 17:20:47
Just a guess (Could you maybe post a screenshot?):
Try setting the glFrontFace to GL_CW. I think your polygons are in clockwise direction. (Someone correct me on this. I have a hard time telling :) ). LWJGL defaults to a counter clockwise direction. This would produce some wierd effects (possibly what you are describing). :lol:
Title: lwjgl Lighting problems compared to JOGL
Post by: hawkettc on February 14, 2006, 09:21:43
(http://homepage.mac.com/hawkettc/cube.jpg)

Hi I'm pretty sure I am doing them counter clockwise... will check - here is the screenshot in the meantime - cheers,

Colin
Title: lwjgl Lighting problems compared to JOGL
Post by: hawkettc on February 14, 2006, 11:41:16
(http://homepage.mac.com/hawkettc/cubeJOGL.jpg)

This is JOGL at roughly the same point in the rotation.  I also tried GL_CW and GL_CCW in lwjgl - I had expected the lighting to be different if the front faces were all on the inside of the cube instead of the outside - but there wasn't actually any discernable difference either way.... the order in the code should be CCW i.e. - bottom left, bottom right, top right, top left....
Title: lwjgl Lighting problems compared to JOGL
Post by: spasi on February 14, 2006, 13:36:54
Maybe Display.create() is the cause of the problem. The default PixelFormat used there is a PixelFormat(0, 0, 8, 0, 0). Try this:

Display.create(new PixelFormat(24, 8, 24, 0, 0));

I don't know about JOGL, but I can assure you that LWJGL contains no GL related optimization and does not modify the GL state in any way, except from initContext() in the Display class that just sets up an orthographic view.
Title: hmmmmmm...
Post by: Fool Running on February 14, 2006, 18:13:06
QuoteThe default PixelFormat used there is a PixelFormat(0, 0, 8, 0, 0)
I didn't realize the default depth bit was set so low. That's almost worthless for 3D graphics. :lol:
QuoteHi I'm pretty sure I am doing them counter clockwise... will check - here is the screenshot in the meantime - cheers
Yeah, that doesn't look like your problem from the screenshots. I think spasi is right. 8)
Title: lwjgl Lighting problems compared to JOGL
Post by: hawkettc on February 14, 2006, 20:48:44
Cool - thats done the trick - thanks heaps.  btw great work on lwjgl guys - as an fyi - it was Mouse.setGrabbed() that got me from JOGL to lwwjgl... but there are so many other small tings that make it better to work with... keep it up

Colin