1
votes

My goal is to create small scene with lighting. However, lighting seem to rotate together with my rendered object (test cube).

In most responses I've read I should use GL11.glLight in projection and model matrix mode, I assumed. Please correct me if I'm wrong. However, result is that lighting works, but it intensity varies with cube rotation.

Here is my example prepared for Stack:

package main;

import java.nio.FloatBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;

public class Stack {

    static int rot;
    static int rot2;

    public static void main(String[] args) {
        Stack r = new Stack();
        r.start();
    }

    public void start() {
        try {
            createWindow();
            initGL();
            run();
        } catch (Exception e) {

            e.printStackTrace();
        }
    }

    private void run() {
        while (!Display.isCloseRequested()) {
            try {
                render();
                Display.update();
                Display.sync(60);
            } catch (Exception e) {

            }
        }
        Display.destroy();
    }

    private void render() {
        rot++;
        rot2++;
        rot2++;
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
        GL11.glLoadIdentity();
        GL11.glLight(GL11.GL_LIGHT0,GL11.GL_POSITION,floatBuffer(5,0,10,0));

        GL11.glTranslatef(0f, 0.0f, -7f);
        GL11.glRotatef(rot, 0.0f, 1.0f, 0.0f);
        GL11.glRotatef(rot2, 1.0f, 0.0f, 0.0f);
        renderCube();
        GL11.glRotatef(-rot2, 1.0f, 0.0f, 0.0f);
        GL11.glRotatef(-rot, 0.0f, 1.0f, 0.0f);
        GL11.glTranslatef(0f, 0.0f, 7f);
    }

    public FloatBuffer floatBuffer(float a, float b, float c, float d) {
        float[] data = new float[] { a, b, c, d };
        FloatBuffer fb = BufferUtils.createFloatBuffer(data.length);
        fb.put(data);
        fb.flip();
        return fb;
    }

    private void renderCube() {

        GL11.glBegin(GL11.GL_QUADS);
        GL11.glColor3f(1.0f, 0.7f, 0.7f);
        GL11.glVertex3f(1.0f, 1.0f, -1.0f);
        GL11.glVertex3f(-1.0f, 1.0f, -1.0f);
        GL11.glVertex3f(-1.0f, 1.0f, 1.0f);
        GL11.glVertex3f(1.0f, 1.0f, 1.0f);
        GL11.glColor3f(1.0f, 0.5f, 0.0f);
        GL11.glVertex3f(1.0f, -1.0f, 1.0f);
        GL11.glVertex3f(-1.0f, -1.0f, 1.0f);
        GL11.glVertex3f(-1.0f, -1.0f, -1.0f);
        GL11.glVertex3f(1.0f, -1.0f, -1.0f);
        GL11.glColor3f(1.0f, 0.0f, 0.0f);
        GL11.glVertex3f(1.0f, 1.0f, 1.0f);
        GL11.glVertex3f(-1.0f, 1.0f, 1.0f);
        GL11.glVertex3f(-1.0f, -1.0f, 1.0f);
        GL11.glVertex3f(1.0f, -1.0f, 1.0f);
        GL11.glColor3f(1.0f, 1.0f, 0.0f);
        GL11.glVertex3f(1.0f, -1.0f, -1.0f);
        GL11.glVertex3f(-1.0f, -1.0f, -1.0f);
        GL11.glVertex3f(-1.0f, 1.0f, -1.0f);
        GL11.glVertex3f(1.0f, 1.0f, -1.0f);
        GL11.glColor3f(0.0f, 0.0f, 1.0f);
        GL11.glVertex3f(-1.0f, 1.0f, 1.0f);
        GL11.glVertex3f(-1.0f, 1.0f, -1.0f);
        GL11.glVertex3f(-1.0f, -1.0f, -1.0f);
        GL11.glVertex3f(-1.0f, -1.0f, 1.0f);
        GL11.glColor3f(1.0f, 0.0f, 1.0f);
        GL11.glVertex3f(1.0f, 1.0f, -1.0f);
        GL11.glVertex3f(1.0f, 1.0f, 1.0f);
        GL11.glVertex3f(1.0f, -1.0f, 1.0f);
        GL11.glVertex3f(1.0f, -1.0f, -1.0f);
        GL11.glEnd();
    }

    DisplayMode displayMode;

    private void createWindow() throws Exception {
        Display.setFullscreen(false);
        DisplayMode d[] = Display.getAvailableDisplayModes();
        for (int i = 0; i < d.length; i++) {
            if (d[i].getWidth() == 640 && d[i].getHeight() == 480 && d[i].getBitsPerPixel() == 32) {
                displayMode = d[i];
                break;
            }
        }
        Display.setDisplayMode(displayMode);
        Display.setTitle("Stack Example");
        Display.create();
    }

    private void initGL() {
        GL11.glEnable(GL11.GL_TEXTURE_2D);
        GL11.glShadeModel(GL11.GL_SMOOTH);
        GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        GL11.glClearDepth(1.0);
        GL11.glEnable(GL11.GL_DEPTH_TEST);
        GL11.glDepthFunc(GL11.GL_LEQUAL);

        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();

        GLU.gluPerspective(45.0f, (float) displayMode.getWidth() / (float) displayMode.getHeight(), 0.1f, 100.0f);

        GL11.glEnable(GL11.GL_LIGHTING); // enable lighting
        GL11.glEnable(GL11.GL_LIGHT0); // enable light 0
        GL11.glLightModeli(GL11.GL_LIGHT_MODEL_TWO_SIDE, GL11.GL_TRUE);
        GL11.glEnable(GL11.GL_COLOR_MATERIAL);
        GL11.glColorMaterial(GL11.GL_FRONT_AND_BACK, GL11.GL_AMBIENT_AND_DIFFUSE);

        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);
    }
}

enter image description here enter image description here

I expected lighting to be static if GL11.glLight is used before transformations. I would be very glad for explanation, cause most tutorials I look up use shaders to achieve lighting effect.

1
I'm confused too. I tried using this - relativity.net.au/gaming/java/Lighting.html example, replacing only rendering part - from part to cube - with the same effect.The Raven
Thanks for tip, I will edit the question to include all the code..The Raven

1 Answers

3
votes

The lighting is calculated based on the local surface normal vector of each point at which the light model is to be evaluated.

You do not provide any normal vectors for your cube, so the GL will use the very same normal vector for each and every vertex. As a result, all your cube faces are lighted as if they are facing to the same direction.