Как исправить вращающееся освещение с моделью? - PullRequest
1 голос
/ 24 марта 2019

Моя цель - создать маленькую сцену с освещением. Однако освещение, кажется, вращается вместе с моим визуализированным объектом (тестовым кубом).

В большинстве ответов, которые я прочитал, я должен использовать GL11.glLight в режиме проекции и матричного режима, я предположил. Пожалуйста, поправьте меня, если я ошибаюсь. Тем не менее, результат заключается в том, что освещение работает, но его интенсивность зависит от вращения куба.

Вот мой пример, подготовленный для стека:

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

Я ожидал, что освещение будет статическим, если GL11.glLight используется до преобразований. Я был бы очень рад за объяснения, потому что большинство учебных пособий, которые я смотрю, используют шейдеры для достижения эффекта освещения.

1 Ответ

3 голосов
/ 25 марта 2019

Освещение рассчитывается на основе локального вектора нормали поверхности каждой точки, в которой должна оцениваться модель освещения.

Вы не предоставляете никаких нормальных векторов для своего куба,поэтому GL будет использовать тот же самый нормальный вектор для каждой вершины.В результате все ваши грани куба подсвечиваются, как если бы они смотрели в одном направлении.

...