使用GL_LUMINANCE_ALPHA由GLES20.glTexImage2D加载的损坏数据

时间:2013-02-02 13:16:47

标签: android opengl-es glteximage2d

我正在使用opengl ES2.0在Android上渲染16位灰度数据。 (我在着色器中处理16位到8位动态范围缩放,16位输入是强制性的,因为它是数据的传入格式。)分辨率为640x512。

目前我的工作是将像素2一次推入320x512 32位RGBA纹理。即:

texture2D(thData, vTextureCoord)[0]是像素i低位字节,

texture2D(thData, vTextureCoord)[1]是像素i高位字节,

texture2D(thData, vTextureCoord)[2]是像素i+1低位字节,

texture2D(thData, vTextureCoord)[3]是像素i+1高位字节。

我能够从中重建数据,但我通过渲染到640x512缓冲区并使用gl_FragCoord.x和条件语句来重建原始分辨率,以确定是否从通道0,1或2,3中绘制像素。代码如下所示:

 private final String mFragmentShader =
    "precision highp float;\n" + 
    "varying vec2 vTextureCoord;\n" +
    "uniform sampler2D thData;\n" +
    "void main() {\n" +

    //This works out whether the pixel is in an odd or even column:
    "int odd = 0;\n" +
    "if (fract(gl_FragCoord.x/2.) >= 0.5) odd = 2;\n"+

    //This chooses the channels based on the column number
    "float data =((texture2D(thData, vTextureCoord)[odd]) + (texture2D(thData, vTextureCoord)[odd+1]*256.))*256.;\n" +

原则上这很好但是由于某些原因我似乎得到了一些交换的列,我的猜测是它可能是舍入错误导致条件语句的错误结果。

我想做的是首先使用16位全分辨率纹理来避免下采样,这看起来非常简单;我刚刚更改了glTexImage2D代码:

GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 320, 512, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, sBuffer);

GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE_ALPHA, 640, 512, 0, GLES20.GL_LUMINANCE_ALPHA, GLES20.GL_UNSIGNED_BYTE, sBuffer);

然而,当我这样做时,我似乎在纹理中得到奇怪的数据。 texture2D(thData, vTextureCoord)[0]似乎是正确的,但texture2D(thData, vTextureCoord)[1]与元素0具有相同的数据,无法看到像素的高字节。

我在这里遗漏了什么吗?

或者有人可以提出另一种方法吗?

2 个答案:

答案 0 :(得分:1)

您是否设置了所有像素解包参数?见glPixelStorei。您很可能必须将GL_UNPACK_ALIGNMENT设置为1。

答案 1 :(得分:1)

GL_LUMINANCE_ALPHA个纹理会复制所有xyz组件中的第一个组件。第二个组件位于w中,因为枚举名称的“ALPHA”部分表示。请参阅http://www.khronos.org/opengles/sdk/docs/man/xhtml/glTexImage2D.xml

GL_LUMINANCE_ALPHA格式的定义