【发布时间】:2013-06-05 10:00:20
【问题描述】:
在使用 OpenGL ES 2.0 的 Android 上,我尝试使用不同的内部纹理格式执行某些性能测试。 最初,我有很多 RGBA 纹理 (png),我想使用 OpenGL 以不同的格式(例如 RGB 和 LUMINANCE)在内部加载和存储这些纹理。我像这样使用 glTexImage2D 加载我的纹理:
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),resourceId);
...
int size = bitmap.getRowBytes() * bitmap.getHeight();
ByteBuffer b = ByteBuffer.allocate(size);
bitmap.copyPixelsToBuffer(b);
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, bitmap.getWidth(),
bitmap.getHeight(), 0, GLES20.GL_RGBA,
GLES20.GL_UNSIGNED_BYTE, b);
这很好用,但是如果我将第一个 GLES20.GL_RGBA(internalFormat 参数)更改为其他任何值(GLES20.GL_RGB 或 GLES20.GL_LUMINANCE),我的纹理就会显示为全黑。将第二个 GLES20.GL_RGBA 更改为相同的值会显示一些东西 - 但显然不正确,因为原始数据是 RGBA。
我认为它可能与着色器代码有关 - 也许 texture2D(..) 返回不同的值,因为纹理的内部格式不同。我的着色器代码很简单:
gl_FragColor = texture2D(texture, fragment_texture_coordinate);
我也尝试过改变它,但还没有运气。所以我想也许 glTex2DImage 并没有像我想的那样工作(我不是这方面的专家)。
我做错了什么?
编辑: 我忽略了 texImage2D 上的这个小细节。看来:
internalformat 必须匹配格式。纹理图像处理期间不支持格式之间的转换。 type 可以用作指定所需精度的提示,但 GL 实现可以选择以它选择的任何内部分辨率存储纹理数组。
我从中得到的信息是,如果您想存储不同于原始格式的纹理,您必须自己进行转换。
【问题讨论】:
-
我试图找到解决方案几个星期......没有机会...... BitmapFactory.decodeXXXXX 正在预乘 alpa groups.google.com/forum/?fromgroups#!topic/android-developers/… ...唯一的方法是构建自己的加载器。 .. 我现在正在使用 jni 和 libpng
-
感谢您的回复,但我不认为预乘 alpha 是这里的问题。我的图像没有任何(半)透明像素。
-
from khronos.org/opengles/sdk/docs/man/xhtml/glTexImage2D.xml :
format Specifies the format of the texel data. Must match internalformat. The following symbolic values are accepted: GL_ALPHA, GL_RGB, GL_RGBA, GL_LUMINANCE, and GL_LUMINANCE_ALPHA.RGB 和 LUMINANCE 是连接的,如果是这样,为什么不使用香奈儿作为 LUMINANCE? -
啊,谢谢你的链接。奇怪我忽略了这一点:
internalformat must match format. No conversion between formats is supported during texture image processing. type may be used as a hint to specify how much precision is desired, but a GL implementation may choose to store the texture array at any internal resolution it chooses.所以基本上只能存储它,所以如果我的纹理已经是 RGB/亮度格式(或在 GL 调用之前转换)。
标签: android opengl-es-2.0