Can’t write/process/readback floats using RGBA_FLOAT32_ATI textures and shaders?
Fighting hard to get a “simple” particle system with vertices updated by a shader. (FBO+MRT)
It seems I have to bang my head on every possible stupid bug.
Until now I’ve managed to find answers. But for this one I need some help.
I use a simple fragment shader to process an input texture as an array of floats then I write the result in another texture and read the result back to CPU to check it. (latter I will use it as source for vertices).
Whenever I change the values (not just copy them) I don’t get the correct result.
I guess this is just a float “format” mismatch but can’t find where I’m wrong.
The initial float texture is created with: (this is JOGL sorry for the gl.* GL.* ).
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA_FLOAT32_ATI, size, size, 0, GL.GL_RGBA, GL.GL_FLOAT, null);
gl.glTexSubImage2D(GL.GL_TEXTURE_2D, 0, 0, 0, texSize, texSize, GL.GL_RGBA, GL.GL_FLOAT, FloatBuffer.wrap(data));
data is a java float[] initialized with the index of the array element
so for the debug 2x2 texture the 4 texels are:
1.0 2.0 3.0 4.0 | 5.0 6.0 7.0 8.0 |
9.0 10.0 11.0 12.0 | 13.0 14.0 15.0 16.0 |
The texture is bound to a FBO and used as
gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, fbo);
gl.glFramebufferTexture2DEXT(GL.GL_FRAMEBUFFER_EXT, GL.GL_COLOR_ATTACHMENT0_EXT, GL.GL_TEXTURE_2D, texS, 0); gl.glFramebufferTexture2DEXT(GL.GL_FRAMEBUFFER_EXT, GL.GL_COLOR_ATTACHMENT1_EXT, GL.GL_TEXTURE_2D, texD, 0);
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glPushMatrix();
gl.glLoadIdentity();
glu.gluOrtho2D(0.0, texSize, 0.0, texSize);
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glPushMatrix();
gl.glLoadIdentity();
gl.glViewport(0, 0, texSize, texSize);
gl.glDrawBuffer(GL.GL_COLOR_ATTACHMENT1_EXT);
The vertex/fragment shaders are applied using a single quad
gl.glBegin(GL.GL_QUADS);
gl.glColor3f(1, 1, 1);
gl.glMultiTexCoord2f(GL.GL_TEXTURE0, 0.0f, 0.0f);
gl.glVertex2f(0, 0);
gl.glMultiTexCoord2f(GL.GL_TEXTURE0, 1.0f, 0.0f);
gl.glVertex2f(texSize, 0);
gl.glMultiTexCoord2f(GL.GL_TEXTURE0, 1.0f, 1.0f);
gl.glVertex2f(texSize, texSize);
gl.glMultiTexCoord2f(GL.GL_TEXTURE0, 0.0f, 1.0f);
gl.glVertex2f(0, texSize);
gl.glEnd();
Then read back with
gl.glReadBuffer(GL.GL_COLOR_ATTACHMENT1_EXT);
gl.glReadPixels(0, 0, texSize, texSize, GL.GL_RGBA, GL.GL_FLOAT, FloatBuffer.wrap(result));
The shaders are:
vertex:
void main(){
gl_Position = ftransform();
gl_TexCoord[0] = gl_MultiTexCoord0;
}
fragment:
uniform sampler2D Texture0;
void main() {
vec4 vi = texture2D(Texture0,vec2(gl_TexCoord[0]));
// gl_FragData[0] = vec4(.01,-.02,1.111,-1E10); // test 1 OK
// gl_FragData[0] = gl_FragCoord; // test 2 OK
// gl_FragData[0] = vi; // test 3 OK
// gl_FragData[0] = vec4(vi.x,vi.y,vi.z,vi.w); // test 4 OK
// gl_FragData[0] = -vi; // test 5 OK
gl_FragData[0] = 2.0*vi; // test 6 KO
}
test 1 OK. I get back the correct values set from GLSL. So the formats from java and GLSL seems to be the same.
test 2 OK. I get back the correct mid-texel values (like 0.5 0.5 0.5 1.0 | 1.5 0.5 0.5 1.0 …)
test 3 OK. I get back exactly the values I’ve put from java (1.0 2.0 3.0 4.0 | 5.0 6.0 …)
test 4 OK. dito
test 5 OK. correct values (ie input values with the sign inverted.)
test 6 ARGH. does not work as I expect. Rather than returning 2.0 4.0 6.0 8.0 | 10.0 12.0 … it gives me strange values.
5.902958E20 1.1805916E21 1.7708874E21 2.3611832E21 | 2.951479E21 3.541775E21 4.1320707E21 4.7223665E21 |
5.3126623E21 5.902958E21 6.493254E21 7.08355E21 | 7.6738455E21 8.2641413E21 8.854437E21 9.444733E21 |
So… what am I missing there?
Probably a stupid misconception but I can’t go further without understanding that!
Thx for your help.
Olivier
PS: I’m using a 7800GT with 93.71 drivers, jogl-1.1.0-pre-20061214-windows-i586 and JSE 6