我正在使用 opengl ES2.0 在 Android 上渲染 16 位灰度数据。(我在着色器中处理 16 位到 8 位的动态范围缩放,16 位输入是强制性的,因为它是数据的传入格式。)分辨率为 640x512。
目前,我通过一次将 2 个像素推入 320x512 32 位 RGBA 纹理来完成这项工作。IE:
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 相同的数据,像素的高字节无处可见。
我在这里错过了什么吗?
或者任何人都可以提出另一种方法吗?