我正在开发Android上的openGL。 现在我遇到了一个问题。我定义了一个float数组,用于传递给片段着色器。
float[] data = new float[texWidth*texHeight];
// test data
for (int i = 0; i < data.length; i++) {
data[i] = 0.123f;
}
1。 initTexture:
glGenTextures...
glBindTexture...
glTexParameteri...
FloatBuffer fb = BufferUtils.array2FloatBuffer(data);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, fb);
2.FBO:
glGenBuffers...
glBindFramebuffer...
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texId, 0);
3.onDrawFrame:
glUseProgram(mProgram);...
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);...
IntBuffer fb = BufferUtils.iBufferAllocateDirect(texWidth*texHeight);
glReadPixels(0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_BYTE, fb);
System.out.println(Integer.toHexString(fb.get(0)));
System.out.println(Integer.toHexString(fb.get(1)));
System.out.println(Integer.toHexString(fb.get(2)));
片段着色器:
precision mediump float;
uniform sampler2D sTexture;
varying vec2 vTexCoord;
void main()
{
tex = texture2D(sTexture, vTexCoord.st);
vec4 color = tex;
gl_FragColor = color;
}
那么,我怎么能得到glReadPixels的浮点数据(0.123f,我之前定义的)?现在我得到的是ff000000(ABGR),所以我怀疑着色器不能通过这种方式获取数据。有人可以告诉我为什么以及如何处理它?我是一个新手,真的很感激。
答案 0 :(得分:0)
您的主要问题发生在glReadPixels()
之前。主要问题在于您使用glTexImage2D()
的方式:
FloatBuffer fb = BufferUtils.array2FloatBuffer(data);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0,
GL_RGBA, GL_UNSIGNED_BYTE, fb);
第8个参数的GL_UNSIGNED_BYTE
值指定传入的数据由无符号字节组成。但是,缓冲区中的值是浮点数。所以你的浮点值被解释为字节,它们可能很好地结束,因为它们是完全不同的格式,具有不同的大小和内存布局。
现在,您可能会想要这样做:
FloatBuffer fb = BufferUtils.array2FloatBuffer(data);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0,
GL_RGBA, GL_FLOAT, fb);
这适用于桌面OpenGL,它支持隐式格式转换,作为指定纹理数据的一部分。但OpenGL ES支持 。在ES 2.0中,GL_FLOAT
甚至不是format参数的合法值。在ES 3.0中,它是合法的,但仅适用于实际存储浮点数的内部格式,例如GL_RGBA16F
或GL_RGBA32F
。将它与GL_RGBA
内部格式(第三个参数)结合使用是错误的。
因此,除非您在ES 3.0中使用浮动纹理(消耗更多内存),否则您需要将原始数据转换为字节。如果浮点值介于0.0和1.0之间,则可以将它们乘以255,然后舍入到下一个整数。
然后你可以将它们作为带有glReadPixels()
的字节读回来,并且应该再次获得相同的值。