C# 或 C++游戏:许多 16 色图像加载到 RAM 中。有效的解决方案?
我正处于创建一款格斗游戏的规划阶段,不确定如何处理与内存相关的问题。
背景信息:
- 仍在争论是使用 C# (XNA) 还是 C++。在我们探索如何用两种语言解决这个问题之前,我们不想承诺任何一种。
- 如果可能的话,使用最大 256MB RAM 会很棒。
- 一次会出现两个角色,并且这些角色只能在战斗之间更换。战斗之间有时间加载/释放内存,但游戏在战斗期间需要以每秒 60 帧的恒定速度运行。每帧16.67ms
- 每个角色的图像总数只有几百张。每个图像大约为 200x400 像素。在任何给定时刻只会显示每个角色的一张图像。
根据我的计算,未压缩时每张图像大约需要 300kb;整个字符超过 100MB。鉴于某些其他资源也需要内存,这太接近 256MB 限制了。
因为每个图像总共可以用 16 种颜色来制作。理论上,如果我能利用这一点,我应该能够使用 1/8 的空间。我环顾四周,但没有找到任何对调色板图像的本机支持。 (使用更少的位存储每个像素,每个像素映射到 32 位 RGBa 颜色)
我们尝试使用 DXT 压缩,但是,压缩伪影非常明显。
我正在考虑制作自己的文件格式,每像素 4 位(以及一些额外的调色板信息),在战斗前将这种新格式的所有图像加载到 RAM 中,然后在绘制任何特定图像时,仅将该图像解压缩为原始图像所以它可以正确渲染。我不知道每帧执行如此多的赋值操作(每个字符约 200x400 = 160k)是否现实。对我来说这听起来很老套。
有人对我的解决方案听起来是否合理以及是否有更好的解决方案有建议吗?
非常感谢!
(我还尝试使用只有 1 个通道的图像,然后使用着色器执行一系列 if 语句,将各种值转换为其他颜色。不幸的是,着色器的代码行太多。它也相当 hacky并且不能很好地扩展。)
I am in the planning stages of creating a fighting game and am unsure how to handle one issue relating to memory.
Background info:
- Still debating whether to use C# (XNA) or C++. We do not want to commit to either until we have explored how to solve this problem in both languages.
- Using a max of 256MB RAM would be great if possible.
- Two characters will be present at a time, and these characters can only change between battles. There is time to load/free memory between battles, but the game needs to run at a constant 60 drawn frames per second during combat. Each frame is 16.67ms
- The total number of images per character is in the low hundreds. Each image is roughly 200x400 pixels. Only one image from each character will be displayed at any given moment.
Uncompressed, each image takes roughly 300kb from my calculations; upwards of 100MB for a whole character. This is pushing too close to the 256MB limit given that memory will be needed for some other resources as well.
Since each image can be made with a total of 16 colors. Theoretically I should be able to use 1/8th the space if I can take advantage of this. I've looked around but haven't found any word of native support for paletted images. (Storing each pixel using fewer bits that each map to a 32-bit RGBa color)
We tried using DXT compression, however, the compression artifacts are quite noticeable.
I was considering making my own file format with 4 bits per pixel (and some extra palette info), loading all the images of this new format into RAM before battle, and then when drawing any specific image, decompress only that image into a raw image so it can be rendered properly. I don't know if it's realistic to perform so many assignment operations (appx 200x400 for each character = 160k) each frame. It sounds very hacky to me.
Does anyone have advice on whether my solution sounds reasonable, and if there is perhaps a better one available?
Thanks so much!
(I also attempted to use an image with only 1 channel, then use a shader to perform a series of if statements to translate various values into other colors. Unfortunately, there were too many lines of code for the shader. It is also rather hacky and does not scale well.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
请改用 S3 纹理压缩(又名 DXTn)。 S3TC 允许您以 4 位/像素或 8 位/像素存储纹理,并且显卡本身支持它。您不必担心动态解压缩它,因为显卡会这样做。
DirectX 在 C++ 和 C# 中对 S3TC 都有很好的支持。
Use S3 Texture Compression (aka DXTn) instead. S3TC lets you store textures at 4 bits/pixel or 8 bits/pixel, and it's supported natively by graphics cards. You don't have to worry about decompressing it on the fly, since the graphics card does that.
DirectX has very good support for S3TC, in both C++ and C#.
如果您想以 Xbox 360 为目标并且没有合适的(成熟的)开发套件,那么 C# 是您唯一的选择。当开始使用 XNA 时,XNA 肯定会让您的工作变得更加轻松,特别是如果您现在只做 2D(并且可以处理许多您现在不需要担心的其他事情)。
至于内存限制问题,建议解决:
(虽然你只有 1 位
alpha)
您还可以结合其中一些选项来节省更多。
If you want to target the XBox 360 and don't have a proper (full blown) devkit, then C# is your only option. When starting out XNA certainly makes doing things a lot easier for you, especially if you're just doing 2D for now (and takes care of a lot of other things you don't need to worry about right now).
As for the memory constraints issue, suggestions to get it down:
(although you'll only have 1 bit of
alpha)
You could also combine some of these options to save more.
我认为将图像放入精灵表中是最好的选择。这可以让您在因压缩而丢失图像数据和内存成本之间取得最佳平衡。
我将从 C# 和 XNA 框架开始,因为它对内置精灵处理器有很好的支持,并且内容管道可以在编译时自动将单个图像转换为完整的精灵表。 Microsoft 在此处提供了一个演示此功能的示例项目: http://create.msdn .com/en-US/education/catalog/sample/sprite_sheet
I think putting your images into a spritesheet is your best option. This gives you the best balance between losing your image data to compression, and memory cost.
I would start with C# and the XNA framework as there is excellent support for a built in sprite processor and the content pipeline can automatically convert individual images into a complete spritesheet at compile time. Microsoft provides a sample project demonstrating this functionality here: http://create.msdn.com/en-US/education/catalog/sample/sprite_sheet
您可以使用霍夫曼编码树来存储在内存中压缩的数据(因为正如您所说,它压缩得很好);然后实时提取/加载。您还可以使用其他压缩数据结构。
You could use a Huffman Encoding Tree to store the data compressed in the memory (since, as you say, it compresses well); then extract/load in real-time. There are other compressed data structures as well that you could use.
您可能需要查看 xnaMUGEN。格斗游戏引擎可以用 C# 轻松完成。
You may want to look at xnaMUGEN. A fighting game engine is something which can easily be done in C#.