【问题标题】:Memory violation in Android OpenGL GLES20 with glTexImage2D带有 glTexImage2D 的 Android OpenGL GLES20 中的内存冲突
【发布时间】:2016-06-04 13:33:08
【问题描述】:

我有一个位图(可以转换为 ByteBuffer)。我想通过偏移量将其所有 6 个面上传到 OpenGL 中的 GPU。当我执行以下操作时,应用程序会因 OpenGL 崩溃而导致内存冲突。

这里bitmap是一个字节数组byte[]

for (int i=0 ; i<6 ; i++) {
      GLES20.glTexImage2D(
          GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
          0,
          GLES20.GL_RGBA,
          side,
          side,
          0,
          GLES20.GL_RGBA,
          GLES20.GL_UNSIGNED_BYTE,
          ByteBuffer.wrap(bitmap, length / 6 * i, side * side * 4));
    }

但是当我复制数组然后像这样上传到GPU时(这里bitmapBitmap类型):

int numBytes = bitmap.getByteCount();
 ByteBuffer pixels = ByteBuffer.allocate(numBytes);
 bitmap.copyPixelsToBuffer(pixels);
 for (int i=0 ; i<6 ; i++) {
   Log.d("aakash", String.valueOf(numBytes / 6 * i));
   byte[] arr = Arrays.copyOfRange(pixels.array(), numBytes / 6 * i, numBytes / 6 * (i+1));
   GLES20.glTexImage2D(
       GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
       0,
       GLES20.GL_RGBA,
       bitmap.getWidth(),
       bitmap.getHeight() / 6,
       0,
       GLES20.GL_RGBA,
       GLES20.GL_UNSIGNED_BYTE,
       ByteBuffer.wrap(arr));
 }

我正确渲染了立方体贴图。

我在第一个中做错了什么?我想避免复制数组以将其部分上传到 GPU。

我可以保证尺寸和数学计算是正确的。

【问题讨论】:

    标签: android opengl-es bitmap bytearray bytebuffer


    【解决方案1】:

    为了避免内存冲突,只需替换

    ByteBuffer pixels = ByteBuffer.allocate(numBytes);
    

    ByteBuffer pixels = ByteBuffer.allocateDirect(numBytes);
    

    但是你不需要 ByteBuffer 来进行简单的侧面纹理加载

    loadSideTexture(context, GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_X, R.raw.lake2_rt);
    loadSideTexture(context, GLES20.GL_TEXTURE_CUBE_MAP_NEGATIVE_X, R.raw.lake2_lf);
    
    loadSideTexture(context, GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_Y, R.raw.lake2_up);
    loadSideTexture(context, GLES20.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, R.raw.lake2_dn);
    
    loadSideTexture(context, GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_Z, R.raw.lake2_bk);
    loadSideTexture(context, GLES20.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, R.raw.lake2_ft);
    
    private void loadSideTexture(Context context, int target, @RawRes int resID) {
        final Bitmap bitmap = BitmapFactory.decodeStream(context.getResources().openRawResource(resID));
        GLUtils.texImage2D(target, 0, bitmap, 0);
        bitmap.recycle();
    }
    

    【讨论】:

    • 供参考:立方体贴图纹理的位图需要是正方形的,例如:512 x 512
    猜你喜欢
    • 1970-01-01
    • 2017-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多