首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JavaFX中的JOGL画布

JavaFX中的JOGL画布
EN

Stack Overflow用户
提问于 2018-10-09 20:07:06
回答 1查看 1.2K关注 0票数 2

我在JavaFX场景中使用JOGL画布/面板有问题。我的假设是,如果JOGL GLCanvas坚持awt.Canvas合同,那么将其放在JFX场景中就没有问题了。

我收集了以下代码(所有片段都在JFX应用程序中::start)。

第一次创建JOGL "hello world“(脉动背景只是为了查看事物是否呈现和移动):

代码语言:javascript
复制
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 (没有移动,这显然有效):

代码语言:javascript
复制
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);

和测试代码--把东西组合在一起:

代码语言:javascript
复制
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的死链接。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-10-11 18:25:47

出于完全的绝望,试图使用GLJPanel而不是GLCanvas,而且它很有效。说大也大吧。

SwingNode调整大小存在问题--它有一个不允许轻松调整大小的错误(OracleJDK在相当长的时间内都有这个错误,OpenJDK似乎已经解决了)

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

代码语言:javascript
复制
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。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52728560

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档