在使用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实现可以选择以任何内部分辨率存储纹理数组。
我从中收集的是,如果你想要存储与原始格式不同的纹理,你必须自己转换它。
答案 0 :(得分:0)
必须编写片段着色器以同意您为glTexImage2D()提供的格式。对于GL_RGB,它应该强制alpha为1.0,如下所示:
vec3 Color_RGB = texture2D(sampler2d, texCoordinate);
gl_FragColor = vec4(Color_RGB, 1.0);
但是,对于GL_RGBA,它应该如下所示:
vec4 Color_RGBA = texture2D(sampler2d, texCoordinate);
gl_FragColor = Color_RGBA;
并且,如上所述,如果PNG文件没有透明度,则只能使用Android Bitmap类进行纹理处理。本文解释说: http://software.intel.com/en-us/articles/porting-opengl-games-to-android-on-intel-atom-processors-part-1