2011-03-10 31 views
0

我已經創建了一個帶有畫布的JFrame,就像您可以在下面的代碼中看到的一樣。我想要做的是在屏幕大小更新時調整openGL上下文的大小。這應該像調用glViewport()一樣簡單,我在調用resize()的事件處理函數中執行此操作。然而,結果如下:JFrame + Canvas:爲什麼在調用glViewport時遇到NUllPointerException?

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)」這樣的視口調用時,會發生同樣的情況。所有這些值都在窗口的邊界內,但是當我調整窗口大小時,它仍會拋出非常相同的nullPointerExceptions。

我沒有想法和精力來弄清楚爲什麼(我一直在用谷歌搜索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); 
    } 
} 

回答

1

您應該從主線程完成所有顯示操作。如果您查看您在其他問題中發佈的示例,則可以看到新的畫布大小已存儲,然後由主線程更新。它也完成了線程安全。你需要做的,然後讓你的顯卡初始化這樣的事情之後,一個循環:

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

//finished 
Display.destroy(); 
0

最有可能你得到的第一個調整大小事件之前的OpenGL被初始化。在OpenGL安裝程序之後移動canvas.addComponentListener(adapter);

相關問題