JavaFX中的joglcanvas

JavaFX中的joglcanvas,java,swing,javafx,awt,jogl,Java,Swing,Javafx,Awt,Jogl,在JavaFX场景中获取JOGL画布/面板时遇到问题。我的假设是,若JoglCanvas遵守awt.Canvas的合同,那个么将其放置在JFX场景中应该并没有问题 我收集了以下代码(所有代码片段都在JFX Application::start中) JOGL“hello world”的首次创建(脉动背景,仅用于查看事物是否渲染和移动): 备选hello world(无需移动,这显然有效): 和测试代码,将所有内容组合在一起: if (jfx) { SwingNode swingNode =

在JavaFX场景中获取JOGL画布/面板时遇到问题。我的假设是,若JoglCanvas遵守awt.Canvas的合同,那个么将其放置在JFX场景中应该并没有问题

我收集了以下代码(所有代码片段都在JFX Application::start中)

JOGL“hello world”的首次创建(脉动背景,仅用于查看事物是否渲染和移动):

备选hello world(无需移动,这显然有效):

和测试代码,将所有内容组合在一起:

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(Canvas())、JFrame(JPanel(GLCanvas()))和JFrame(GLJPanel(GLCanvas()))按预期工作(GLPanel似乎忽略了背景色设置)

当我尝试非JOGL包装阶段(场景(组(JPanel)(Canvas()))时,工作正常(JFX工作)

现在对于JOGL,包装器阶段(场景(组(JPanel)(GLJPanel(GLCanvas()))在画布内容应该是的地方生成黑色。包装器阶段(场景(组(JPanel)(GLCanvas()))(跳过使用GLJPanel)不会为画布内容生成黑色方块,我只为JPanel生成蓝色方块


我在互联网上发现的唯一提及的是2012/2013年,在那里它似乎不起作用(但当时似乎也不存在SwingNode),以及2016年在JOGL论坛上链接到bugzzila的dead link。

出于绝望,我尝试使用GLJPanel而不是GLCanvas,它起了作用。有点像

SwingNode resize有一个问题-它有一个不允许轻松调整大小的bug(这个bug已经存在了很长一段时间,似乎已经解决了)

调整大小问题的建议解决方案是将“宽度/高度”属性侦听器放置在场景中,并在每次大小更改时重新插入画布:

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);
Dimension dim=新维度((int)scene.getWidth(),(int)scene.getHeight());
ChangeListener stageSizeListener=(obs、上一个、下一个)->{
dim.setSize(scene.getWidth(),scene.getHeight());
组件设置大小(dim);
swingNode.setContent(swingPanel);
};
scene.heightProperty().addListener(stageSizeListener);
scene.widthProperty().addListener(stageSizeListener);
这适用于问题中的代码,但每个重新插入触发器都会触发dispose(GL)和init(GL)循环,这对于某些应用程序来说可能是正常的,但在我的情况下不是这样

决定做一点修改,使GLJPanel的大小达到允许的最大分辨率(比如4K,我还是先渲染到屏幕外缓冲区),以所需的分辨率渲染,在面板左上角显示结果,并将JFX场景中的面板剪切到相同的分辨率


正如tomsontom所提到的,性能并不是很好,GLJPanel本身要比GLCanvas慢得多(4K时从800FPS到40FPS),而在SwingNode中性能更差(4K时为17FPS)。将尽可能推迟JFX的使用,希望他们在即将与JDK分离的过程中修复SwingNode,或者甚至获得DirectRenderingNode。

即使它可以工作,性能也会非常差。JavaFX需要的真正解决方案是获得DirectRendering Node,您可以使用任何技术进行绘制nt绘制(JOGL、LWJGL、Native等)。目前正在讨论如何实现这样一个节点,因此请订阅openjfx邮件列表(或者您可能希望关注我的博客),看看这是否会实现,而尝试一下NewtCanvasJFX(自JOGL 2.4以来):真正的问题在我们的bug追踪器中得到了解释,OpenJFX/JavaFX没有Java AWT本机接口的等价物,它阻止我们实现一个持久的解决方案,而我们为AWT、SWT和Swing实现了这个解决方案。@gouessej到2020年这一切都改变了吗?让JOGL与JavaFX一起工作。@BAR是的,JOGL>=2.4.0更好com.jogamp.newt.javafx.NewtCanvasJFX,但仍有一些限制。顺便说一句,如果您有JOGL特定的问题要问,请在我们的官方论坛上提问,因为StackOverflow上只有很少的贡献者。我忘了提到这一点:
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);
}
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);