我在JavaFX场景中使用JOGL画布/面板有问题。我的假设是,如果JOGL GLCanvas坚持awt.Canvas合同,那么将其放在JFX场景中就没有问题了。
我收集了以下代码(所有片段都在JFX应用程序中::start)。
第一次创建JOGL "hello world“(脉动背景只是为了查看事物是否呈现和移动):
GLCanvas glCanvas = new GLCanvas();
glCanvas.setSize(size-10, size-10);
glCanvas.addGLEventListener(new GLEventListener() {
private final long t0 = System.currentTimeMillis();
@Override
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {}
@Override
public void init(GLAutoDrawable drawable) {
new Thread(() -> {while (true) glCanvas.display();}).start();
}
@Override
public void dispose(GLAutoDrawable drawable) {}
@Override
public void display(GLAutoDrawable drawable) {
GL4 gl = drawable.getGL().getGL4();
float t = (float)(Math.sin((System.currentTimeMillis()-t0)/1000f)+1)/2f;
gl.glClearColor(t, 1-t, 0, 1);
gl.glClear(GL4.GL_COLOR_BUFFER_BIT);
}
});
GLJPanel glPanel = new GLJPanel();
glPanel.add(glCanvas);
glPanel.setBackground(Color.BLUE);替代hello world (没有移动,这显然有效):
Canvas awtCanvas = new Canvas() {
@Override
public void paint(Graphics g) {g.fillRect(0, 0, getWidth(), getHeight());}
};
awtCanvas.setSize(size-10, size-10);
JPanel swingPanel = new JPanel();
swingPanel.add(awtCanvas);
swingPanel.setBackground(Color.BLUE);和测试代码--把东西组合在一起:
if (jfx) {
SwingNode swingNode = new SwingNode();
swingNode.setContent(swingPanel);
primaryStage.setScene(new Scene(new Group(swingNode), size, size+30));
primaryStage.show();
} else {
JFrame frame = new JFrame();
frame.setSize(size, size+30);
frame.add(swingPanel);
frame.setVisible(true);
}参考解决方案JFrame(Panel(画布()、JFrame(JPanel(GLCanvas()和JFrame(GLJPanel(GLCanvas()按预期工作(某种程度上,GLPanel似乎忽略了背景色设置)。
当我尝试非JOGL包装阶段(场景(组(JPanel(画布(),作品如预期(JFX )。
现在对于JOGL来说,包装器Stage(Scene(Group(JPanel(GLJPanel(GLCanvas()))))会产生黑色的画布内容。包装阶段(场景(Group( JPanel (GLCanvas()(跳过使用GLJPanel)不会为画布内容生成黑色方块,而对于JPanel,我只得到蓝色方块。
我在互联网上发现的唯一提到是2012/2013年,似乎不起作用(但似乎SwingNode当时也不存在),2016年在JOGL论坛上,链接到bugzzila的死链接。
发布于 2018-10-11 18:25:47
出于完全的绝望,试图使用GLJPanel而不是GLCanvas,而且它很有效。说大也大吧。
SwingNode调整大小存在问题--它有一个不允许轻松调整大小的错误(OracleJDK在相当长的时间内都有这个错误,OpenJDK似乎已经解决了)
建议的调整大小问题的解决方案是在场景中放置宽度/高度属性侦听器,并在每次大小更改时重新插入画布:
Dimension dim = new Dimension((int)scene.getWidth(), (int)scene.getHeight());
ChangeListener<Number> stageSizeListener = (obs, prev, next) -> {
dim.setSize(scene.getWidth(), scene.getHeight());
component.setSize(dim);
swingNode.setContent(swingPanel);
};
scene.heightProperty().addListener(stageSizeListener);
scene.widthProperty().addListener(stageSizeListener);这适用于问题中的代码,但每个重新插入触发器dispose(GL)和init(GL)循环可能对某些应用程序都是可行的,而在我的情况下则不然。
决定做一些小黑客,使GLJPanel的最大允许的分辨率(比如说4K,我首先呈现到屏幕缓冲区),以理想的分辨率呈现,在面板的左上角闪现结果,并在JFX场景中将面板剪裁到相同的分辨率。
正如tomsontom所提到的那样,性能并不是很好,GLJPanel本身比GLCanvas慢得多(从800 gets到4K的40 gets),而在SwingNode中则变得更糟(4K时为17 gets)。将尽可能推迟JFX的使用,希望它们要么在即将与JDK分离的时候修复SwingNode,要么甚至得到DirectRenderingNode。
https://stackoverflow.com/questions/52728560
复制相似问题