Android OpenGL动态壁纸

news/2024/11/28 19:29:42/

Android OpenGL动态壁纸

首先申明下,本文为笔者学习《OpenGL ES应用开发实践指南》的笔记,并加入笔者自己的理解和归纳总结。

1、动态壁纸的Service组件

WallpaperService提供了基本的动态壁纸的实现。
public class GLWallpaperService extends WallpaperService {@Overridepublic Engine onCreateEngine() {return new GLEngine();}}

2、创建自定义GLSurfaceView

GLSurfaceView会调用getHolder()来添加界面,只需重载getHolder方法,返回动态壁纸的渲染表面。onWallpaperDestroy在销毁动态壁纸时被调用,使用GLSurfaceView的onDetachedFromWindow方法。
class WallpaperGLSurfaceView extends GLSurfaceView {public WallpaperGLSurfaceView(Context context) {super(context);}@Overridepublic SurfaceHolder getHolder() {return GLEngine.this.getSurfaceHolder();}public void onWallpaperDestroy() {super.onDetachedFromWindow();}
}

3、Engine类

GLEngine继承Engine类,当动态壁纸创建时,调用GLEngine的onCreate方法来初始化,销毁时调用onDestroy方法。当动态壁纸可见或者隐藏时,onVisibilityChanged方法会被调用。
public class GLEngine extends Engine {@Overridepublic void onCreate(SurfaceHolder surfaceHolder) {super.onCreate(surfaceHolder);}@Overridepublic void onVisibilityChanged(boolean visible) {super.onVisibilityChanged(visible);}@Overridepublic void onDestroy() {super.onDestroy();}}
完善动态壁纸的生命周期,在onCreate中创建GLSurfaceView,onDestroy中销毁。
private WallpaperGLSurfaceView mSurfaceView;@Override
public void onCreate(SurfaceHolder surfaceHolder) {super.onCreate(surfaceHolder);mSurfaceView = new WallpaperGLSurfaceView(GLWallpaperService.this);
}public void onVisibilityChanged(boolean visible) {super.onVisibilityChanged(visible);if (mRender) {if (visible) {mSurfaceView.onResume();} else {mSurfaceView.onPause();}}
}@Override
public void onDestroy() {super.onDestroy();mSurfaceView.onWallpaperDestroy();
}

4、添加配置

在AndroidManifest.xml中添加
<uses-feature android:name="android.software.live_wallpaper" />
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
表明这个应用包含一个动态壁纸,并且还需要OpenGL ES 2.0或以上版本。
还需要添加动态壁纸Service的引用
<service android:name=".opengl.GLWallpaperService"android:label="@string/app_name"android:permission="android.permission.BIND_WALLPAPER" ><intent-filter><action android:name="android.service.wallpaper.WallpaperService" /></intent-filter><meta-dataandroid:name="android.service.wallpaper"android:resource="@xml/wallpaper" />
</service>
在资源目录res/xml下,添加wapaper.xml文件
<?xml version="1.0" encoding="utf-8"?>
<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"android:thumbnail="@drawable/ic_wallpaper" />

5、体验动态壁纸

(1) 切换到设备的主屏幕上,按住屏幕的空白部分,直至弹出一个菜单。
(2) 选择"动态壁纸",从弹出的列表中选择我们自己的动态壁纸。
(3) 选择"设置壁纸"


6、随主屏幕滚动背景

当你在主屏幕上的不同页面之间来回滑动时,动态壁纸没有移动,通过Engine的onOffsetsChanged方法,可以是实现动态壁纸的滚动效果。
public void onOffsetsChanged(final float xOffset, final float yOffset, float xOffsetStep,float yOffsetStep, int xPixelOffset, int yPixelOffset) {mSurfaceView.queueEvent(new Runnable() {@Overridepublic void run() {mShaderRender.handleOffsetsChanged(xOffset, yOffset);}});
}

7、GLWallpaperService类

public class GLWallpaperService extends WallpaperService {@Overridepublic Engine onCreateEngine() {return new GLEngine();}public class GLEngine extends Engine {private WallpaperGLSurfaceView mSurfaceView;private OpenGLParticleShaderRender mShaderRender;private boolean mRender;@Overridepublic void onCreate(SurfaceHolder surfaceHolder) {super.onCreate(surfaceHolder);mSurfaceView = new WallpaperGLSurfaceView(GLWallpaperService.this);ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);ConfigurationInfo configurationInfo = am.getDeviceConfigurationInfo();boolean supportEs2 = configurationInfo.reqGlEsVersion >= 0x20000;if (supportEs2) {// 选择OpenGL ES 2.0mSurfaceView.setEGLContextClientVersion(2);mShaderRender = new OpenGLParticleShaderRender();// 设置渲染mSurfaceView.setRenderer(mShaderRender);mRender = true;} else {Toast.makeText(GLWallpaperService.this ,"This device does not support OpenGL ES 2.0",Toast.LENGTH_LONG).show();}}@Overridepublic void onVisibilityChanged(boolean visible) {super.onVisibilityChanged(visible);if (mRender) {if (visible) {mSurfaceView.onResume();} else {mSurfaceView.onPause();}}}@Overridepublic void onDestroy() {super.onDestroy();mSurfaceView.onWallpaperDestroy();}@Overridepublic void onOffsetsChanged(final float xOffset, final float yOffset, float xOffsetStep,float yOffsetStep, int xPixelOffset, int yPixelOffset) {mSurfaceView.queueEvent(new Runnable() {@Overridepublic void run() {LogUtil.log("GLEngine", "xOffset = " + xOffset + ", yOffset = " + yOffset);mShaderRender.handleOffsetsChanged(xOffset, yOffset);}});}class WallpaperGLSurfaceView extends GLSurfaceView {public WallpaperGLSurfaceView(Context context) {super(context);}@Overridepublic SurfaceHolder getHolder() {return GLEngine.this.getSurfaceHolder();}public void onWallpaperDestroy() {super.onDetachedFromWindow();}}}private class OpenGLParticleShaderRender implements GLSurfaceView.Renderer {private Particle mParticle;private ParticleProgram mParticleProgram;private ParticleShooter mRedParticleShooter, mGreenParticleShooter, mBlueParticleShooter;private long mGlobalStartTime;private float[] projectionMatrix = new float[16];private float[] viewMatrix = new float[16];private float[] viewProjectionMatrix = new float[16];private float xOffset, yOffset;@Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config) {GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.1f);GLES20.glEnable(GLES20.GL_BLEND);GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE);mParticleProgram = new ParticleProgram(GLWallpaperService.this);mParticle = new Particle(10000);mGlobalStartTime = System.nanoTime();final Geometry.Vector particleDirection = new Geometry.Vector(0f, 0.5f, 0f);mRedParticleShooter = new ParticleShooter(new Geometry.Point(-1, 0, 0),particleDirection, Color.rgb(250, 50, 5));mGreenParticleShooter = new ParticleShooter(new Geometry.Point(0, 0, 0),particleDirection, Color.rgb(25, 255, 25));mBlueParticleShooter = new ParticleShooter(new Geometry.Point(1, 0, 0),particleDirection, Color.rgb(5, 50, 255));final float angleVarianceInDegrees = 5f;final float speedVariance = 1f;mRedParticleShooter = new ParticleShooter(new Geometry.Point(-1, 0, 0),particleDirection, Color.rgb(250, 50, 5), angleVarianceInDegrees, speedVariance);mGreenParticleShooter = new ParticleShooter(new Geometry.Point(0, 0, 0),particleDirection, Color.rgb(25, 255, 25), angleVarianceInDegrees, speedVariance);mBlueParticleShooter = new ParticleShooter(new Geometry.Point(1, 0, 0),particleDirection, Color.rgb(5, 50, 255), angleVarianceInDegrees, speedVariance);}@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) {// 设置视图尺寸GLES20.glViewport(0, 0, width, height);// 创建透视投影Matrix.perspectiveM(projectionMatrix, 0, 45, (float)width / (float)height, 1f, 10f);updateViewMatrices();}@Overridepublic void onDrawFrame(GL10 gl) {// 清空屏幕GLES20.glClear(GL10.GL_COLOR_BUFFER_BIT);float currentTime = (System.nanoTime() - mGlobalStartTime) / 1000000000f;mRedParticleShooter.addParticles(mParticle, currentTime, 5);mGreenParticleShooter.addParticles(mParticle, currentTime, 5);mBlueParticleShooter.addParticles(mParticle, currentTime, 5);mParticleProgram.setUniform(viewProjectionMatrix);mParticleProgram.setCurrentTime(currentTime);mParticle.bindData(mParticleProgram);mParticle.draw();}private void handleOffsetsChanged(float xOffset, float yOffset) {this.xOffset = (xOffset - 0.5f) * 2.5f;this.yOffset = (yOffset - 0.5f) * 2.5f;updateViewMatrices();}private void updateViewMatrices() {// 定义模型矩阵Matrix.setIdentityM(viewMatrix, 0);Matrix.translateM(viewMatrix, 0, 0f - xOffset, -1.5f - yOffset, -5f);Matrix.multiplyMM(viewProjectionMatrix, 0, projectionMatrix, 0, viewMatrix, 0);}}}
显示如下



http://www.ppmy.cn/news/446707.html

相关文章

骚操作 Python爬你要的网站数据

引言 介绍下 Python 用 Beautiful Soup 周期性爬取 xxx 网站获取新闻流&#xff1b; 图 1 项目介绍 1. 开发环境 Python&#xff1a;      3.6.3 BeautifulSoup&#xff1a;   4.2.0 , 是一个可以从HTML或XML文件中提取数据的Python库* ( BeautifulSoup 的中文官方文档…

千万别急着入手 5G 手机!

【CSDN 编者按】5G 时代轰轰烈烈地来了&#xff0c;5G 手机的概念也随之越炒越热&#xff0c;芯片方面则一路高更猛进走到了骁龙 855。关于哪家将抢下此局首发&#xff0c;更是华为、小米、联想各路预测不断。但此间繁荣盛景究竟是商家合力炒作下的虚势&#xff0c;还是循序渐进…

硅谷速递 | 数据挖掘究竟在挖什么?我们如何充分利用它?

点击“蓝字”关注我们 硅谷不仅是世界高科技中心&#xff0c;也是新时代的灵魂&#xff0c;作为全球创新的聚集地&#xff0c;无论是基础的技术创新&#xff0c;还是下一代的技术应用创新&#xff0c;都有一批又一批的技术与应用来自“硅谷创新”。在硅谷我们不仅能看到专注于技…

昔日的 HTC 与三星,今日的苹果:寒冬过后手机厂商才会明白的潜规则

哥德巴赫猜想下的三星、HTC 和苹果。 作者 | 刘旷本文经授权转载自刘旷公众号&#xff08;ID&#xff1a;liukuang110&#xff09; 1742年6月7日&#xff0c;德国数学家哥德巴赫在写给著名数学家欧拉的一封信中&#xff0c;提出了一个大胆的猜想&#xff1a;即任何不小于4的偶数…

3G

3g 目录 简介 中国电信运营商重组与3G标准 关于中国移动3G放号 关于3G手机 UMTS 3G时代 中国3G的现状 TD-SCDMA十城市现状 支持3G手机终端 3G参数 最新3g关注 支持3G手机终端 3G参数 最新3g关注 [ 编辑本段] 简介  3G&#xff0c;全称为3rd Generation&#xff0c;中文含义就…

中国电信运营商重组与3G标准

第一代模拟制式手机(1G) 第二代GSM、TDMA等数字手机(2G) 第三代数字通信(3G):3G标准&#xff0c;国际电信联盟(ITU)目前一共确定了全球四大3G标准&#xff0c;它们分别是WCDMA、CDMA2000和TD-SCDMA和WiMAX。 电信重组方案的确定&#xff1a;中国移动铁通中国移动&#xff0c…

[苹果解密]创新是伟大公司诞生的源泉--Apple再度成为美国最大上市公司

分享一下我老师大神的人工智能教程&#xff01;零基础&#xff0c;通俗易懂&#xff01;http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章。分享知识&#xff0c;造福人民&#xff0c;实现我们中华民族伟大复兴&#xff01; 近日不论美股还是A股&#xff0c;都是跌落…

同一路由器WAN口与LAN口连接

10.20.9.x 为设备外网上网口地址&#xff0c;192.168.0.X 为两个设备局域网地址&#xff0c;路由器WAN口DHCP上网。