【问题标题】:How to save images in the memory with LWJGL?如何使用 LWJGL 将图像保存在内存中?
【发布时间】:2012-06-23 17:12:26
【问题描述】:

我一直在使用java常规图形设备,awt和swing的东西,有Graphics,Graphics2D等有一段时间,然后开始看LWJGL的一系列教程。我真的很喜欢并决定在那个系统中重做我的一个游戏;我想,既然我已经有了逻辑,那就很容易了。我刚刚遇到了一个概念问题。

在这个特定的例子中,我有一个 Box 类来表示一个盒子,但是我用图像绘制了它,从而制作了边框。我有 9 张图像,一张用于中心(那只是一张 1 像素宽的纯色图像),4 张用于侧面,4 张用于角落。我将所有这些图像放在一个 BufferedImage 数组中,它是静态的,因为所有盒子都是一样的。然后,每个盒子都有一个全局的BufferedImage,我在里面画了盒子,这个过程真的很慢,因为我必须在盒子的每个部分都画一个图像。然后,在真正的绘制方法(接收图形 g)中,我只是将 BufferedImage 绘制在正确的位置。由于盒子的大小在创建后并没有改变,我只需要在构造函数中“创建”一次盒子图像。

我不知道如何使用 LWJGL 来做到这一点,因为 gl_ 方法(​​glBegin()、glVertex2i())将始终在屏幕上绘制,即使我从未指定过。那么如何绘制图像以及如何将其存储在内存中(也使用 BufferedImage),以及如何在需要时将其绘制在屏幕上?我发现 LWJGL 使用纹理,我将 BufferedImage 的第一个静态数组设为纹理的静态数组,然后正确保存其中的 9 个纹理中的每一个。这是正确的方法吗?全局BufferedImage呢,应该是全局Texture吗?在那种情况下,如何在纹理上“绘制”?

【问题讨论】:

    标签: java image opengl textures lwjgl


    【解决方案1】:

    您正在寻找的技术通常称为“渲染到纹理”(RTT)。您创建一个 opengl 帧缓冲区,将纹理附加到它,绑定您的帧缓冲区,然后发出正常的绘制调用。绑定帧缓冲区后,绘图调用将直接绘制到您的纹理中。然后,您取消绑定帧缓冲区并将您的纹理用作普通纹理。

    通过这些搜索词,我相信您可以在 Internet 上找到有关如何执行此操作的教程。

    我只是好奇,你的盒子是什么样子的,它不能用正常的纹理绘制?也许有更简单的方法来解决它。

    【讨论】:

    • 非常感谢,我现在正在搜索它,我相信它会非常有用。关于盒子,也许我只是不知道纹理是如何工作的,但它是这样的:你创建的每个盒子都有不同的尺寸,它们都有相同的固定尺寸边框。所以我猜更好的方法是创建 9 个图像,就像我说的那样。我不知道是否有更好的方法 - 我想象使用静态纹理边框会与框成比例地增长,我不希望那样。
    【解决方案2】:

    在 OpenGL 中,缩放非常便宜。你不需要预先生成任何东西。您可以将所有图像放在一个纹理中,并在将它们绘制到屏幕时使用纹理映射来正确放置和缩放它们。

    如果您已经有了使用 BufferedImage 的解决方案,请保持这种方式。在 GPU 上生成此图像不会为您节省太多时间。使用 awt 生成图像,从中创建纹理并使用 LWJGL 将其绘制到屏幕上。

    如果您真的想这样做,您可以使用glCopyPixels 将屏幕上的内容保存到纹理中。但我不会从那里开始学习 OpenGL。避免将图像传输到主内存(将其保存在纹理而不是 BufferedImage 中),在 CPU 和 GPU 之间发送数据可能非常慢。

    【讨论】:

    • 我在寻找纹理映射,但找不到任何方法来做我想做的事(但也没有找到任何很棒的教程,只是一些特定的点)。我试图从 BufferedImage 生成纹理,但它不起作用;我确定 BI 已正确创建,并且我使用了从 Internet 复制的方法,但它显示了一个白框。我正在尝试使用纹理映射,这是我收到的另一个建议,但也没有用。
    【解决方案3】:

    看看这个LWJGL texture tutorial,来自他们的维基。 在这个例子中,他们使用Slick-Util Library,这使得从图像创建纹理变得更加容易。


    您也可以自己生成纹理:

    BufferedImage bufferedImage = ...;
    ByteBuffer textureBuffer = convertImageData(bufferedImage);
    
    int texture = glGenTextures();
    glBindTexture(GL_TEXTURE_2D, texture);
    
    int pixelFormat;
    if (bufferedImage.getColorModel().hasAlpha()) {
        pixelFormat = GL_RGBA;
    } else {
        pixelFormat = GL_RGB;
    }
    
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 
            bufferedImage.getWidth(), bufferedImage.getHeight(), 0,
            pixelFormat, GL_UNSIGNED_BYTE, textureBuffer);
    

    Aaaaa 并查看 this answer 了解我之前写过的 convertImageData()。 (在他的代码中有几行可以删除)

    要绘制纹理:参见LWJGL Space Invaders 的第 97 行。

    【讨论】:

    • 我试过了,它没有给出任何错误,但它仍然不起作用。它生成 BufferedImage OK(我将它保存在一个文件中只是为了查看),但是该正方形出现的纹理混乱。我试图找出错误,这肯定是我在代码的其他部分中犯的一些错误。感谢您的回答!
    猜你喜欢
    • 1970-01-01
    • 2015-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-17
    • 2012-09-03
    相关资源
    最近更新 更多