1
\$\begingroup\$

I'm actually trying to port a GBA game to SDL for educationnal purpose. The game has many sprites and tiles. Since the GBA screen size is 240x160px, I decided to scale it 2x. At first, it went okay creating spritesheet for animations, because typical animations had something around 2-8 frames.

However, I faced yesterday a problem that I had not seen coming. I got a 89-frame animation. Including the scale, each frame is around 480x320px. With 89 frames, it creates a huge image.

When I load it into a SDL_Texture with IMG_LoadTexture, the size of the test program goes from ~9MB to 56MB. I find this huge considering the image weights at most 4MB (without compression, PNG-32 bits I believe). No matter what compression I do, it still takes ~50MB.

Here's the code that loads the image:

m_frameDestRect = { 0, 0, 480, 320 }; 
m_frameSrcRect = { 0, 0, 480, 320 };
m_pTexSprite = IMG_LoadTexture(pRenderer, "image.png");

I keep the SDL_Texture in a SDL_Texture* property of my class. It also never change.

Here's the code that "draws" the texture:

SDL_RenderCopy(m_pRenderer, m_pTexSprite, &m_frameSrcRect, &m_frameDestRect);

Here's the code that "update" the frame:

uint32_t frameX = (m_frame + 1) % 5;
uint32_t col = (m_frame + 1) / 5;

m_frameSrcRect = { frameX * 480, col * 320, 480, 320 };

I could live with that, but then I saw that I got an animation that has 489 frames...

Since I am no expert in video games programming, nor in imaging, I came here to ask this very question.

1. Is the RAM consumption of SDL_Texture (and whatever loaded behind) normal ?
2. Animation wise, are there other ways to implement them?

I find it totally impressive all these sprites (got tons of them, in gif formats) actually loaded quite smoothly on the GBA, considering the number of frames.

Any advice / solutions / answers is more than welcomed.

Thanks

\$\endgroup\$
0
\$\begingroup\$

Just remember that unless you are using gpu compression (Which PNGs don't support), all of your images will be uncompressed in ram.

Also, your animation seems pretty standard. Remember that as long as everything fits into ram, you're only drawing what you see so performance shouldn't be an issue

\$\endgroup\$
  • \$\begingroup\$ Thanks for your answer. I'll look further for the GPU compression. Performance isn't indeed an issue at the moment. I was much more worried about the size I used in RAM. Also, a 489 frames animation each frame being 480x320px doesn't fit well on a standard image, since SDL_Image limits to 8192x8192px (which to me sounds huge). But if you say that it is standard, then I'll assume no worries on that. \$\endgroup\$ – Alexandre TryHard Leblanc Oct 8 '15 at 16:47
  • \$\begingroup\$ If you're just doing a 2D game, it's highly unlikely if you will need GPU compression btw \$\endgroup\$ – CobaltHex Oct 8 '15 at 17:43
  • \$\begingroup\$ Then it leads me to a point that I wouldn't know what to do with a 489 frames animation. It doesn't fit on a loadable spritesheet image. That is without considering the memory it'll consume. I can tell the animation once scaled and everything, will be around 480 * 320 * 489 = 75,110,400px² . That's around 8666px per side. No matter how I look at it, it won't load in SDL. Therefore I'll need to use another strategy for it. Thanks for your answers. \$\endgroup\$ – Alexandre TryHard Leblanc Oct 8 '15 at 17:50
  • \$\begingroup\$ If you had to, you could always break it into multiple textures. Another thing would be to shrink your textures and then upscale them (at the cost of them looking pixelated/blurry). Also, another point: Changing the texture format may use less memory (at the cost of possibly less fidelity). If you are aiming for a GBA look, the GBA had a 15bit palette, which is about half of what you're probably using now. It won't decrease the size but it will shrink the memory usage. \$\endgroup\$ – CobaltHex Oct 8 '15 at 17:59
  • \$\begingroup\$ I think the scaling solution might be good enough for the animation because the animation itself doesn't need to be clear. The normal eye wouldn't probably even notice. That'll solve it. Since it is only used in battles, I do not need to have it persistently in the memory, so to me it settles it. Thanks a lot! \$\endgroup\$ – Alexandre TryHard Leblanc Oct 8 '15 at 18:00
0
\$\begingroup\$

With a standard setup you'll use 32 bit per pixel, that is 4 bytes. So each of your frames requires 614400bytes, 89 frames use 52MB.

You could reduce the amount by factor 2 if you switch to 16bit RGB565 for RGBA4444 format - that is not GPU dependent.

ETC1, PVRTC 2bbp/4bbp, DXTC are platform specific. Your software might not run on all kinds of GPUs.

8192x8192 might also not work on all devices.

I would recommend using a video codec to compress the images. They use the difference between frames and give you a way better compression ratio.

\$\endgroup\$
  • \$\begingroup\$ That is an interesting approach. So I guess I could try this. Being multi-platform is really important to me. Since the "original" sprite was in an uncompressed animated GIF format, I guess this is most likely feasible. Thanks ! \$\endgroup\$ – Alexandre TryHard Leblanc Oct 8 '15 at 17:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.