Odd FBO behavior w.r.t. texturing in shaders

I’m having a problem using texturing in fragment shaders while rendering to an FBO.

The library I’m working on does all of its rendering to FBOs, so I know the FBO rendering is working in all cases except when shaders are using texturing. Shaders that use no texturing also work fine. The problem with texturing is that I get a vec4(0.0) back, no matter what. I’ve verified that the texture I’m using is populated correctly (and contains no all-zero texels).

Here are the vertex shader:


void main ()
{ gl_Position = ftransform(); }

the fragment shader:


uniform sampler1D tex;
uniform mat4 matrix;
uniform vec2 circle_1;
uniform float radius_0;
uniform float radius_1;

void main ()
{
    vec2 pos = (matrix * vec4 (gl_FragCoord.xy, 0.0, 1.0)).xy;
    
    float dr = radius_1 - radius_0;
    float dot_circle_1 = dot (circle_1, circle_1);
    float dot_pos_circle_1 = dot (pos, circle_1);
    
    float A = dot_circle_1 - dr * dr;
    float B = -2.0 * (dot_pos_circle_1 + radius_0 * dr);
    float C = dot (pos, pos) - radius_0 * radius_0;
    float det = B * B - 4.0 * A * C;
    det = max (det, 0.0);
    
    float sqrt_det = sqrt (det);
    /* This complicated bit of logic acts as
     * "if (A < 0.0) sqrt_det = -sqrt_det", without the branch.
     */
    sqrt_det *= 1.0 + 2.0 * sign (min (A, 0.0));
    
    float t = (-B + sqrt_det) / (2.0 * A);
    gl_FragColor = texture1D (tex, t);
}

and the code (boiled down from a Bugle trace):


    GLuint tex1, tex2, tex3;
    GLuint fb1;
    GLint max_texture_size;
    GLuint vert_shader, frag_shader, program;
    GLint status, loc;
    unsigned int pixels[600 * 350];

    const GLchar* vert_text[] = { /*...*/ };
    const GLchar* frag_text[] = { /*...*/ };

    float matrix[16] = {
        0, -52.7967, 0, 9239.42,
        -90.5086, 0, 0, 27152.6,
        0, 0, 1, 0,
        0, 0, 0, 1
    };
    GLint vertices[8] = {
        0, 0,
        0, 350,
        600, 350,
        600, 0
    };

    glGenTextures(1, &tex1);
    glBindTexture(GL_TEXTURE_2D, tex1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
    glGenTextures(1, &tex2);
    glBindTexture(GL_TEXTURE_2D, tex2);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 600, 350, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glGenFramebuffersEXT(1, &fb1);
    glBindFramebufferEXT(GL_FRAMEBUFFER, fb1);
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2, 0);
    glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
    glBindFramebufferEXT(GL_FRAMEBUFFER, fb1);
    glDrawBuffer(GL_COLOR_ATTACHMENT0);
    glReadBuffer(GL_COLOR_ATTACHMENT0);
    glViewport(0, 0, 600, 350);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, 600, 0, 350, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glClearColor(0, 0, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT);
    vert_shader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vert_shader, 1, vert_text, NULL);
    glCompileShader(vert_shader);
    glGetShaderiv(vert_shader, GL_COMPILE_STATUS, &status);
    frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(frag_shader, 1, frag_text, NULL);
    glCompileShader(frag_shader);
    glGetShaderiv(frag_shader, GL_COMPILE_STATUS, &status);
    program = glCreateProgram();
    glAttachShader(program, vert_shader);
    glAttachShader(program, frag_shader);
    glLinkProgram(program);
    glGetProgramiv(program, GL_LINK_STATUS, &status);
    glPushAttrib(GL_ALL_ATTRIB_BITS);
    glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
    glBindFramebufferEXT(GL_FRAMEBUFFER, fb1);
    glDrawBuffer(GL_COLOR_ATTACHMENT0);
    glReadBuffer(GL_COLOR_ATTACHMENT0);
    glViewport(0, 0, 600, 350);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, 600, 0, 350, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    glActiveTexture(GL_TEXTURE0);
    glClientActiveTexture(GL_TEXTURE0);
    glGenTextures(1, &tex3);
    glBindTexture(GL_TEXTURE_1D, tex3);
    glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA8, 8192, 0, GL_RGBA, GL_UNSIGNED_BYTE, gradient_data);
    glUseProgram(program);
    loc = glGetUniformLocation(3, "tex");
    glUniform1i(loc, 0);
    loc = glGetUniformLocation(3, "matrix");
    glUniformMatrix4fv(loc, 1, GL_TRUE, matrix);
    loc = glGetUniformLocation(3, "circle_1");
    glUniform2f(loc, 0, 0);
    loc = glGetUniformLocation(3, "radius_0");
    glUniform1f(loc, 0);
    loc = glGetUniformLocation(3, "radius_1");
    glUniform1f(loc, 16384);
    glVertexPointer(2, GL_INT, 0, vertices);
    glEnableClientState(GL_VERTEX_ARRAY);
    glDrawArrays(GL_QUADS, 0, 4);
    glUseProgram(0);
    glDeleteTextures(1, &tex3);
    glPopClientAttrib();
    glPopAttrib();
    glBindFramebufferEXT(GL_FRAMEBUFFER, fb1);
    glDrawBuffer(GL_COLOR_ATTACHMENT0);
    glReadBuffer(GL_COLOR_ATTACHMENT0);
    glViewport(0, 0, 600, 350);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, 600, 0, 350, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glPixelStorei(GL_PACK_ALIGNMENT, 1);
    glPixelStorei(GL_PACK_ROW_LENGTH, 600);
    glReadPixels(0, 0, 600, 350, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, &pixels);
    glGetError();
    glDeleteFramebuffersEXT(1, &fb1);
    glDeleteTextures(1, &tex2);
    glDeleteTextures(1, &tex1);
    glDeleteShader(vert_shader);
    glDeleteShader(frag_shader);
    glDeleteProgram(program);
    glDeleteShader(0);
    glDeleteShader(0);
    glDeleteProgram(0);

I know there are some extraneous calls, and I’ve tried to remove as much code as possible, but nothing seems to fix the all-zeros texturing problem. If I replace the last line of the fragment shader with “gl_FragColor = vec3(t, t, t, 1.0);”, I get a radial gradient, dark in the center and white at the edges – just as I expect. But when I use “t” to look up a texel, I get vec4(0.0), as I said before.

Also, while investigating this issue, I built another small test app that uses texturing in a fragment shader while rendering to an FBO with no problems, so I don’t suspect a system config issue.

Any Ideas? I’m stumped.

Thanks in advance.

Fixed. I wasn’t setting the min/mag filters. Setting them not to use mipmap levels fixed the problem.