gpt4 book ai didi

java - 慢速双缓冲方法

转载 作者:行者123 更新时间:2023-12-01 11:13:44 25 4
gpt4 key购买 nike

我一直在尝试在我的游戏库中实现双缓冲,但它比没有它时慢得多。

这是我实现它的类。基本上,它绘制到图像上,然后将图像绘制到 JPanel 的图形 (pg) 上。

public abstract class DrawingPanel extends GameLoop {

private BufferedImage image;
private Graphics2D ig;
private Graphics pg;

private int backgroundRGB;

public DrawingPanel(final int fps, final int ups, final JPanel panel, final Color background) {
super(fps, ups);
initialize(panel, background);
}

/**
* Creates a panel with 60 fps and 120 ups
*
* @param panel
* @param background
*/
public DrawingPanel(final JPanel panel, final Color background) {
this(60, 120, panel, background);
}

public DrawingPanel(final JPanel panel) {
this(panel, Color.WHITE);
}

public DrawingPanel(final int ups, final JPanel panel, final Color background) {
super(ups);
initialize(panel, background);
}

private void initialize(final JPanel panel, final Color background) {
image = GraphicsUtils.createImage(panel.getWidth(), panel.getHeight(), Transparency.OPAQUE);
ig = (Graphics2D) image.getGraphics();
pg = panel.getGraphics();
GraphicsUtils.prettyGraphics(ig);
backgroundRGB = background.getRGB();

panel.addMouseListener(this);
panel.addMouseMotionListener(this);
panel.addKeyListener(this);
panel.addMouseWheelListener(this);

panel.setFocusable(true);
panel.requestFocusInWindow();
}

@Override
public void draw() {
// set background
Arrays.fill(((DataBufferInt) image.getRaster().getDataBuffer()).getData(), backgroundRGB);

// draw on the buffer
draw(ig);
// draw our buffer to the screen
pg.drawImage(image, 0, 0, null);
}

public abstract void draw(Graphics2D g);

}

结果:measurement one这意味着 25% - 6% = 19% 的时间花在了绘制方法上!

我以为这可能是我使用了Array.fill的事实,但事实证明这并不是一个无用的“过早优化”;如果我用

替换该行
ig.setColor(backgroundColor);
ig.fillRect(0, 0, image.getWidth(), image.getHeight());

所需的时间甚至更长:26 - 5% = 21%。有什么办法可以加快这个方法的速度吗?

顺便说一下,GraphicsUtils.createImage 从我的 GraphicsConfiguration 创建了一个兼容的图像。

整个库是on github ,如果您想查看整个代码。

最佳答案

这不是 Swing 中绘画的工作方式 -> pg = panel.getGraphics(); 这是一个非常糟糕的主意。您正在 Swing 的被动渲染引擎和尝试绘制组件的“快照”之间进行斗争。

当您正确使用 Swing 组件时,它们会在内部进行双缓冲,但是您需要使用 API。

首先查看 Performing Custom PaintingPainting in AWT and Swing有关 Swing 中绘画工作原理的更多详细信息

基本上,发生的情况是,您正在使用 getGraphics 的结果来绘制面板,RepaintManager 出现并决定需要更新您的组件,并且重新绘制它,这会产生一个空白面板,重复速度非常快。这就是导致你闪烁的原因。在 Swing 中,您无法控制绘制过程,您只能要求在发生绘制周期时收到通知(例如覆盖 paintComponent)并向绘制系统发出应该发生重绘的请求,但是由绘画系统实际决定绘画周期何时发生。

相反,首先重写面板的 paintComponent 方法并在其中执行所有自定义绘制。使用repaint请求更新组件。

如果您“确实”需要主动绘画过程,请查看 BufferStrategyBufferStrategy and BufferCapabilities ,它为您提供了直接控制何时将输出推送到屏幕设备的方法。

关于java - 慢速双缓冲方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32084097/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com