Java2D 绘图闪烁

发布于 2024-12-27 21:14:04 字数 1136 浏览 0 评论 0原文

我正在开发 GameBoy 模拟器并使用 Java2D 进行绘图。然而,我当前的绘图方法在我的 Linux 机器上导致了很多闪烁。我朋友的 Mac 上不存在这种闪烁。

我应该先解释一下 GameBoy 上的图形。 GameBoy 不维护要绘制的像素数据数组,而是具有要渲染的精灵和图块数据的列表。内存中还有一个字节,其中包含正在渲染的垂直线的当前 x 坐标。

因为我需要监视正在绘制的内容的当前 x 位置,所以我认为绘制所有内容的最佳方法是循环遍历所有图块和精灵,将它们渲染到 BufferedImage,然后遍历此 BufferedImage 并将其绘制为像素按像素计算,同时使用当前 x 坐标更新内存中的点。

这是我的代码:

@Override
public void paint(Graphics graphics) {
    super.paint(graphics);
    Graphics2D g = (Graphics2D) graphics;
    BufferedImage secondBuffer = new BufferedImage(160, 144, BufferedImage.TYPE_INT_RGB);
    Graphics2D bg = secondBuffer.createGraphics();

    display.draw(ram, buffer.createGraphics());
    for (int y = 0; y < 144; y++) {
        for (int x = 0; x < 160; x++) {
            bg.setPaint(new Color(buffer.getRGB(x, y)));
            bg.drawLine(x, y, x, y);
            ram.getMemory().put(Ram.LY, (byte) x);
        }
    }

    bg.dispose();
    g.drawImage(secondBuffer, null, 0, 0);

    cpu.setInterrupt(Cpu.VBLANK);
}

我不是 Java2D 专家,因此可能存在我不熟悉的情况。我无法弄清楚为什么这是代码导致闪烁。

编辑:我使用 OpenJDK 可能相关,也可能不相关。我听说它有一些图形问题,但我不知道这是否是原因。

I am working on a GameBoy emulator and using Java2D for drawing. However my current method of drawing is causing a lot of flickering on my Linux machine. This flickering is not present on my friend's Mac.

I should explain graphics on the GameBoy a bit first. The GameBoy does not maintain an array of pixel data to be drawn, but instead has a list of sprite and tile data that is rendered. There is also a byte in memory that contains the current x coordinate of the vertical line that is being rendered.

Because I need to monitor the current x position of what is being drawn, I figured that the best way to draw everything was to loop through all the tiles and sprites, rendering them to a BufferedImage, and then go through this BufferedImage and plot it pixel by pixel while updating the spot in memory with the current x coordinate.

Here is my code:

@Override
public void paint(Graphics graphics) {
    super.paint(graphics);
    Graphics2D g = (Graphics2D) graphics;
    BufferedImage secondBuffer = new BufferedImage(160, 144, BufferedImage.TYPE_INT_RGB);
    Graphics2D bg = secondBuffer.createGraphics();

    display.draw(ram, buffer.createGraphics());
    for (int y = 0; y < 144; y++) {
        for (int x = 0; x < 160; x++) {
            bg.setPaint(new Color(buffer.getRGB(x, y)));
            bg.drawLine(x, y, x, y);
            ram.getMemory().put(Ram.LY, (byte) x);
        }
    }

    bg.dispose();
    g.drawImage(secondBuffer, null, 0, 0);

    cpu.setInterrupt(Cpu.VBLANK);
}

I am not an expert with Java2D, so there could be something going on under the hood that I am not familiar with. I cannot figure out why this is code is causing flickering.

EDIT: It may or may not be relevant that I am using OpenJDK. I have heard that it has some graphical issues, but I do not know if that is the cause.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

笑红尘 2025-01-03 21:14:04

当我在 swing 中遇到奇怪的图形问题时,几乎总是因为我在操作数据对象的同时 swing 试图渲染它们。解决此并发问题的最简单方法是使用 SwingUtilities.invokeLater()。下面的示例代码将在 swing 线程内调用,而不是在应用程序的主线程内调用。

SwingUtilities.invokeLater(new Runnable() {
        public void run() {
        CHANGE DATA STRUCTURES HERE
        }});

由于操作系统依赖于线程行为,这些问题在每台计算机上表现得不同。有关详细信息,请参阅:

http://docs.oracle.com/javase/教程/uiswing/concurrency/initial.html

When I experience weird graphics issues with swing it's almost always because I am manipulating data objects at the same time swing is trying to render them. The easiest way to get around this concurrency issue is by using SwingUtilities.invokeLater(). The example code below will be invoked inside the swing thread and not your application's main thread.

SwingUtilities.invokeLater(new Runnable() {
        public void run() {
        CHANGE DATA STRUCTURES HERE
        }});

Due to how OS dependent thread behavior is these problems manifest themselves different on each computer. For more information see:

http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html

绻影浮沉 2025-01-03 21:14:04

我发现了这个问题。我犯了一个愚蠢的错误,将 AWT 和 Swing 混合在一起,因为我不怎么使用 GUI 或 Java。我在 Canvas 上绘图,而不是 Swing 对象。当我切换到 Swing 对象(GUI 的其余部分是 Swing)时,闪烁消失了。

I found the issue. I made the foolish mistake of mixing AWT and Swing, since I do not do GUIs or Java very much. I was drawing on a Canvas, not a Swing object. When I switched to a Swing object (the rest of my GUI is Swing), the flickering went away.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文