如何将抗锯齿应用于 GraphicsContext.fillArc() 之类的 javafx 方法?
How to apply antialiasing to javafx methods like GraphicsContext.fillArc()?
我是 javafx 的新手,我正在使用它的渲染功能编写游戏,具体来说,GraphicsContext.fillArc()
以及 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
class中找不到任何相关方法,并且将scene
的实例化更改为new Scene(root, 400, 400, false, SceneAntialiasing.BALANCED);
也没有效果。所以我的问题是如何在 GraphicsContext.fillArc()
上实现抗锯齿,或者它是否从根本上可行?
此外,我对 javafx 和 cgi 总体上还很陌生,因此欢迎提出任何建议。
更新:
正如@jewelsea 所建议的,当代码块 gc.setFill(Color.BLUE);
gc.fillArc(150, 150, 100, 100, 0, 240, ArcType.ROUND);
放置在 AnimationTimer
的匿名子 class 之外时,渲染的图像是抗锯齿的。我们现在都不知道为什么。仅供参考。
我在玩 Canvas
和 AnimationTimer
时遇到了类似的问题。解决方案的一个重要关键是 :
"... if you comment out the animation timer and just draw the arc without it, then the arc is nicely antialiased ..."
这基本上意味着,如果我们绘制圆弧 一次 它是抗锯齿的。但是如果我们在AnimationTimer
的handle()
方法中绘制,每秒绘制60次。在handle()
方法中加入long sleep后可以更好的看到结果。第一次在白色背景上呈现圆圈并按预期显示。第二次在前一个蓝色圆圈之上呈现一个蓝色圆圈。由于抗锯齿而部分着色为蓝色的像素变得更暗。第三次画圆时也是如此,以此类推。下图显示了经过 1、2、3、4、5、10 和 50 次迭代后圆弧的放大部分:
该问题的一个简单解决方案是在渲染任何内容之前用背景颜色填充 canvas:
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);
}
我是 javafx 的新手,我正在使用它的渲染功能编写游戏,具体来说,GraphicsContext.fillArc()
以及 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
class中找不到任何相关方法,并且将scene
的实例化更改为new Scene(root, 400, 400, false, SceneAntialiasing.BALANCED);
也没有效果。所以我的问题是如何在 GraphicsContext.fillArc()
上实现抗锯齿,或者它是否从根本上可行?
此外,我对 javafx 和 cgi 总体上还很陌生,因此欢迎提出任何建议。
更新:
正如@jewelsea 所建议的,当代码块 gc.setFill(Color.BLUE);
gc.fillArc(150, 150, 100, 100, 0, 240, ArcType.ROUND);
放置在 AnimationTimer
的匿名子 class 之外时,渲染的图像是抗锯齿的。我们现在都不知道为什么。仅供参考。
我在玩 Canvas
和 AnimationTimer
时遇到了类似的问题。解决方案的一个重要关键是
"... if you comment out the animation timer and just draw the arc without it, then the arc is nicely antialiased ..."
这基本上意味着,如果我们绘制圆弧 一次 它是抗锯齿的。但是如果我们在AnimationTimer
的handle()
方法中绘制,每秒绘制60次。在handle()
方法中加入long sleep后可以更好的看到结果。第一次在白色背景上呈现圆圈并按预期显示。第二次在前一个蓝色圆圈之上呈现一个蓝色圆圈。由于抗锯齿而部分着色为蓝色的像素变得更暗。第三次画圆时也是如此,以此类推。下图显示了经过 1、2、3、4、5、10 和 50 次迭代后圆弧的放大部分:
该问题的一个简单解决方案是在渲染任何内容之前用背景颜色填充 canvas:
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);
}