3
\$\begingroup\$

I'm trying to enable lighting in lwjgl according to the method described by NeHe and this post. However, no matter what I try, all faces of my shapes always receive the same amount of light, or, in the case of a spinning shape, the amount of lighting seems to oscillate. All faces are lit up by the same amount, which changes as the pyramid rotates. Concrete example (apologies for the length):

The pyramid, dark The pyramid, now lit up after rotating. Note how all panels are always the same brightness.

Note how all panels are always the same brightness, but the brightness varies with the pyramid's rotation.

This is using lwjgl 2.8.3 on Mac OS X.

package com;

import com.zarkonnen.lwjgltest.Main;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.lwjgl.util.glu.*;
import org.lwjgl.input.Keyboard;

import java.nio.FloatBuffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

/**
 *
 * @author penguin
 */
public class main {

    public static void main(String[] args) {
        try {
            Display.setDisplayMode(new DisplayMode(800, 600));
            Display.setTitle("3D Pyramid");
            Display.create();
        } catch (Exception e) {
        }
        initGL();

        float rtri = 0.0f;
        Texture texture = null;
        try {
            texture = TextureLoader.getTexture("png", Main.class.getResourceAsStream("tex.png"));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        while (!Display.isCloseRequested()) {
            // Draw a Triangle :D

            GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);

            GL11.glLoadIdentity();

            GL11.glTranslatef(0.0f, 0.0f, -10.0f);

            GL11.glRotatef(rtri, 0.0f, 1.0f, 0.0f);

            texture.bind();

            GL11.glBegin(GL11.GL_TRIANGLES);

            GL11.glTexCoord2f(0.0f, 1.0f);
            GL11.glVertex3f(0.0f, 1.0f, 0.0f);
            GL11.glTexCoord2f(-1.0f, -1.0f);
            GL11.glVertex3f(-1.0f, -1.0f, 1.0f);
            GL11.glTexCoord2f(1.0f, -1.0f);
            GL11.glVertex3f(1.0f, -1.0f, 1.0f);

            GL11.glTexCoord2f(0.0f, 1.0f);
            GL11.glVertex3f(0.0f, 1.0f, 0.0f);
            GL11.glTexCoord2f(-1.0f, -1.0f);
            GL11.glVertex3f(1.0f, -1.0f, 1.0f);
            GL11.glTexCoord2f(1.0f, -1.0f);
            GL11.glVertex3f(1.0f, -1.0f, -1.0f);

            GL11.glTexCoord2f(0.0f, 1.0f);
            GL11.glVertex3f(0.0f, 1.0f, 0.0f);
            GL11.glTexCoord2f(-1.0f, -1.0f);
            GL11.glVertex3f(-1.0f, -1.0f, -1.0f);
            GL11.glTexCoord2f(1.0f, -1.0f);
            GL11.glVertex3f(1.0f, -1.0f, -1.0f);

            GL11.glTexCoord2f(0.0f, 1.0f);
            GL11.glVertex3f(0.0f, 1.0f, 0.0f);
            GL11.glTexCoord2f(-1.0f, -1.0f);
            GL11.glVertex3f(-1.0f, -1.0f, -1.0f);
            GL11.glTexCoord2f(1.0f, -1.0f);
            GL11.glVertex3f(-1.0f, -1.0f, 1.0f);


            GL11.glEnd();

            GL11.glBegin(GL11.GL_QUADS);
            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();

            Display.update();
            rtri += 0.05f;
            // Exit-Key = ESC
            boolean exitPressed = Keyboard.isKeyDown(Keyboard.KEY_ESCAPE);
            if (exitPressed) {
                System.out.println("Escape was pressed!");
                Display.destroy();

            }
        }

        Display.destroy();
    }

    private static void initGL() {
        GL11.glEnable(GL11.GL_LIGHTING);
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GLU.gluPerspective(45.0f, ((float) 800) / ((float) 600), 0.1f, 100.0f);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glLoadIdentity();

        GL11.glEnable(GL11.GL_TEXTURE_2D);
        GL11.glShadeModel(GL11.GL_SMOOTH);
        GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        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);
        float lightAmbient[] = {0.5f, 0.5f, 0.5f, 1.0f};  // Ambient Light Values
        float lightDiffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};      // Diffuse Light Values
        float lightPosition[] = {0.0f, 0.0f, 2.0f, 1.0f}; // Light Position

        ByteBuffer temp = ByteBuffer.allocateDirect(16);
        temp.order(ByteOrder.nativeOrder());
        GL11.glLight(GL11.GL_LIGHT1, GL11.GL_AMBIENT, (FloatBuffer) temp.asFloatBuffer().put(lightAmbient).flip());              // Setup The Ambient Light
        GL11.glLight(GL11.GL_LIGHT1, GL11.GL_DIFFUSE, (FloatBuffer) temp.asFloatBuffer().put(lightDiffuse).flip());              // Setup The Diffuse Light
        GL11.glLight(GL11.GL_LIGHT1, GL11.GL_POSITION, (FloatBuffer) temp.asFloatBuffer().put(lightPosition).flip());         // Position The Light
        GL11.glEnable(GL11.GL_LIGHT1);                          // Enable Light One
    }
}
\$\endgroup\$
4
\$\begingroup\$

For lighting to work, every vertex needs a normal. What seems to be the case right now is that all of your vertices have the same normal, which is why all the faces are getting the same amount of light.

To calculate the normal for a triangle, take the cross-product using two of its sides and normalize it. However, this will produce hard edges, which are not always desirable. In that case, you calculate normals per-vertex. This is done by adding all of the face normals of the triangles that share the vertex together an normalizing the vector sum.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.