简体   繁体   中英

Android OpenGL ES 2.0 Textures not working at some sizes

I just discovered a really bizarre problem with my app.

This problem occurs when it is run on my phone.

I was loading a bitmap (to be used as an Open GL Texture) like so:

 tiles = BitmapFactory.decodeResource(view.getResources(), R.drawable.tilespic, BMFOptions);

BMFOptions is setting the following line:

BMFOptions.inPreferredConfig = Bitmap.Config.RGB_565;

When I ran my app, what happened initially was that the texture appeared as just a black square. So, I tried it on another device (a tablet) and it ran perfectly.

I know that if the bitmap has an alpha channel, BitmapFactory will just load it as ARGB_8888 if Bitmap.Config.RGB_565 has been specified and I have confirmed this with other bitmaps (by calling getConfig). This bitmap does have Alpha.

However, when I call getConfig on it, it returns null (only when RGB_565 is specified and only on this one bitmap/texture - on this device).

What I've tried

If I set it to ARGB_8888 or just omit BMFOptions for this bitmap, then everything displays correctly.

If I set it to ARGB_4444 (just for testing), then it does display but the textures are crooked/at an angle, (again just this bitmap/texture).

So, what I did was resize the original bitmap (original size - 100 x 909).

I resized it to 505 x 201, 506 x 201 and a multitude of other sizes and it still didn't work (Note these are sprite sheets so, these sizes are just how to they worked out).

I then resized it to 506 x 204 and it did work. I then tried it at 1880 x 921 and it worked again.

I'm not using NPOT textures and have never had a problem before, bear in mind that I also have other textures with odd sizes such as 1880 x 921 and 1000 x 885 and these behave perfectly on this phone (but obviously their pixel data / layout is different).

As this bitmap has alpha (which I need), I am simply removing the BMFOptions for this particular bitmap for now and allowing it to load as ARGB_8888, however, I would like to know any possible reasons for this odd behaviour.

If it helps, this is the code I use to load my textures....

    public static int LoadTexture(GLSurfaceView view, Bitmap imgTex){

        int textures[] = new int[1];
        try {

            GLES20.glGenTextures(1, textures, 0);
            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
            GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
            GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);

            GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, imgTex, 0);

            GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,GLES20.GL_CLAMP_TO_EDGE);
            GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,GLES20.GL_CLAMP_TO_EDGE);

        } catch (Exception e){
          }
        textureCount++;     
        return textures[0];
    }

Some phones can only use textures with power of 2 sizes.
eg 256x256, 512x512, 1024x128 will work
300x300, 512x100, etc. won't work.

This is a requirement of the OpenGL ES 2.0 standard (afaik 3.0 relaxes this). Some phones will work with non-pow-of-2 textures, but it's not mandatory to do so. Sticking to pow-of-2 textures is the safe way to go if you wish to target as much phones as possible.

If this is not the problem, see if you get any GLErrors .

Also i just noticed: you are using GL10.GL_TEXTURE_2D, while in the other lines you are using GLES20.*. I looked it up and GL_TEXTURE_2D is defined as 3553 in both places, but still it would look better if you used GLES20 there as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM