android - Android OpenGLes LoadTextures 内存不足异常

标签 android memory opengl-es heap-memory

我正在尝试加载纹理以便在我的游戏中使用它们。目前,我的游戏需要 84 个图像帧才能按我的预期运行,但是当我加载这么多图像时,它会出现 OutOfMemmory 异常。

有没有更好的方法来加载这些图像?

每个 Obs 在 HDPI 设备上的大小均为 150x150px。

我运行的设备是 Galaxy SII,我相信它有 50mb 的堆内存。

这里是异常发生的地方:

    public void loadTextures(GL10 gl) {
    InputStream is[] = new InputStream[textureCount];
    Bitmap bitmap[] = new Bitmap[textureCount];

    is[0] = context.getResources().openRawResource(R.drawable.bg_01);
    is[1] = context.getResources().openRawResource(R.drawable.bg_02);
    is[2] = context.getResources().openRawResource(R.drawable.bg_03);

    is[3] = context.getResources().openRawResource(R.drawable.win_hud);
    is[4] = context.getResources().openRawResource(R.drawable.heart);

    is[5] = context.getResources().openRawResource(R.drawable.skyblue);
    is[6] = context.getResources().openRawResource(R.drawable.heart);
    is[7] = context.getResources().openRawResource(R.drawable.heart);
    is[8] = context.getResources().openRawResource(R.drawable.heart);
    is[9] = context.getResources().openRawResource(R.drawable.heart);
    is[10] = context.getResources().openRawResource(R.drawable.heart);

             //reserving numbers for more textures from 6 to 10.


    is[11] = context.getResources().openRawResource(R.drawable.walking01);
    is[12] = context.getResources().openRawResource(R.drawable.walking02);
    is[13] = context.getResources().openRawResource(R.drawable.walking03);
    is[14] = context.getResources().openRawResource(R.drawable.walking04);
    is[15] = context.getResources().openRawResource(R.drawable.walking05);

    is[16] = context.getResources().openRawResource(R.drawable.flying01);
    is[17] = context.getResources().openRawResource(R.drawable.flying02);

    is[18] = context.getResources().openRawResource(R.drawable.falling_01);
    is[19] = context.getResources().openRawResource(R.drawable.falling_02);
    is[20] = context.getResources().openRawResource(R.drawable.fallen);

    is[21] = context.getResources().openRawResource(
            R.drawable.standingup_01);
    is[22] = context.getResources().openRawResource(
            R.drawable.standingup_02);

    is[23] = context.getResources().openRawResource(R.drawable.death_01);
    is[24] = context.getResources().openRawResource(R.drawable.death_02);
    is[25] = context.getResources().openRawResource(R.drawable.death_03);
    is[26] = context.getResources().openRawResource(R.drawable.death_04);
    is[27] = context.getResources().openRawResource(R.drawable.death_05);
    is[28] = context.getResources().openRawResource(R.drawable.death_06);


    is[29] = context.getResources().openRawResource(R.drawable.p_walk_1);
    is[30] = context.getResources().openRawResource(R.drawable.p_walk_2);
    is[31] = context.getResources().openRawResource(R.drawable.p_walk_3);
    is[32] = context.getResources().openRawResource(R.drawable.p_walk_4);
    is[33] = context.getResources().openRawResource(R.drawable.p_walk_5);
    is[34] = context.getResources().openRawResource(R.drawable.p_walk_6);

    is[35] = context.getResources().openRawResource(R.drawable.p_holding01);
    is[36] = context.getResources().openRawResource(R.drawable.p_holding03);

    is[37] = context.getResources().openRawResource(R.drawable.p_opening01);
    is[38] = context.getResources().openRawResource(R.drawable.p_opening02);


    is[39] = context.getResources().openRawResource(R.drawable.p_parachute01);
    is[40] = context.getResources().openRawResource(R.drawable.p_parachute02);
    is[41] = context.getResources().openRawResource(R.drawable.p_parachute03);
    is[42] = context.getResources().openRawResource(R.drawable.p_parachute04);
    is[43] = context.getResources().openRawResource(R.drawable.p_parachute05);

    is[44] = context.getResources().openRawResource(R.drawable.p_closing01);
    is[45] = context.getResources().openRawResource(R.drawable.p_closing02);

    is[46] = context.getResources().openRawResource(R.drawable.p_cracking01);
    is[47] = context.getResources().openRawResource(R.drawable.p_cracking02);

    is[48] = context.getResources().openRawResource(R.drawable.p_fallen01);

    is[49] = context.getResources().openRawResource(R.drawable.p_standing01);
    is[50] = context.getResources().openRawResource(R.drawable.p_standing02);
    is[51] = context.getResources().openRawResource(R.drawable.p_standing3);

    is[52] = context.getResources().openRawResource(R.drawable.p_dead01);
    is[53] = context.getResources().openRawResource(R.drawable.p_dead02);
    is[54] = context.getResources().openRawResource(R.drawable.p_dead03);
    is[55] = context.getResources().openRawResource(R.drawable.p_dead04);
    is[56] = context.getResources().openRawResource(R.drawable.p_dead05);
    is[57] = context.getResources().openRawResource(R.drawable.p_dead06);
    is[58] = context.getResources().openRawResource(R.drawable.p_dead07);
    is[59] = context.getResources().openRawResource(R.drawable.p_dead08);
    is[60] = context.getResources().openRawResource(R.drawable.p_dead09);

    is[61] = context.getResources().openRawResource(R.drawable.r_walking01);
    is[62] = context.getResources().openRawResource(R.drawable.r_walking02);
    is[63] = context.getResources().openRawResource(R.drawable.r_walking03);
    is[64] = context.getResources().openRawResource(R.drawable.r_walking04);
    is[65] = context.getResources().openRawResource(R.drawable.r_walking05);
    is[66] = context.getResources().openRawResource(R.drawable.r_walking06);
    is[67] = context.getResources().openRawResource(R.drawable.r_walking07);
    is[68] = context.getResources().openRawResource(R.drawable.r_walking08);
    is[69] = context.getResources().openRawResource(R.drawable.r_falling01);
    is[70] = context.getResources().openRawResource(R.drawable.r_falling02);

    is[71] = context.getResources().openRawResource(R.drawable.r_fallen);

    is[72] = context.getResources().openRawResource(R.drawable.r_standingup01);
    is[73] = context.getResources().openRawResource(R.drawable.r_standingup02);

    is[74] = context.getResources().openRawResource(R.drawable.r_dyeing01);
    is[75] = context.getResources().openRawResource(R.drawable.r_dyeing02);
    is[76] = context.getResources().openRawResource(R.drawable.r_dyeing03);
    is[77] = context.getResources().openRawResource(R.drawable.r_dyeing04);
    is[78] = context.getResources().openRawResource(R.drawable.r_dyeing05);
    is[79] = context.getResources().openRawResource(R.drawable.r_dyeing06);
    is[80] = context.getResources().openRawResource(R.drawable.r_dyeing07);
    is[81] = context.getResources().openRawResource(R.drawable.r_dyeing08);
    is[82] = context.getResources().openRawResource(R.drawable.r_dyeing09);
    is[83] = context.getResources().openRawResource(R.drawable.r_dyeing10);




    for (int loop = 0; loop < textureCount; loop++) {

        bitmap[loop] = BitmapFactory.decodeStream(is[loop]);
        try {
            is[loop].close();
            is[loop] = null;
        } catch (IOException e) {
        }
    }
    gl.glGenTextures(textureCount, textures, 0);
    for (int loop = 0; loop < textureCount; loop++) {
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[loop]);
        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.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, // OpenGL docs.
                GL10.GL_NICEST);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
                GL10.GL_CLAMP_TO_EDGE);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
                GL10.GL_CLAMP_TO_EDGE);

        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap[loop], 0);
        bitmap[loop].recycle();
    }
}

最佳答案

由于您需要同时在屏幕上显示所有内容,因此优化是不可能的。我建议您选择Displaying Bitmaps Efficiently教程值得铭记,因为它提供了一些有关如何避免可怕的 java.lang.OutofMemoryError:位图大小超出 VM 预算 错误的提示。

还有一些其他的事情浮现在我的脑海中。首先,我建议不要在循环之前加载所有InputStream。为什么不在循环中加载流?也许写入要加载到文件中的图像的名称并迭代它们。

此外,根据我的经验,BitmapFactory.decodeFileDescriptor() 造成的麻烦也较少。虽然我不确定它是否能解决问题,但目前不会有什么坏处!

关于android - Android OpenGLes LoadTextures 内存不足异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16862858/

相关文章:

c++ - 为什么删除不破坏任何东西?

c - 多个相同文字的内存使用与 const

opengl-es - 尝试附加纹理时,GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT

android - 启动应用程序知道包名

android - 我们可以在没有物理罗盘的情况下获得罗盘方向吗(例如使用 2 个 GPS 点?)

java - button.OnClick 代码运行但不执行更改?

Python Tkinter - 如何使某些代码使用更少的内存

android - 在 Android OpenGL ES 中使用 Wavefront .obj 的纹理坐标的问题

ios - iOS 有哪些合适的粒子效果引擎选项?

Android获取联系人姓名和号码查询