Android: текстуры OpenGL слишком большие, не могу понять, почему

#android #opengl-es

#Android #opengl-es

Вопрос:

Почему мои текстуры, похоже, занимают так много места?

Мое приложение, которое интенсивно использует opengl, выдает следующую статистику кучи * во время работы:

 Used heap dump 1.8 MB 
Number of objects 49,447 
Number of classes 2,257 
Number of class loaders 4 
Number of GC roots 8,551 
Format hprof 
JVM version  
Time 1:08:15 AM GMT 02:00 
Date Oct 2, 2011 
Identifier size 32-bit 
  

Но, когда я использую диспетчер задач на своем телефоне, чтобы посмотреть на использование ОЗУ моим приложением, он говорит, что мое приложение использует 44,42 МБ. Есть ли какая-либо связь между использованием размера кучи и использованием оперативной памяти? Я думаю, что большая часть этих 42 МБ должна быть моими текстурами open GL, но я не могу понять, почему они занимают так много места, потому что на диске все файлы вместе занимают всего 24 МБ (и они не все загружаются одновременно). И я даже уменьшаю многие из них, изменяя размер растрового изображения перед загрузкой текстуры. Я также динамически создаю некоторые текстуры, но также уничтожаю эти текстуры после использования.

Я использую OpenGL 1.0 и Android 2.2, типичный код, который я использую для загрузки текстуры, выглядит так:

 static int set_gl_texture(Bitmap bitmap){

        bitmap = Bitmap.createScaledBitmap(bitmap, 256, 256, true);
        // generate one texture pointer
        mGL.glGenTextures(1, mTextures, 0);
        mGL.glBindTexture(GL10.GL_TEXTURE_2D, mTextures[0]); // A bound texture is
                                                            // an active texture


        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0,GL10.GL_RGBA, bitmap, 0);

        // create nearest filtered texture
        mGL.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
                GL10.GL_LINEAR); // This is where the scaling algorithms are
        mGL.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
                GL10.GL_LINEAR); // This is where the scaling algorithms are
        mGL.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
                GL10.GL_CLAMP_TO_EDGE);
        mGL.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
                GL10.GL_CLAMP_TO_EDGE);
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

        bitmap.recycle();
        Log.v("GLSurfaceView", "Loading Texture Finished, Error Codes:" mGL.glGetError());
        return mTextures[0];
    }
  

Код, который я использую для загрузки растровых изображений, выглядит следующим образом:

 public int load_texture(int res_id){

            if(mBitmapOpts==null){
                mBitmapOpts = new BitmapFactory.Options();
                mBitmapOpts.inScaled = false;
            }

            mBtoLoad = BitmapFactory.decodeResource(MyApplicationObject.getContext().getResources(),res_id, mBitmapOpts);

            assert mBtoLoad != null;

            return GraphicsOperations.set_gl_texture(mBtoLoad);

        }
  

* файл hprof анализируется с использованием mat, те же данные генерируются eclipse ddms

Ответ №1:

PNG — это сжатые изображения. Чтобы OpenGL мог их использовать, PNG-файлы должны быть распакованы. Эта декомпрессия увеличит размер памяти.

Возможно, вы захотите как-то уменьшить размер некоторых текстур. Возможно, вместо использования изображений 512×512 используйте 256×256 или 128×128. Некоторые текстуры, которые вы используете, могут не быть такими большими, поскольку они загружаются на мобильное устройство с ограниченным размером экрана.

Комментарии:

1. память освобождается после распаковки

2. Данные все еще находятся в памяти после того, как они были перенесены в контекст OpenGL. Однако это не те же данные, что и само растровое изображение. Вы можете проверить это, выведя собственное использование памяти до и после использования glTexImage2D