Search code examples
androidopengl-estextures

OpenGL Textures have distorted colors on some android devices


I am uploading loading images as textures to GLSurfaceView. The resulting textures look perfectly fine on some devices, on others the appear completely distorted.

This is what it looks like on a Samsung Galaxy Nexus (screen density 2.0): enter image description here

The same images on a Motorola (screen density 1.5):
enter image description here

Here is my loading code:

FutureTask<Integer> futureTask = new FutureTask<Integer>(new Callable<Integer>() {
    @Override
    public Integer call() throws Exception {

        // Generate Texture
        int[] texturenames = new int[1];
        GLES20.glGenTextures(1, texturenames, 0);

        // Bind texture to texturename
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texturenames[0]);

        // Set filtering
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
                GLES20.GL_LINEAR);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,
                GLES20.GL_LINEAR);

        // Set wrapping mode
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);

        // Correct the bitmap if its not a power of two
        Bitmap potTextureBitmap = textureBitmap;
        int potWidth = nextPOT(textureBitmap.getWidth());
        int potHeight = nextPOT(textureBitmap.getHeight());
        if ((textureBitmap.getWidth() != potWidth) || (textureBitmap.getHeight() != potHeight)) {
            potTextureBitmap = Bitmap.createScaledBitmap(textureBitmap, potWidth, potHeight, false);
        }

        // Load the bitmap into the bound texture.
        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, potTextureBitmap, 0);

        GLES20.glFlush();

        return Integer.valueOf( texturenames[0]);
    }
});

this.mSurfaceView.queueEvent(futureTask);

What am I doing wrong?


Solution

  • I finally found the cause of this problem. Its rather specific, but I'll share the details anyhow:

    There turned out to be an error in my color calculation. I need to convert from Hex colors to normalized rgba (in my case convert white #ffffffff to {1.0, 1.0, 1.0, 1.0}), but I actually fed non-normalized values into my shader (example: {255, 255, 255, 255}). When multiplied with the color from my texture, the resulting colors would blow up. Depending on the graphic card this caused the artifacts or not. So the assumed dependency on the screen resolution was pure coincidence!