2011-12-21 54 views
3

我有一個帶有GLCanvas的JFrame。當我調用JFrame的Component.printAll()方法,然後將Graphics2D對象打印到PNG文件(使用BufferedImage和ImageIO.write())時,那麼printAll()方法沒有抓住GLCanvas。 JFrame在png圖像上,但GLCanvas全是灰色的。JOGL:使用Component.printAll()在JFrame中截取GLCanvas不起作用

我錯過了什麼?

重現問題的示例代碼。運行代碼後查看生成的名爲「image.png」的png文件。你會看到除GLCanvas以外的所有東西。創建圖像的代碼片段位於構造函數的底部。

import com.sun.opengl.util.Animator; 
import java.awt.Graphics2D; 
import java.awt.event.*; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import java.util.logging.*; 
import javax.imageio.ImageIO; 
import javax.media.opengl.*; 
import javax.media.opengl.glu.GLU; 
import javax.swing.JFrame; 

public class JOGLTest implements GLEventListener { 

    GLU glu = new GLU(); 
    JFrame frame = new JFrame("JOGL"); 
    GLCanvas canvas = new GLCanvas();  
    public static void main(String[] args) { 
     JOGLTest joglTest = new JOGLTest(); 
    } 

    public JOGLTest() { 
     canvas.addGLEventListener(this); 
     frame.add(canvas); 
     frame.setSize(500, 500); 
     final Animator animator = new Animator(canvas); 
     frame.addWindowListener(new WindowAdapter() { 

      @Override 
      public void windowClosing(WindowEvent e) { 
       new Thread(new Runnable() { 

        public void run() { 
         animator.stop(); 
         System.exit(0); 
        } 
       }).start(); 
      } 
     }); 

     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 

     animator.start(); 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException ex) { 
      Logger.getLogger(JOGLTest.class.getName()).log(Level.SEVERE, null, ex); 
     } 

     BufferedImage image = new BufferedImage(frame.getWidth(), frame.getHeight(), BufferedImage.TYPE_INT_RGB);   
     Graphics2D g = image.createGraphics();   
     frame.printAll(g);   
     image.flush(); 

     try { 
      ImageIO.write(image, "png", new File("image.png")); 
     } catch (IOException ex) { 
      Logger.getLogger(JOGLTest.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 

    public void init(GLAutoDrawable drawable) { 
     GL gl = drawable.getGL(); 
     gl.setSwapInterval(1); 
     gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
     gl.glShadeModel(GL.GL_SMOOTH); 
    } 

    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { 
     GL gl = drawable.getGL(); 
     GLU glu = new GLU(); 
     if (height <= 0) {   
      height = 1; 
     } 
     final float h = (float) width/(float) height; 
     gl.glViewport(0, 0, width, height); 
     gl.glMatrixMode(GL.GL_PROJECTION); 
     gl.glLoadIdentity(); 
     glu.gluPerspective(20.0f, h, 1.0, 550.0); 
     gl.glMatrixMode(GL.GL_MODELVIEW); 
     gl.glLoadIdentity(); 
    } 

    private int eyeX = 0; 
    private int eyeY = 0; 
    private int eyeZ = 130; 
    private int centerX = 0;  

    public void display(GLAutoDrawable drawable) { 
     GL gl = drawable.getGL(); 
     gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); 
     gl.glLoadIdentity(); 
     glu.gluLookAt(eyeX, eyeY, eyeZ, centerX, 0.0, 0.0, 0.0, 1.0, -0.0); 
     gl.glBegin(GL.GL_LINES); 
     gl.glVertex2d(1, 1); 
     gl.glVertex2d(20, 20); 
     gl.glEnd(); 
     gl.glFlush(); 
    } 
    public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) { 
    } 
} 
+0

我的openGL中缺少了很多常量。例如我看不到GL.GL_PROJECTION .....你可以指定你的版本 – jayunit100 2011-12-27 01:32:13

回答

4

使用GLJPanel代替GLCanvas中:

GLJPanel panel = new GLJPanel(); 

然後只是panel更換您canvas變量,它應該工作。在擺動組件內使用時,GLCanvas有時會導致兼容性問題。

從GLCanvas中API頁面:

GLJPanel是爲了與Swing用戶接口的兼容性,當添加一個重量級的要麼是因爲Z排序或佈局管理問題不能正常工作。