ofImage. how to use texture memory only

Hi, all.

I am developing a game for iphone and now it takes about 120 Mb of RAM (lots of pictures)
How is it possible to deallocate memory used in “pixels”? and use memory on texture only.

I only load pictures and use Draw function. No any picture modifications required.

you can use:

  
  
ofLoadImage( texture,"path" );  
  

where texture is an ofTexture

But this function uses pixes insight and probably allocates them… (not sure) am I right?

although it will allocate memory (the image needs to be decompressed into ram before being loaded onto the texture) it will be temporary, as opposed to a traditional ofImage, where the pixels in RAM stay in RAM.

well, I made some research.
I have loadResources(…) function with 8 ofImages (1. 960x480 jpg, rest - pngs ~150x150)

and used ofImage::LoadImage(…)

It requires 8.42MB

Than I replaced all ofImage to ofTexture and used ofLoadImage. Now it takes 5.54 MB.

most memory eater is
glTexSubImage2D(texData.textureTarget, 0, 0, 0, w, h, texData.glType, texData.pixelType, data);

It it possible to reduce more the memory ammount?

also I have noticed one confusing thing:

when loading ofTexture (or ofImage), app takes X MB of RAM.

But if I call once function ofImage(or ofTexture) Draw(x, y, w, h). App requires X + 5-10 MB and even when I stop showing those images, allocated RAM memory still X + 5-10 MB.

How can I clean it?

problem place:
void ofTexture::drawSubsection(float x, float y, float z, float w, float h, float sx, float sy, float sw, float sh) {

glDrawArrays( GL_TRIANGLE_FAN, 0, 4 );

looks like memory is not cleaned after drawing arrays

what version of OF are you using? there’s no glDrawArrays anymore in ofTexture it’s using an ofMesh in 0.8 but even with that i’m pretty sure there was a delete in previous versions. if it doesn’t increase over time it might be some caching that openGL is doing internally. if you don’t have enough video memory to hold all the textures you are drawing, openGL will move some things to ram so that might be it.

also the only way to reduce textures more is to use some compressed format, if you are on desktop you can use:

  
  
texture.setCompression(OF_COMPRESS_ARB)  
  

on iphone there’s some compression formats but i think they are not directly supported in OF

I use 0.71

When calling draw() memory increases only once, for the first drawing. The problem is that when I stop draw that texture, memory is occupied.

as long as the memory usage stops incrementing at some point it’s normal. as i pointed out before opengl must be doing some caching and it won’t release that memory no matter if you are drawing or not. also if you don’t need that texture anymore you can always release the memory it’s using by calling:

  
  
texture.clear();  
  

I had similar issues recently on iOS when dealing with lots of image sequences- same deal with the caching after the first draw. I solved it by loading all the images into an ofPixels array and having a single ofTexture, then in the update/draw load the data every frame, eg. texture.loadData(pixels.getPixels()).

There would be a limit on how many images you could preload into the array, but it worked for me (300+ images at 342x257). If you do hit a limit, you could load and unload smaller batches (eg. 10-20 at a time) of images in a thread as you need them.

Yeah… I thought about it, but it’s not suitable for me. Because I need these textures during game is running (for example, “Game over” screen). I just want to unload the part of memory that was occupied during first drawing.

also something pretty common for assets for games is to upload all textures packed in one big texture + use an xml or similar to get the texture coordinates for each image. i think there’s even some addon to do it. the name of the technique is texture atlas. it’ll probably use a little less memory but is also way faster than using lots of small textures

another term for that is sprite sheet – here’s a couple of addons for it:

https://github.com/stfj/ofxSpriteSheetRenderer
https://github.com/chrisoshea/ofxSpriteSheet