Hi everybody, I'm working on a Live Wallpaper that shows a waving flag in two different fashions:
- "fullscreen" in which all you can see is a waving cloth that fills the screen;
- "standard" that shows the flag attached to a pole.
Everything works just fine except for the fact that I can't display a bitmap behind my scene when I'm in "standard" mode. The bitmap should act like a background for the displayed scene.
I premise that I'm very new to 3d and OpenGL so it's just my fault not being able to achieve what I want.
I tried to use the FrameBuffer.blit(Texture [...]) method but it slows down too much my animation. Right now I'm using a 512x512 bitmap. This size is not fixed because users will be able to select from their gallery a custom image to set as background. Anyway I've already written an interactive ImageCropper that outputs only 2^x px squared bitmaps.
The way I'm using the blit method right now is the following:
framebuffer.blit(TextureManager.getInstance().getTexture(background),0,0,0,0,512,512,FrameBuffer.OPAQUE_BLITTING);
So I tried to look for different approaches.
I read somewhere that if I clear my framebuffer using an RBG whith alpha value assigned, I can make it transparent.
Since, as I said, I'm not able to write OpenGL on my own, I surfed the net looking for some code snippets that would fit my needs.
I found
this tutorial and after a little of tweaking I've been able to show my bitmap in front of my 3d model. It basically draws a square with a texture but I couldn't place the square behind my Object3D. I don't know if this is caused by the fact that the framebuffer isn't transparent or just because I'm incapable (probably is the second because I was basically trying to draw the square before clearing the framebuffer...)
I've also tried to set the background in the WallpaperService.Engine that creates and manages my Renderer:
in onSurfaceChanged(SurfaceHolder holder, int format, int width, int height), I call the following method:
private void drawFrame() {
final SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
c = holder.lockCanvas();
if (c != null) {
Bitmap background = BitmapFactory.decodeResource(getResources(), R.drawable.sky_day);
Rect dest = new Rect(0, 0, width, height);
Paint paint = new Paint();
paint.setFilterBitmap(true);
c.drawBitmap(background, null, dest, paint);
}
} finally {
if (c != null) holder.unlockCanvasAndPost(c);
}
// Reschedule the next redraw
mHandler.removeCallbacks(mDrawCube);
if (mVisible) {
mHandler.postDelayed(mDrawCube, 1000 / 25);
}
}
The above method gets then rescheduled using an android.os.Handler.
What I got is a flickering image that switches very fast bethwin the 3d scene and the background, probably because I work on the same surface using concurrent threads. So I tried to call the above method in my Renderer's drawFrame(GL10 gl) but I got the following error: "CPU may be pegged" that probably have to do with that lock on the Canvas...
So what I want to know is:
Are there any other ways to set a bitmap as background for a scene?
Otherwise, what is the correct way to blit a bitmap without significant frame rate loss?
Thanks, and apologise me for my inaccuracies and for wasting your time with such newbie's questions..