Search code examples
androidopengl-esgradient

Android OpenGL-ES gradient background


I would like to have a gradient background in OpenGL

I found these two links, but I cannot reproduce it:

OpenGL gradient fill on iPhone looks striped

OpenGL gradient banding on Android

I tried the following of the first link:

    // Begin Render
    //IntBuffer redBits = null, greenBits = null, blueBits = null;
    //gl.glGetIntegerv (GL10.GL_RED_BITS, redBits); // ==> 8
    //gl.glGetIntegerv (GL10.GL_GREEN_BITS, greenBits); // ==> 8
    //gl.glGetIntegerv (GL10.GL_BLUE_BITS, blueBits); // ==> 8

    gl.glDisable(GL10.GL_BLEND);
    gl.glDisable(GL10.GL_DITHER);
    gl.glDisable(GL10.GL_FOG);
    gl.glDisable(GL10.GL_LIGHTING);
    gl.glDisable(GL10.GL_TEXTURE_2D);
    gl.glShadeModel(GL10.GL_SMOOTH);

    float[] vertices = {
        0, 0,
        320, 0,
        0, 480,
        320, 480,
    };
    FloatBuffer vertsBuffer = makeFloatBuffer(vertices); 

    int[] colors = {
    255, 255, 255, 255,
    255, 255, 255, 255,
    200, 200, 200, 255,
    200, 200, 200, 255,
    };
    
    IntBuffer colorBuffer = makeIntBuffer(colors);

    gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertsBuffer);
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glColorPointer(4, GL10.GL_UNSIGNED_BYTE, 0, colorBuffer);
    gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
    // End Render




protected static FloatBuffer makeFloatBuffer(float[] arr) {
    ByteBuffer bb = ByteBuffer.allocateDirect(arr.length*4);
    bb.order(ByteOrder.nativeOrder());
    FloatBuffer fb = bb.asFloatBuffer();
    fb.put(arr);
    fb.position(0);
    return fb;
}

protected static IntBuffer makeIntBuffer(int[] arr) {
    ByteBuffer bb = ByteBuffer.allocateDirect(arr.length*4);
    bb.order(ByteOrder.nativeOrder());
    IntBuffer ib = bb.asIntBuffer();
    ib.put(arr);
    ib.position(0);
    return ib;
}

But it just shows a rectangle in the right upper corner. But I don't know if the

glGetIntegerv

would have an effect? Any ideas/links how to make it run?

SOLUTION

    // set orthographic perspective
    setOrtho2D(activity, gl);
    
    gl.glDisable(GL10.GL_BLEND);
    //gl.glDisable(GL10.GL_DITHER);
    gl.glDisable(GL10.GL_FOG);
    gl.glDisable(GL10.GL_LIGHTING);
    gl.glDisable(GL10.GL_TEXTURE_2D);
    gl.glShadeModel(GL10.GL_SMOOTH);

    float[] vertices = {
            0, 0,
            _winWidth, 0,
            0, _winHeight,
            _winWidth, _winHeight
        };
    
    FloatBuffer vertsBuffer = makeFloatBuffer(vertices); 

    float[] colors = {
    1.0f, 1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f, 1.0f,
    0.2f, 0.2f, 0.2f, 1.0f,
    0.2f, 0.2f, 0.2f, 1.0f
    };

    FloatBuffer colorBuffer = makeFloatBuffer(colors);

    gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertsBuffer);
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);
    gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);

I forgot to comment in the perspective line again. I also changed the vertices layed order from "U" shape to the "Z" shape (as commented from Nick). Now it looks like how I want it:android_gradient_background


Solution

  • This is a problem:

    int[] colors;
    ....
    gl.glColorPointer(4, GL10.GL_UNSIGNED_BYTE, 0, colorBuffer);
    

    You are using signed four-byte integers for your color channels, and then telling opengl that they are unsigned one-byte integers. You should be using a buffer full of unsigned bytes.

    It would be easier however, to just use floats instead:

    float[] colors = {
        1.0f, 1.0f, 1.0f, 1.0f,
        1.0f, 1.0f, 1.0f, 1.0f,
        0.5f, 0.5f, 0.5f, 1.0f,
        0.5f, 0.5f, 0.5f, 1.0f,
        };
    
    float vertices[] = {
        0,  0,
        800, 0,
        0, 480,
        480, 800,
        };
    
    FloatBuffer colorBuffer = makeFloatBuffer(colors);
    
    gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);