Float format? Bug or misconception?

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

What about these versions:
gl_FragData[0] = vec4(2.0) * vi;
gl_FragData[0] = vi + vi;
gl_FragColor = vec4(2.0) * vi;

Don’t you need to use
#extension ARB_draw_buffers : enable
to use gl_FragData?

Use nvEmulate to dump the assembly code and look if there’s a problem in the generated code.
http://developer.nvidia.com/object/nvemulate.html

Hum,…
In fact it works very well… so well that it did work toot fast for me to notice that I was going through many loops (the debug trace was too verbose for me to notice)
So… the “strange” values were only due to the 222*2…*initial value.
Please dont laugh at me, at least not loud enough for me to ear :wink:
Thx anyway Relic!

To conclude, if someone wants to use the code above, it works fine!

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.