Java JFrame+;画布:为什么调用glViewport时会出现NUllPointerException?
我已经创建了一个带有画布的JFrame,如下面的代码所示。我试图做的是在屏幕大小更新时调整openGL上下文的大小。这应该和调用glViewport()一样简单,我正在名为resize()的事件处理程序中执行此操作。然而,这导致:Java JFrame+;画布:为什么调用glViewport时会出现NUllPointerException?,java,swing,opengl,awt,lwjgl,Java,Swing,Opengl,Awt,Lwjgl,我已经创建了一个带有画布的JFrame,如下面的代码所示。我试图做的是在屏幕大小更新时调整openGL上下文的大小。这应该和调用glViewport()一样简单,我正在名为resize()的事件处理程序中执行此操作。然而,这导致: Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at org.lwjgl.opengl.GL11.glViewport(GL11.java:3199) at gltest.Ga
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,1100,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);
}
}
您应该从主线程执行所有显示操作。如果您查看在另一个问题中发布的示例,您可以看到新的画布大小被存储,然后由主线程更新。这也很安全。您需要这样做,然后在图形初始化后有一个循环,如下所示:
while (!closeRequested) {
GL11.glViewport(0, 0, dim.width, dim.height);
Display.update();
}
//finished
Display.destroy();
最有可能的情况是,您在opengl初始化之前收到了第一个调整大小事件。移动canvas.addComponentListener(适配器)代码>在OpenGL设置之后