1

I'm working on openGL es on Android. Now i meet a problem. I defined a float array, which is used to pass to fragment shader.

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)));

fragment shader:

precision mediump float;
uniform sampler2D sTexture;
varying vec2 vTexCoord;

void main()
{
    tex = texture2D(sTexture, vTexCoord.st);
    vec4 color = tex;
    gl_FragColor = color;
}

So, how can i get the float data(0.123f, which i defined before) whith glReadPixels? Now what i get is ff000000(ABGR), so i suspect shader doesn't get the data through this way. Can someone tell me why and how can i deal with it? i am a newbie on it and really appreciate it.

4

1 回答 1

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格式参数甚至不是合法值。在 ES 3.0 中,它是合法的,但仅适用于实际存储浮点数的内部格式,例如GL_RGBA16For GL_RGBA32FGL_RGBA将其与内部格式(第三个参数)结合使用是错误的。

因此,除非您在 ES 3.0 中使用浮点纹理(这会消耗更多内存),否则您需要将原始数据转换为字节。如果浮点值介于 0.0 和 1.0 之间,则可以通过将它们乘以 255 并四舍五入到下一个整数来实现。

然后,您也可以使用 , 将它们作为字节读回glReadPixels(),并且应该再次获得相同的值。

于 2015-06-04T02:59:32.193 回答