如何将抗锯齿应用于像GraphicsContext.fillArc()这样的javafx方法? [英] How to apply antialiasing to javafx methods like GraphicsContext.fillArc()?

查看:427
本文介绍了如何将抗锯齿应用于像GraphicsContext.fillArc()这样的javafx方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是javafx的新手,我正在使用其渲染功能编写游戏,特别是 GraphicsContext.fillArc()等在eclipse中。

I am new to javafx, and I'm programming a game using its rendering functions, specifically, GraphicsContext.fillArc() and the like in eclipse.

这是我目前的代码:

        BorderPane root = new BorderPane();

        Scene scene = new Scene(root, 400, 400);
        primaryStage.setScene(scene);
        scene.getStylesheets()
                .add(getClass().getResource("application.css").toExternalForm());

        Canvas canvas = new Canvas(400, 400);
        root.getChildren().add(canvas);

        GraphicsContext gc = canvas.getGraphicsContext2D();
        new AnimationTimer()
        {
            public void handle(long currentNanoTime)
            {
                gc.setFill(Color.BLUE);
                gc.fillArc(150, 150, 100, 100, 0, 240, ArcType.ROUND);
            }
        }.start();
        primaryStage.show();

然而 fillArc()方法呈现一个我的屏幕上的形状有粗糙的边缘。我想要应用抗锯齿,以便边缘平滑。但是我在 GraphicsContext 类中找不到任何相关方法,并将 scene 的实例化更改为新场景(root,400,400,false,SceneAntialiasing.BALANCED); 也没有效果。所以我的问题是如何在 GraphicsContext.fillArc()上实现抗锯齿,或者它是否从根本上可行?

However the fillArc() method renders a shape on my screen with ragged edges. I want antialiasing to be applied so that the edges are smoothed. However I cannot find any related methods in GraphicsContext class, and changing the instantiation of scene to new Scene(root, 400, 400, false, SceneAntialiasing.BALANCED); has no effect as well. So my question is how to achieve antialiasing on GraphicsContext.fillArc() or whether it's fundamentally possible?

我也是一般来说,javafx和cgi都是新手,所以欢迎任何建议和建议。

Also I'm very new to javafx and cgi in general, so any suggestions and recommendations are welcomed.

更新:

正如@jewelsea所建议的,当代码块 gc.setFill(Color.BLUE);
gc.fillArc(150,150,100,100,0,240,ArcType.ROUND);
放在 AnimationTimer ,渲染图像是抗锯齿的。我们都不知道为什么到现在为止。仅供参考。

As suggested by @jewelsea, when the code block gc.setFill(Color.BLUE); gc.fillArc(150, 150, 100, 100, 0, 240, ArcType.ROUND); is placed outside of the anonymous subclass of AnimationTimer, the rendered image is antialiased. Neither of us can figure out why as of now. FYI.

推荐答案

我在玩 Canvas 时遇到了类似的问题和 AnimationTimer 。解决方案的一个重要关键是发布的评论by @jewelsea

I encountered a similar problem while playing around with Canvas and AnimationTimer. An important key to the solution is the comment posted by @jewelsea:


...如果您注释掉动画计时器并且只绘制弧线而没有它,那么弧很好地抗锯齿......

这基本上意味着,如果我们绘制弧<强>曾经它是抗锯齿的。但是如果我们在 AnimationTimer handle()方法中绘制它,则每秒绘制60次。将长睡眠添加到 handle()方法后,可以更好地看到结果。第一次在白色背景上渲染圆圈并按需要显示。第二次在前一个蓝色圆圈的顶部渲染一个蓝色圆圈。由于抗锯齿而部分呈蓝色的像素变得更暗。第三次绘制圆时会发生同样的情况,依此类推。下图显示了1,2,3,4,5,10和50次迭代后弧的放大部分:

This basically means, if we draw the arc once it is antialiased. But if we draw it in the handle() method of the AnimationTimer, it is drawn 60 times per second. The results can be seen better after adding a long sleep to the handle() method. The first time the circle is rendered on a white background and looks as desired. The second time a blue circle is rendered on top of the previous blue circle. The pixels which were colored partially blue because of antialiasing, become darker. The same happens when the circle is drawn the third time, and so on. The following image shows a magnified portion of the arc after 1, 2, 3, 4, 5, 10, and 50 iterations:

问题的一个简单解决方案是在渲染任何内容之前用画布填充背景颜色:

A simple solution to the problem is to fill the canvas with the background color, before rendering anything:

public void handle(long currentNanoTime) {
    gc.setFill(Color.WHITE);
    gc.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());

    gc.setFill(Color.BLUE);
    gc.fillArc(150, 150, 100, 100, 0, 240, ArcType.ROUND);
}

这篇关于如何将抗锯齿应用于像GraphicsContext.fillArc()这样的javafx方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆