从帧缓冲获取新纹理的方法?

huangapple go评论45阅读模式
英文:

LibGDX - Getting a new Texture from a Framebufer?

问题

我正在制作一款卡牌游戏,其中卡片的纹理需要由多个子部分组成(例如边框、肖像、伤害和生命值的文本等)。
为此,我创建了一个构建器类,使用一个fbo(FrameBufferObject)来绘制我的组件,然后使用以下代码将结果返回为一个纹理:return fbo.getColorBufferTexture();

这对于单张卡片完全有效,但在我尝试创建第二张卡片时出现了问题。因为return fbo.getColorBufferTexture();返回的不是一个新的纹理对象,而是指向fbo绘制到的内部纹理的引用。因此,当创建新的卡片时,所有之前创建的卡片现在看起来都一样,因为所有单独的纹理都是指向相同位置的引用(即我用来创建它们的fbo的内部纹理)。

如何解决这个问题?

  • 是否有一种方法可以从fbo中提取一个新的纹理对象,而不是一个引用?
  • 是否有一种我忽视了的将现有纹理数据复制到新对象中的简单方法?

我尝试过的方法:

  • 显然可以从纹理中获取纹理数据,并将其作为输入传递给纹理的构造函数,然而以下代码:new Texture( generatorFrameBuffer.getColorBufferTexture().getTextureData(); 不起作用(它不会报错,但在绘制纹理时看不到任何东西)。
  • 我尝试使用Json类对纹理进行序列化并将其恢复为一个新对象,但这给我带来了一个错误消息。再加上纹理类没有实现“serializable”,这让我相信这不会起作用。
英文:

I am building a cardgame where the textures for the cards need to be composed of multiple sub-parts. (the frame, the portrait, text for the damage and health values etc.).
For this I made a builder class that uses an fbo (FrameBufferObject) to draw my components to and then return the result as a Texture using: return fbo.getColorBufferTexture();

This works perfectly for a single card, but gives problems when I try to create a second card. As return fbo.getColorBufferTexture(); returns not a new Texture object but a reference to the internal Texture that the fbo draws to. So when a new card is created, all previously created cards now look the same, since all the seperate Textures are references pointing to the same place (the internal Texture of the fbo I used to create them).

How do I fix this problem?

  • Is there a way to extract a new texture object from the fbo instead of a reference?
  • Is there an easy way to copy data from an existing texture into a new object that I have overlooked?

Things I have tried:

  • Apparently there is a way to get texturedata from a texture and the constructor for texture accepts that as input, however the code: new Texture( generatorFrameBuffer.getColorBufferTexture().getTextureData(); Does not work. (It does not give errors but when I draw the textures there is nothing to see)
  • I have tried serializing the Texture using the Json class and restoring it to a new object, but this gave me an error message. This combined with the fact that the Texture class does not implement "serializable" leads me to believe this will not work.

答案1

得分: 1

Json 只备份原始成员变量,所以它不能用于 Texture,它使用本地内存(在 GPU 上)来存储图像。

TextureData 不会起作用,因为它引用与 Texture 相同的图像。它不会创建副本。

无法从相同的 FBO 创建多个 Textures。当你从中调用 getColorBufferTexture() 时,你会得到一个始终显示当前绘制到帧缓冲区的 Texture。因此,即使你可以创建多个这些 Textures,它们也会看起来完全相同。

因此,如果你需要在游戏中反复更新这些卡片,那么你的唯一选项是:

  1. 为每张卡片创建单独的帧缓冲区。
  2. 创建一个大帧缓冲区,一次性将所有卡片绘制在上面,并使用 TextureRegions 将其分割以在游戏中使用。

如果你只需要创建一张卡片,然后在游戏的整个会话中使用它而不改变其外观,那么你可以使用帧缓冲区重复创建图像,将它们导出为 Pixmap,并重复。将其导出为 Pixmap 会从 GPU 内存中复制图像数据。然后你可以将单独的 Pixmaps 加载为 Textures。我认为只有在将这些 Pixmaps 导出为 PNG 文件以在未来会话中加载时,这个选项才有意义,因为它否则不会真正节省你大量内存,而上面的选项更容易管理。

要导出为 Pixmap:

frameBufferToCopy.bind();
Pixmap pixmap = Pixmap.createFromFrameBuffer(0, 0, frameBufferToCopy.getWidth(), frameBufferToCopy.getHeight());
英文:

Json only backs up primitive member variables, so it won't work on a Texture, which uses native memory (on the GPU) to store its image.

TextureData won't work, because it's referencing the same image that the Texture does. It's not making a copy.

There is no way to create multiple Textures from the same FBO. When you call getColorBufferTexture() from it, you get a Texture that always shows whatever is currently drawn onto the FrameBuffer. So even if you could create multiple of these Textures, they would all look identical.

So, if you need to be able to update these cards repeatedly during the game, then your only options are:

  1. Create a separate FrameBuffer for each card.
  2. Create a big FrameBuffer that you draw all your cards onto at once, and use TextureRegions to split it apart for use in the game.

If you only need to create the card once and then use it for the entire session of the game without changing its appearance, then you could use a FrameBuffer to repeatedly create images, export them as a Pixmap, and repeat. Exporting as a Pixmap copies the image data from GPU memory. You can then load the individual Pixmaps as Textures. I think this option really only makes sense if you export these Pixmaps as PNG files to load on future sessions, because it's not really saving you significant memory otherwise, and the above option is simpler to manage.

To export as Pixmap:

frameBufferToCopy.bind();
Pixmap pixmap = Pixmap.createFromFrameBuffer(0, 0, frameBufferToCopy.getWidth(), frameBufferToCopy.getHeight());

huangapple
  • 本文由 发表于 2023年2月23日 22:51:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/75546452.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定