我希望将巨大的位图作为纹理加载到Android上的图形卡内存中,在OpenGL ES 2.0中,用作纹理图集,最大的尺寸。我的设备的最大纹理大小为8192x8192。
我知道我可以通过以下方式将位图加载为纹理:
// create bitmap
Bitmap bitmap = Bitmap.createBitmap(8192, 8192, Bitmap.Config.ARGB_8888);
{ // draw something
Canvas c = new Canvas(bitmap);
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
p.setColor(0xFFFF0000);
c.drawCircle(4096, 4096, 4096, p);
}
// load as a texture
GLUtils.texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);
然而,(毫不奇怪)我在尝试创建这样大小的位图时得到java.lang.OutOfMemoryError
。
是否可以加载部分?由于它是一个纹理图集,它可以从较小的位图组装而成。我查看了texSubImage2D
函数,但我不知道在哪里初始化全尺寸纹理,或者事先提供完整纹理的大小。
答案 0 :(得分:1)
在GL方面,您需要分配完整存储空间,然后对其进行修补。
使用glTexImage2D()
为null
参数设置data
值来分配存储空间。使用glTexSubImage2D()
上传补丁。
请注意,这仍然需要256MB内存,因此在许多预算设备上,您仍会获得OOM ...
答案 1 :(得分:0)
根据solidpixel的回答,这是一个完成工作的代码:
GLES20.glTexImage2D ( GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 8192, 8192, 0,
GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
Bitmap bitmap = Bitmap.createBitmap(1024, 1024, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bitmap);
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
for (int i = 0; i < 8; ++i) {
for (int j = 0; j < 8; ++j) {
// clear the bitmap
c.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
{ // draw something
p.setARGB(255, 32 * i, 32 * j, 255 - 32 * j);
c.drawCircle(512, 512, 512, p);
}
// load as part of a texture
GLUtils.texSubImage2D(GL_TEXTURE_2D, 0, i * 1024, j * 1024, bitmap);
}
}
此处纹理由64个1024x1024大小的位图组合而成。