How to pass float data into the fragment shader and back out in openGL ES?

Hi, I have been studying openGL ES for a week now, and I am not sure how to get float data in and out using FBO. Here are my C codes which gives no error:

    /* allocate CPU memory */
    float *dens = (float *) malloc (4*(W)*(H)*sizeof(float));
    float* result = (float*) malloc (4*W*H*sizeof(float));

    for (int i = 0; i < 4*W*H; i++) {
        dens[i] = 10;
        result[i] = 0;
    }
    /* create FBO */
    GLuint FBO;
    glGenFramebuffers(1, &FBO);
    glBindFramebuffer(GL_FRAMEBUFFER, FBO);

    /* create input texture */
    GLuint dens_gl;
    glGenTextures(1, &dens_gl);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, dens_gl);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, W, H, 0, GL_RGBA, GL_FLOAT, dens);
    
    GLint Loc;
    Loc = glGetUniformLocation(_program, "dens_gl");
    glUniform1i(Loc, 0);
    
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dens_gl, 0);

    /* read GPU memory to result pointer */
    glReadBuffer(GL_COLOR_ATTACHMENT0);
    glReadPixels(0, 0, W, H,GL_RGBA,GL_FLOAT, result);

I have already set the vertex shader to the corners so my fragment shader becomes pixel shader. I then try to do some calculations in fsh:

    uniform sampler2D dens_gl;
void main(void) {
    float d = texture2D(dens_gl, uv).r;
    d = d*0.5;
    gl_FragColor = vec4(d,d,d,1.0);
}

but the result pointer at the end only holds the same value as the dens CPU memory ( from 0 changed to 10). What did I do wrong? I have used glgeterror function everywhere and I do not receive an error.

You might post a short, standalone test program that folks can compile and run locally on their PC and use to spot things that aren’t in your snippet (such as a bind of the program object and a draw call, both of which aren’t present in your snippet). You might also check that glGetUniformLocation is returning a non-negative value.

I also don’t see an explicit set of GL_PACK_ALIGNMENT, but in your case the default value of 4 should be just as good as 1.