View Full Version : Float format? Bug or misconception?

12-14-2006, 12:03 PM
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);
glu.gluOrtho2D(0.0, texSize, 0.0, texSize);
gl.glViewport(0, 0, texSize, texSize);
gl.glDrawBuffer(GL.GL_COLOR_ATTACHMENT1_EXT);The vertex/fragment shaders are applied using a single quad

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.glReadPixels(0, 0, texSize, texSize, GL.GL_RGBA, GL.GL_FLOAT, FloatBuffer.wrap(result));The shaders are:

void main(){
gl_Position = ftransform();
gl_TexCoord[0] = gl_MultiTexCoord0;

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.


PS: I'm using a 7800GT with 93.71 drivers, jogl-1.1.0-pre-20061214-windows-i586 and JSE 6

12-15-2006, 12:57 AM
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.

12-15-2006, 02:55 AM
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 2*2*2*2....*initial value.
Please dont laugh at me, at least not loud enough for me to ear ;)
Thx anyway Relic!

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