loading multiple textures openGL
I just started using openGL I need to load allot of bitmaps for animation I can get it to work great for a few frames but run out of memory when I try to load all the frames How can I load just a few frames at a time? This is the code I'm using to load the textures
public void loadGLTexture(GL10 gl, Context context) {
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.r1);
Bitmap bitmap01 = Bitmap.createScaledBitmap(bitmap, 512, 512, false);
Bitmap bitmap2 = BitmapFactory.decodeResource(context.getResources(),R.drawable.r2);
Bitmap bitmap02 = Bitmap.createScaledBitmap(bitmap2, 512, 512, false);
Bitmap bitmap3 = BitmapFactory.decodeResource(context.getResources(),R.drawable.r3);
Bitmap bitmap03 = Bitmap.createScaledBitmap(bitmap3, 512, 512, false);
try {
bitmap = bitmap01;
bitmap2 = bitmap02;
bitmap3 = bitmap03;
} finally {
}
//Generate there texture pointer
gl.glGenTextures(3, textures, 0);
//Create Texture and bind it to texture 0
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
//Create Texture and bind it to texture 1
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[1]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap2, 0);
//Create Texture and bind it to texture 2
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[2]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, G开发者_运维技巧L10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap3, 0);
//Clean up
bitmap.recycle();
bitmap2.recycle();
bitmap3.recycle();
}
}
Well, it's the classic issue of loading to many bitmaps in the (very limited) memory available to your app's process. I'm not gonna get into this, suffice to say that pre Honeycomb these bitmaps were loaded offheap, from Honeycomb and beyond they're loaded on the heap, but the issue still remains: a bitmap of 128x256 pixels will take 4*128*256 bytes in memory. And you usually have between 16 and 48 megs of available memory for your app (depending on device and Android version).
Good news here is that once you load a bitmap and create an opengl texture with it, you no longer need that Bitmap object, you can recycle it and make it null. So you might try loading (and, as I see from your code, scaling) the first bitmap, then create the first texture object, then recycle and de-refference that first bitmap. Then go on and do the same with the second bitmap for the second texture object.
First, you could recycle the bitmaps as soon as you scale the image. Second, you should prescale them down, that is, store them as 512x512 from the get go.
But most importantly, you should create a texture atlas for this. Essentially, instead of using multiple textures, you could use a single, large texture and store all the fragments there. The idea would be to create, say, a 2048x2048 texture, which can store 16 "cels" of 512x512 pixels (4 rows of 4 cels each), and then when drawing your quads on screen, altering the texture coordinates to display a particular cel.
For offline generation, there are a number of utilities that can help; TexturePacker is one, and there are many others. To do it in code, you can generate your texture once:
gl.glGenTextures(1, textures, 0);
//Create Texture and bind it to texture 0
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, 2048, 2048, 0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, null);
That last line allocates an empty image of the size (2048x2048)
Then for each of your bitmaps, you can use:
int xoffset = (imageIndex % 4) * 512;
int yoffset = (imageIndex / 4) * 512;
GLUtils.texSubImage2D(GL10.GL_TEXTURE_2D, 0, xoffset, yoffset, bitmap);
This will load your bitmap into a portion of the texture. As @Joseph hinted, the constraints for the RAM usage on the GL Textures are quite relaxed.
精彩评论