爪哇;调整窗口大小后,油漆(图形)调用过多!

发布于 2024-11-16 09:03:22 字数 1220 浏览 4 评论 0原文

我有一个问题。最近我正在研究使用 Java 实现硬件渲染的方法。我的目标是不使用 OpenGL 等外部库。我在网站上找到了一篇帖子,详细介绍了如何执行此操作。

这就是代码(我重命名了一些项目):

    @Override
    public void paint(Graphics g) {
        createVolatileImage();

        do {
            GraphicsConfiguration gc = getGraphicsConfiguration();
            Graphics offscreenGraphics = volatileImage.getGraphics();

            int validationCode = volatileImage.validate(gc);
            if (validationCode == VolatileImage.IMAGE_INCOMPATIBLE) {
                createVolatileImage();
            }

            offscreenGraphics.setColor(getBackground());
            offscreenGraphics.fillRect(0, 0, getSize().width, getSize().height);

            offscreenGraphics.setColor(getForeground());
            paint(offscreenGraphics);

            g.drawImage(volatileImage, 0, 0, this);
        } while (volatileImage.contentsLost());
    }

    private void createVolatileImage() {
        GraphicsConfiguration gc = getGraphicsConfiguration();
        volatileImage = gc.createCompatibleVolatileImage(getWidth(), getHeight());
    }

不幸的是,如果我调整窗口大小 - 绘制( Graphics )方法(在 Canvas 类中)在一秒钟内被调用大约 1,000 次,导致 OutOfMemoryException 。

以前有人遇到过这种情况吗? 预先非常感谢!

I have a question. Recently I was looking into ways to implement hardware rendering using Java. My goal was not to use an external library such as OpenGL. I found a post on a website that detailed how to do so.

This is what the code was (I renamed some items):

    @Override
    public void paint(Graphics g) {
        createVolatileImage();

        do {
            GraphicsConfiguration gc = getGraphicsConfiguration();
            Graphics offscreenGraphics = volatileImage.getGraphics();

            int validationCode = volatileImage.validate(gc);
            if (validationCode == VolatileImage.IMAGE_INCOMPATIBLE) {
                createVolatileImage();
            }

            offscreenGraphics.setColor(getBackground());
            offscreenGraphics.fillRect(0, 0, getSize().width, getSize().height);

            offscreenGraphics.setColor(getForeground());
            paint(offscreenGraphics);

            g.drawImage(volatileImage, 0, 0, this);
        } while (volatileImage.contentsLost());
    }

    private void createVolatileImage() {
        GraphicsConfiguration gc = getGraphicsConfiguration();
        volatileImage = gc.createCompatibleVolatileImage(getWidth(), getHeight());
    }

Unfortunately, if I resize the window - the paint ( Graphics ) method (in the class Canvas) gets called like 1,000 times within a second, causing an OutOfMemoryException.

Has anyone encountered this before?
Thanks a lot in advance!

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

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

发布评论

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

评论(3

停顿的约定 2024-11-23 09:03:22

您收到 OutOfMemoryException 的原因是因为您从未清理过 VolatileImage。在我看来,每次调用 paint() 时,您都会分配一个新的 VolatileImage ,这可能会发生数百次(或者在您的情况下超过一千次)第二。除非您释放 VolatileImage 使用的内存或进行修复以便分配一次而不是每帧分配一次,否则应用程序的内存空间将会膨胀,直到 JVM 崩溃。尝试在渲染循环末尾添加对 offscreengraphics.dispose() 的调用。另请阅读 Javadoc

编辑:

另一个有用的参考

The reason you are getting an OutOfMemoryException is because you never clean up your VolatileImage. The way I see it, you are allocating a new VolatileImage every time paint() is called, which can happen many hundreds (or in your case over a thousand) times per second. Unless you free the memory used by the VolatileImage or fix things so that you make the allocation once instead of once per frame, your application's memory space will balloon until you crash the JVM. Try adding a call to offscreengraphics.dispose() at the end of your rendering loop. Also read the Javadoc.

EDIT:

Another useful reference.

原来是傀儡 2024-11-23 09:03:22

我真的不认为你的绘画方法中应该有一个循环。它应该为每个需要绘制的操作绘制一次,然后返回。当您拖动屏幕时,操作系统/环境将负责一遍又一遍地向您的应用程序发送重绘消息。如果可能的话,您应该重新粉刷,然后返回。没有循环检查内容是否丢失,操作系统会告诉您何时进行绘画。

I really don't think you should have a loop in your paint method. It should paint a single time for each action that needs a paint, then return.When you drag the screen, the OS/env will take care of dispatching repaint messages over and over to your app. You should repaint if possible then just return. No loops checking if content is lost, the OS will tell you when to do your painting.

狼性发作 2024-11-23 09:03:22

正如在 AWT 和 Swing 中绘制中所讨论的,这是在 AWT 中绘画时的预期行为。特别是,当调整组件大小时,会发生系统触发的绘制操作。正如 @rjacks 所指出的,您需要 dispose()paint() 中创建的任何资源。

As discussed in Painting in AWT and Swing, this is the expected behavior when painting in AWT. In particular, a system-triggered painting operation occurs when a component is resized. As @rjacks notes, you need to dispose() any resources created in paint().

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