I am writing a visual novel on my desktop, using SDL and C++. I'm having trouble handling my sprites, in SDL.

  1. I am getting the "not enough video memory" error when I create all of my sprites to texture at once. I load the textures in the background process, while it was being rendered. I forgot that textures should be created in the main rendering thread, but if I load the image file in the background and load the textures in the foreground, the screen freezes. How do I fix this?

  2. Our target base resolution is 1980x1080 pixels; that is why I am getting the "not enough video memory" error. The sprites should be detailed and huge in a single sprite frame, as they should look like 2/3 in the screen. That means my sprite sheet is as huge as 8k x 2k or a single row of sprites.

    How should I handle it? Do I need to resize our base resolution to a lower size, and just do the bitblock resize of the entire screen/canvas to the screen? Do we do the work, or base the art on a lower screen resolution instead and just resize it to fit the player's screen at runtime? My problem, if we work at smaller resolutions and just resize at runtime, is that it might become blocky or blurry.

The sprite sheets are too big, because the screen resolution is too big. We have one hundred sprite sheets that can not be loaded together, but cannot be loaded in a separate thread. How do I handle a lot of big textures for a visual novel?

  • That's strange. An 8k*2k image in a raw format should only be around 64Mb. Most GPUs have around 2-4Gb – Bálint Dec 26 '16 at 16:21
  • If all of those 100 sprites are 1980*1024 (which is unreasonable), then all those take up around 850 Mb – Bálint Dec 26 '16 at 16:26
  • Are you using the same texture multiple times and loading a new texture for every single object with the same texture instead of just load it once?... I am almost sure that it is your problem, because running out of memory is too much crazy now days. At least it has never happened to me, and i use for example 4K shadow cube maps, which is huge compared to your problem. – Haruko Dec 26 '16 at 20:11

There are couple of things you can do, if you haven't already:

  • Use texture compression to decrease memory footprint. OpenGL supports this out of the box nowdays.
  • Don't use 32 bit textures. Sometimes textures with lower bit-depth can look as good as the 32 bit versions. For example if you don't absolutely need very precise transparency, you could use GL_RGB5_A1 (which is basically 1 bit for alpha, like cutout) and you will save half of the texture memory you would use with 32 bit textures. If the textures look worse in lower bitrate, try tonemapping.
  • Don't have the textures you don't need loaded in memory. This basically means you have to load the textures to the memory only when you need them and at the same time unload those you don't need. Should you want to use loading screens or some background-loading thread is completely up to you. Either work fine. Split up the sprite atlases. You do not need all the sprites loaded in the memory all the time. Load the proper atlas to the memory only when you know a sprite in the atlas is being used in the current scene, or maybe in the next scene if you're preloading in background.
  • Reuse your textures if at all possible. Recolor them using a shader or just reuse them everywhere. Super mario did this for example. You could use this technique to create a forest or a city. Be creative.
  • Instead of having all the text in the game as separate images, create a font atlas and a text engine to draw all the text. If you feel wild enough, you could implement Signed Distance Field (SDF) fonts which can be used very flexibly to render text in many different ways and with different effects, all with just one pretty small texture. If SDF does not give enough quality (your font has lots of sharp corners) you could try MSDF, multichannel SDF.
  • Scale down your textures. If you store your textures in memory with way larger resolution than what you are targetting, you basically are wasting some memory. If your game is running currently in 1080p resolution display, you don't need 4K resolution textures in memory. Measure how large your sprites are on the screen, and load the properly sized textures in to the memory based on the resolution the game is running on the current machine.
  • 1
    I just want to add a small point, try to use multithread to load content if it is possible and if the content that you want to load is big enough. It is just a small addition, you described perfectly what he should do. – Haruko Dec 26 '16 at 20:08

Don't load all textures at once. Only load those you need for the current scene, and release the textures when the scene is over. Visual novels are slow-paced games, so a few milliseconds of load-time between scenes (and even within scenes) isn't an issue. You can usually hide it with a fade-effect anyway.

You can reduce the number of images you need to load by splitting characters into individual images. When you have a character with 10 different poses, put them in 10 individual image files.

Also look into modularizing character sprites. You would be surprised how many different facial expressions you can create by layering a blank face and a few different variations of eyes (looking up, looking down, looking sideways, looking at viewer, closed), eyebrows (neutral, raised, tensed) and mouths (neutral, smile, frown, open).

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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