本文是一个android动态壁纸的例子,利用android_ndk调用底层的C++代码,使用OpenGLES来绘制动态壁纸。仅作参考。
首先是定义我们自己的Renderer类,FireWallpaperRenderer实现了GLWallpaperService.Renderer接口(GLWallpaperService的代码在《android利用OpenGLES开发动态壁纸用到的GLWallpaperService类》的那篇博客里):
import java.io.IOException;
import java.io.InputStream;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
import android.util.Log;
public class FireWallpaperRenderer implements GLWallpaperService.Renderer {
//用于纹理映射的绑定,并把绑定后的地址传递给C++代码,供其调用
private int[] texture = new int[2];
//用于加载Bitmap的context
private Context mContext;
//FireWallpaperRenderer构造函数,用来初始化mContext
public FireWallpaperRenderer(Context context){
mContext = context;
}
/**
* 渲染场景的代码,这里我们是通过调用底层C++的代码来实现的,
* 这样能得到更好地运行速度
* */
@Override
public void onDrawFrame(GL10 gl) {
//调用本地onDrawFrame方法
FireNativeMethod.onDrawFrame(gl);
}
/**
* 处理屏幕尺寸发生变化时的代码,
* 用来重新设置场景的大小和其他一些属性,
* 也是通过调用底层C++代码来实现
* */
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
//调用本地onSurfaceChanged方法
FireNativeMethod.onSurfaceChanged(gl, width, height);
}
/**
* 初始化OpenGL场景,
* 用来设置场景的一些属性,
* 也是通过调用底层C++代码来实现
* */
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
//用来绑定Bitmap纹理
bindTexture(gl, mContext);
//调用本地setTexture方法,把纹理绑定的地址传递给C++代码,以供其调用
FireNativeMethod.setTexture(texture);
//调用本地onSurfaceCreated方法
FireNativeMethod.onSurfaceCreated(gl, config);
}
/**
* 用来绑定Bitmap纹理的代码,
* 因为暂时没有找到在C++代码中绑定Bitmap纹理的方法,
* 所以暂且在java层绑定Bitmap纹理
* */
private void bindTexture(GL10 gl, Context context) {
//生成纹理
gl.glGenTextures(2, texture, 0);
//加载Bitmap
Bitmap bitmap = loadBitmap(context, R.drawable.floor);
if (bitmap != null) {
Log.i("firewallpaperrenderer", "bind the floor texture");
//如果bitmap加载成功,则生成此bitmap的纹理映射
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[0]);
//设置纹理映射的属性
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_NEAREST);
//生成纹理映射
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
//释放bitmap资源
bitmap.recycle();
}
bitmap = loadBitmap(context, R.drawable.fire);
if (bitmap != null) {
//同上
Log.i("firewallpaperrenderer", "bind the fire texture");
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[1]);
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_NEAREST);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
}
}
/**
* 加载Bitmap的方法,
* 用来从res中加载Bitmap资源
* */
private Bitmap loadBitmap(Context context, int resourceId) {
InputStream is = context.getResources().openRawResource(resourceId);
Bitmap bitmap = null;
try {
// 利用BitmapFactory生成Bitmap
bitmap = BitmapFactory.decodeStream(is);
} finally {
try {
// 关闭流
is.close();