markfguerra / GLWallpaperService

Please submit issues and pull requests to the main repository
https://github.com/GLWallpaperService/GLWallpaperService
Apache License 2.0
218 stars 114 forks source link

Bitmaps loaded via Resource does not work #9

Closed timwillhack closed 13 years ago

timwillhack commented 13 years ago

I had an opengl project that worked fine prior to integrating it as a wallpaper service. Now it will not load textures from R. I verified I am able to texture in 3d by creating a bitmap and drawing to it randomly then using that bitmap instead and it works fine.

It is possible its related to something like wallpaper apps do not have the same bit depth or are not allowed to have alpha textures or something, but I've hit a wall.

markfguerra commented 13 years ago

Hmm, I was able to get textures to work on my particular wallpaper project.

When I get the chance, I will share my texture loading code here and we can compare notes on this issue.

markfguerra commented 13 years ago

Here is a method that worked for me in a wallpaper. I can't guarantee that it's 100% correct, so constructive input is welcome. Let me know if this helps you.

As always, make sure the dimensions of your images are in powers of 2.

First create these objects, for example, as members in a class: private FloatBuffer textureBuffer; private int[] textures = new int[1]; // Our texture pointer

Add this to your setup method where you create your other buffers { //...

    //Enable Texture mapping
    gl.glEnable(GL10.GL_TEXTURE_2D);

    float[] textureCoords = {
            //Mapping coordinates for the vertices
            0.0f, 0.0f,
            0.0f, 1.0f,
            1.0f, 0.0f,
            1.0f, 1.0f
    };

    textureBuffer = BufferFactory.createFloatBuffer(textureCoords.length);
    textureBuffer.put(textureCoords);
    textureBuffer.position(0);

    setTexture(gl, context, R.drawable.yourtexturehere);

    //...
}

Add this to your draw() method public void draw(GL10 gl) { gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

    gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);

    //Set OpengGL to use this texture.
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

    //Draw as normal. Set up your vertex pointer
    //gl.glVertexPointer(...);

    //Do your drawing
    gl.glDrawElements(...);

    //You may want to turn this off depending on your situation
    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}

Here is the function that does the loading of a texture from a resource /* * Load the textures * * @param gl - The GL Context * @param context - The android context * @param texture - The texture's resource id / public void setTexture(GL10 gl, Context context, int texture) { //Get the texture from the Android resource directory InputStream is = context.getResources().openRawResource(texture); Bitmap bitmap = null; try { //BitmapFactory is an Android graphics utility for images bitmap = BitmapFactory.decodeStream(is);

    } finally {
        //Always clear and close
        try {
            is.close();
            is = null;
        } catch (IOException e) {
        }
    }

    //Generate one texture pointer...
    gl.glGenTextures(1, textures, 0);
    //...and bind it to our array
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

    //Rotate texture so it's right-side up
    gl.glMatrixMode(GL10.GL_TEXTURE);
    gl.glLoadIdentity();
    gl.glRotatef(-90f, 0f, 0f, 1f);
    gl.glMatrixMode(GL10.GL_MODELVIEW);

    //Create Nearest Filtered Texture
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

    //Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);

    //Use the Android GLUtils to specify a two-dimensional texture image from our bitmap
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

    //Clean up
    bitmap.recycle();
}
timwillhack commented 13 years ago

Hey Mark,

You are the man. Like I said it worked before with this code (for people with a similar problem): bitmap = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.shinybox);

but when I changed it to this now its fine: InputStream is = context.getResources().openRawResource(texture); Bitmap bitmap = null; try { //BitmapFactory is an Android graphics utility for images bitmap = BitmapFactory.decodeStream(is);

           } finally {
                   //Always clear and close
                   try {
                           is.close();
                           is = null;
                   } catch (IOException e) {
                   }
           }

I'm new to opengl and android, did a normal canvas blackjack app, and then switched to iphone opengl so its nice to get it rolling from your samples and your wallpaper service - Thank you!

markfguerra commented 13 years ago

Glad I could help. Thanks for the code should go to Robert Green, the Android Open Source Project, and other testers and coders that have been helping along the way. Good luck with your project and keep reporting bugs.