1

在使用 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 实现可以选择以它选择的任何内部分辨率存储纹理数组。

我从中收集到的是,如果您想存储与原始格式不同的纹理,则必须自己进行转换。

4

1 回答 1

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

于 2013-06-12T02:08:32.083 回答