Search code examples
opengl-esfbo

Opengl-es 1.1 greyscale the FBO


I have the FBO, I just load it to a texture and an ortho (2D) mesh. How can I greyscale down my FBO texture?


Solution

  • Apple uses the following OpenGL ES 1.1 code for converting an image to grayscale in their GLImageProcessing sample:

    static void greyscale(V2fT2f *quad, float t)    // t = 1 for standard perceptual weighting
    {
        GLfloat lerp[4] = { 1.0, 1.0, 1.0, 0.5 };
        GLfloat avrg[4] = { .667, .667, .667, 0.5 };    // average
        GLfloat prcp[4] = { .646, .794, .557, 0.5 };    // perceptual NTSC
        GLfloat dot3[4] = { prcp[0]*t+avrg[0]*(1-t), prcp[1]*t+avrg[1]*(1-t), prcp[2]*t+avrg[2]*(1-t), 0.5 };
    
        // One pass using two units:
        // Unit 0 scales and biases into [0.5..1.0]
        // Unit 1 dot products with perceptual weights
    
        glVertexPointer  (2, GL_FLOAT, sizeof(V2fT2f), &quad[0].x);
        glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &quad[0].s);
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
        glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,      GL_INTERPOLATE);
        glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB,         GL_TEXTURE);
        glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB,         GL_CONSTANT);
        glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB,         GL_CONSTANT);
        glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,    GL_REPLACE);
        glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA,       GL_TEXTURE);
        glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR, lerp);
    
        // Note: we prefer to dot product with primary color, because
        // the constant color is stored in limited precision on MBX
        glActiveTexture(GL_TEXTURE1);
        glEnable(GL_TEXTURE_2D);
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
        glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,      GL_DOT3_RGB);
        glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB,         GL_PREVIOUS);
        glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB,         GL_PRIMARY_COLOR);
        glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,    GL_REPLACE);
        glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA,       GL_PREVIOUS);
    
        glColor4f(dot3[0], dot3[1], dot3[2], dot3[3]);
        validateTexEnv();
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    
        // Restore state
        glDisable(GL_TEXTURE_2D);
        glActiveTexture(GL_TEXTURE0);
    }
    

    I've completely given up 1.1 now, particularly for image processing, but greyscale conversion is one of the few effects you can pull off in 1.1.