JFrame + Canvas: почему я получаю NUllPointerException при вызове glViewport? - PullRequest
0 голосов
/ 11 марта 2011

Я создал JFrame с холстом, как вы можете видеть в коде ниже.Я пытаюсь изменить размер контекста openGL при обновлении размера экрана.Это должно быть так же просто, как вызов glViewport (), который я делаю в обработчике событий под названием resize ().Это, однако, приводит к этому:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at org.lwjgl.opengl.GL11.glViewport(GL11.java:3199)
at gltest.GameMain.resize(GameMain.java:149)
at gltest.GameMain$1.componentResized(GameMain.java:59)
(...)

Я совершенно не в курсе.Границы, возвращаемые по размеру холста, кажутся нормальными, но как только я использую их в окне просмотра, они выдают ошибки.То же самое происходит, когда я вместо этого делаю вызов области просмотра как "glViewport (1, 1, 100, 100)".Все эти значения находятся в пределах границ окна, но все же он выдает те же исключения nullPointerException, когда я изменяю размер окна.

У меня нет идей и энергии, чтобы выяснить, почему (я гуглю уже 3 часа, безрезультатно).Что я делаю не так?

import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.GraphicsConfiguration;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

import javax.swing.JFrame;

import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;

import static org.lwjgl.util.glu.GLU.*;
import static org.lwjgl.opengl.GL11.*;

public class GameMain {
    public JFrame frame;
    public Canvas canvas;

    public boolean initialize(int width, int height) {
        try {
            Canvas canvas = new Canvas();
            JFrame frame = new JFrame("Open Rock Raiders - Delta");
            this.canvas = canvas;
            this.frame = frame;
            ComponentAdapter adapter = new ComponentAdapter() {
                public void componentResized(ComponentEvent e) {
                    resize();
                }
            };

            canvas.addComponentListener(adapter);
            canvas.setIgnoreRepaint(true);
            frame.setSize(640, 480);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(canvas);
            frame.setVisible(true);
            Dimension dim = this.canvas.getSize();

            Display.setLocation(100, 100);
            Display.setTitle("GL Window");
            Display.setDisplayMode(new DisplayMode(dim.width, dim.height));
            Display.setParent(canvas);
            Display.create();

            //openGL setup
            glViewport(0, 0, dim.width, dim.height);
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            gluPerspective(60.0f, (float)(dim.width/dim.height), 0.1f, 10000.0f);
            glMatrixMode(GL_MODELVIEW);
            glClearColor(94.0f/255.0f, 161.0f/255.0f, 255.0f/255.0f, 0.5f);
            glClearDepth(1.0);
            glShadeModel(GL_FLAT);
            glEnable(GL_DEPTH_TEST);
            glDepthFunc(GL_LEQUAL);
            glEnable(GL11.GL_CULL_FACE); 
            glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
            glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        } catch (LWJGLException le) {
            le.printStackTrace();
        }
        return false;
    }

    public void resize()
    {
        Dimension dim = this.canvas.getSize();
        GL11.glViewport(0, 0, dim.width, dim.height);
    }
}

Ответы [ 2 ]

1 голос
/ 11 марта 2011

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

while (!closeRequested) {
    GL11.glViewport(0, 0, dim.width, dim.height);
    Display.update();
}

//finished
Display.destroy();
0 голосов
/ 11 марта 2011

Скорее всего, вы получаете первое событие изменения размера до инициализации opengl. Переместите canvas.addComponentListener(adapter); после настройки OpenGL.

...